Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

First pass at adding profile images. #162

Merged
merged 13 commits into from
Mar 22, 2024
154 changes: 151 additions & 3 deletions python/fullcount/BeerLeagueBallers.py
Original file line number Diff line number Diff line change
Expand Up @@ -96,9 +96,13 @@ def __init__(self, contract_address: Optional[ChecksumAddress]):
self.contract_name, self.address, self.abi
)

def deploy(self, transaction_config):
def deploy(
self, _admin_terminus: ChecksumAddress, _admin_pool_id: int, transaction_config
):
contract_class = contract_from_build(self.contract_name)
deployed_contract = contract_class.deploy(transaction_config)
deployed_contract = contract_class.deploy(
_admin_terminus, _admin_pool_id, transaction_config
)
self.address = deployed_contract.address
self.contract = deployed_contract
return deployed_contract.tx
Expand All @@ -124,12 +128,22 @@ def name(
self.assert_contract_is_instantiated()
return self.contract.Name.call(arg1, block_identifier=block_number)

def num_profile_images(
self, block_number: Optional[Union[str, int]] = "latest"
) -> Any:
self.assert_contract_is_instantiated()
return self.contract.NumProfileImages.call(block_identifier=block_number)

def profile_images(
self, arg1: int, block_number: Optional[Union[str, int]] = "latest"
) -> Any:
self.assert_contract_is_instantiated()
return self.contract.ProfileImages.call(arg1, block_identifier=block_number)

def add_profile_image(self, new_image: str, transaction_config) -> Any:
self.assert_contract_is_instantiated()
return self.contract.addProfileImage(new_image, transaction_config)

def approve(self, to: ChecksumAddress, token_id: int, transaction_config) -> Any:
self.assert_contract_is_instantiated()
return self.contract.approve(to, token_id, transaction_config)
Expand Down Expand Up @@ -210,6 +224,22 @@ def set_approval_for_all(
self.assert_contract_is_instantiated()
return self.contract.setApprovalForAll(operator, approved, transaction_config)

def set_token_images(
self, token_id_list: List, image_index_list: List, transaction_config
) -> Any:
self.assert_contract_is_instantiated()
return self.contract.setTokenImages(
token_id_list, image_index_list, transaction_config
)

def set_token_names(
self, token_id_list: List, new_name_list: List, transaction_config
) -> Any:
self.assert_contract_is_instantiated()
return self.contract.setTokenNames(
token_id_list, new_name_list, transaction_config
)

def supports_interface(
self, interface_id: bytes, block_number: Optional[Union[str, int]] = "latest"
) -> Any:
Expand Down Expand Up @@ -259,6 +289,12 @@ def transfer_from(
self.assert_contract_is_instantiated()
return self.contract.transferFrom(from_, to, token_id, transaction_config)

def update_profile_image(
self, index: int, new_image: str, transaction_config
) -> Any:
self.assert_contract_is_instantiated()
return self.contract.updateProfileImage(index, new_image, transaction_config)


def get_transaction_config(args: argparse.Namespace) -> Dict[str, Any]:
signer = network.accounts.load(args.sender, args.password)
Expand Down Expand Up @@ -331,7 +367,11 @@ def handle_deploy(args: argparse.Namespace) -> None:
network.connect(args.network)
transaction_config = get_transaction_config(args)
contract = BeerLeagueBallers(None)
result = contract.deploy(transaction_config=transaction_config)
result = contract.deploy(
_admin_terminus=args.admin_terminus_arg,
_admin_pool_id=args.admin_pool_id_arg,
transaction_config=transaction_config,
)
print(result)
if args.verbose:
print(result.info())
Expand All @@ -358,13 +398,32 @@ def handle_name(args: argparse.Namespace) -> None:
print(result)


def handle_num_profile_images(args: argparse.Namespace) -> None:
network.connect(args.network)
contract = BeerLeagueBallers(args.address)
result = contract.num_profile_images(block_number=args.block_number)
print(result)


def handle_profile_images(args: argparse.Namespace) -> None:
network.connect(args.network)
contract = BeerLeagueBallers(args.address)
result = contract.profile_images(arg1=args.arg1, block_number=args.block_number)
print(result)


def handle_add_profile_image(args: argparse.Namespace) -> None:
network.connect(args.network)
contract = BeerLeagueBallers(args.address)
transaction_config = get_transaction_config(args)
result = contract.add_profile_image(
new_image=args.new_image, transaction_config=transaction_config
)
print(result)
if args.verbose:
print(result.info())


def handle_approve(args: argparse.Namespace) -> None:
network.connect(args.network)
contract = BeerLeagueBallers(args.address)
Expand Down Expand Up @@ -496,6 +555,34 @@ def handle_set_approval_for_all(args: argparse.Namespace) -> None:
print(result.info())


def handle_set_token_images(args: argparse.Namespace) -> None:
network.connect(args.network)
contract = BeerLeagueBallers(args.address)
transaction_config = get_transaction_config(args)
result = contract.set_token_images(
token_id_list=args.token_id_list,
image_index_list=args.image_index_list,
transaction_config=transaction_config,
)
print(result)
if args.verbose:
print(result.info())


def handle_set_token_names(args: argparse.Namespace) -> None:
network.connect(args.network)
contract = BeerLeagueBallers(args.address)
transaction_config = get_transaction_config(args)
result = contract.set_token_names(
token_id_list=args.token_id_list,
new_name_list=args.new_name_list,
transaction_config=transaction_config,
)
print(result)
if args.verbose:
print(result.info())


def handle_supports_interface(args: argparse.Namespace) -> None:
network.connect(args.network)
contract = BeerLeagueBallers(args.address)
Expand Down Expand Up @@ -557,13 +644,33 @@ def handle_transfer_from(args: argparse.Namespace) -> None:
print(result.info())


def handle_update_profile_image(args: argparse.Namespace) -> None:
network.connect(args.network)
contract = BeerLeagueBallers(args.address)
transaction_config = get_transaction_config(args)
result = contract.update_profile_image(
index=args.index,
new_image=args.new_image,
transaction_config=transaction_config,
)
print(result)
if args.verbose:
print(result.info())


def generate_cli() -> argparse.ArgumentParser:
parser = argparse.ArgumentParser(description="CLI for BeerLeagueBallers")
parser.set_defaults(func=lambda _: parser.print_help())
subcommands = parser.add_subparsers()

deploy_parser = subcommands.add_parser("deploy")
add_default_arguments(deploy_parser, True)
deploy_parser.add_argument(
"--admin-terminus-arg", required=True, help="Type: address"
)
deploy_parser.add_argument(
"--admin-pool-id-arg", required=True, help="Type: uint256", type=int
)
deploy_parser.set_defaults(func=handle_deploy)

verify_contract_parser = subcommands.add_parser("verify-contract")
Expand All @@ -582,13 +689,24 @@ def generate_cli() -> argparse.ArgumentParser:
name_parser.add_argument("--arg1", required=True, help="Type: uint256", type=int)
name_parser.set_defaults(func=handle_name)

num_profile_images_parser = subcommands.add_parser("num-profile-images")
add_default_arguments(num_profile_images_parser, False)
num_profile_images_parser.set_defaults(func=handle_num_profile_images)

profile_images_parser = subcommands.add_parser("profile-images")
add_default_arguments(profile_images_parser, False)
profile_images_parser.add_argument(
"--arg1", required=True, help="Type: uint256", type=int
)
profile_images_parser.set_defaults(func=handle_profile_images)

add_profile_image_parser = subcommands.add_parser("add-profile-image")
add_default_arguments(add_profile_image_parser, True)
add_profile_image_parser.add_argument(
"--new-image", required=True, help="Type: string", type=str
)
add_profile_image_parser.set_defaults(func=handle_add_profile_image)

approve_parser = subcommands.add_parser("approve")
add_default_arguments(approve_parser, True)
approve_parser.add_argument("--to", required=True, help="Type: address")
Expand Down Expand Up @@ -699,6 +817,26 @@ def generate_cli() -> argparse.ArgumentParser:
)
set_approval_for_all_parser.set_defaults(func=handle_set_approval_for_all)

set_token_images_parser = subcommands.add_parser("set-token-images")
add_default_arguments(set_token_images_parser, True)
set_token_images_parser.add_argument(
"--token-id-list", required=True, help="Type: uint256[]", nargs="+"
)
set_token_images_parser.add_argument(
"--image-index-list", required=True, help="Type: uint256[]", nargs="+"
)
set_token_images_parser.set_defaults(func=handle_set_token_images)

set_token_names_parser = subcommands.add_parser("set-token-names")
add_default_arguments(set_token_names_parser, True)
set_token_names_parser.add_argument(
"--token-id-list", required=True, help="Type: uint256[]", nargs="+"
)
set_token_names_parser.add_argument(
"--new-name-list", required=True, help="Type: string[]", nargs="+"
)
set_token_names_parser.set_defaults(func=handle_set_token_names)

supports_interface_parser = subcommands.add_parser("supports-interface")
add_default_arguments(supports_interface_parser, False)
supports_interface_parser.add_argument(
Expand Down Expand Up @@ -747,6 +885,16 @@ def generate_cli() -> argparse.ArgumentParser:
)
transfer_from_parser.set_defaults(func=handle_transfer_from)

update_profile_image_parser = subcommands.add_parser("update-profile-image")
add_default_arguments(update_profile_image_parser, True)
update_profile_image_parser.add_argument(
"--index", required=True, help="Type: uint256", type=int
)
update_profile_image_parser.add_argument(
"--new-image", required=True, help="Type: string", type=str
)
update_profile_image_parser.set_defaults(func=handle_update_profile_image)

return parser


Expand Down
77 changes: 65 additions & 12 deletions src/Players.sol
Original file line number Diff line number Diff line change
Expand Up @@ -6,26 +6,79 @@ import { ERC721 } from "../lib/openzeppelin-contracts/contracts/token/ERC721/ERC
import { ERC721Enumerable } from "../lib/openzeppelin-contracts/contracts/token/ERC721/extensions/ERC721Enumerable.sol";
import { Base64 } from "../lib/openzeppelin-contracts/contracts/utils/Base64.sol";
import { Strings } from "../lib/openzeppelin-contracts/contracts/utils/Strings.sol";
import { ITerminus } from "../lib/web3/contracts/interfaces/ITerminus.sol";

contract BeerLeagueBallers is ERC721Enumerable {
string[24] public ProfileImages = [
"https://badges.moonstream.to/blb/p0.png",
"https://badges.moonstream.to/blb/p1.png",
"https://badges.moonstream.to/blb/p2.png",
"https://badges.moonstream.to/blb/p3.png",
"https://badges.moonstream.to/blb/p4.png",
"https://badges.moonstream.to/blb/p5.png",
"https://badges.moonstream.to/blb/p6.png",
"https://badges.moonstream.to/blb/p7.png"
];
mapping(uint256 => string) public ProfileImages;
uint256 public NumProfileImages;

mapping(uint256 => string) public Name;
mapping(uint256 => uint256) public ImageIndex;

constructor() ERC721("Beer League Ballers", "BLB") { }
address adminTerminus;
uint256 adminPoolID;

constructor(address _adminTerminus, uint256 _adminPoolID) ERC721("Beer League Ballers", "BLB") {
adminTerminus = _adminTerminus;
adminPoolID = _adminPoolID;

ProfileImages[0] = "https://static.fullcount.xyz/Beer_League_Ballers/p0.png";
ProfileImages[1] = "https://static.fullcount.xyz/Beer_League_Ballers/p1.png";
ProfileImages[2] = "https://static.fullcount.xyz/Beer_League_Ballers/p2.png";
ProfileImages[3] = "https://static.fullcount.xyz/Beer_League_Ballers/p3.png";
ProfileImages[4] = "https://static.fullcount.xyz/Beer_League_Ballers/p4.png";
ProfileImages[5] = "https://static.fullcount.xyz/Beer_League_Ballers/p5.png";
ProfileImages[6] = "https://static.fullcount.xyz/Beer_League_Ballers/p6.png";
ProfileImages[7] = "https://static.fullcount.xyz/Beer_League_Ballers/p7.png";
NumProfileImages = 8;
}

function _enforceIsAdmin() internal view {
ITerminus terminus = ITerminus(address(adminTerminus));
require(terminus.balanceOf(msg.sender, adminPoolID) > 0, "BeerLeagueBallers._enforceIsAdmin: not admin");
}

function addProfileImage(string memory newImage) public {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We're probably going to be adding multiple images at once, this seems like it should be a batch method.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We decided not to do this.

_enforceIsAdmin();

ProfileImages[NumProfileImages] = newImage;
NumProfileImages++;
}

function updateProfileImage(uint256 index, string memory newImage) public {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should also probably be a batch method.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We decided not to do this.

_enforceIsAdmin();

ProfileImages[index] = newImage;
}

function setTokenNames(uint256[] memory tokenIDList, string[] memory newNameList) public {
_enforceIsAdmin();

require(
tokenIDList.length == newNameList.length,
"BeerLeagueBallers.setTokenNames: tokenIDList and newNameList length mismatch"
);

for (uint256 i = 0; i < tokenIDList.length; i++) {
Name[tokenIDList[i]] = newNameList[i];
}
}

function setTokenImages(uint256[] memory tokenIDList, uint256[] memory imageIndexList) public {
_enforceIsAdmin();

require(
tokenIDList.length == imageIndexList.length,
"BeerLeagueBallers.setTokenImages: tokenIDList and imageIndexList length mismatch"
);

for (uint256 i = 0; i < tokenIDList.length; i++) {
ImageIndex[tokenIDList[i]] = imageIndexList[i];
}
}

function mint(string memory name, uint256 imageIndex) public returns (uint256) {
require(imageIndex < ProfileImages.length, "BLB.mint: invalid image index");
require(imageIndex < NumProfileImages, "BLB.mint: invalid image index");
uint256 tokenId = totalSupply() + 1;
Name[tokenId] = name;
ImageIndex[tokenId] = imageIndex;
Expand Down
Loading
Loading