## 4 Implementation
### Smart Contract
Those functions use binary operations to align and extract data from token ID, as described in the system design section. The main registration function presented in Listing 5 checks if the caller is the administrator of the whole system, as they are the only ones with the privilege to register new game developers. The minting role for game id is then granted, which allows the newly registered key to sign boosters and register collections (Listing 6). ```
functionregisterMinterRole(uint32 gameId,addressminter)public{ require( hasRole(DEFAULT_ADMIN_ROLE,msg.sender), \"ERC1155:musthaveadminroletoregisterminterrole\" ); bytes32 role=keccak256(abi.encodePacked(\"MINTER_ROLE\",gameId)); _grantRole(role,minter);
```
functionregisterCollection( uint32 gameId, uint32 collection, stringmemorycollectionCID ) public { require( bytes(_collectionURIis[gameId][collection]).length==0, \"TCGProt:collectionalreadyregistered\" ); bytes32 role=keccak256(abi.encodePacked(\"MINER_ROLE\",gameId)); require( hasRole(role,msg.sender), \"TCGProt:musthaveadminroletoregistercollection\" ); _collectionURIis[gameId][collection]=string( abi.encodePacked(\"ipfs://\",collectionCID,\"/\") ); }
```
Collections can only be managed with signatures from registered game developers. During this process, the IPFS content id should already be known, meaning the cards should already have their metadata and images uploaded. The metadata have a predefined format, agreed upon in ERC-1155 standard [34] to be listable in publicly available NFT marketplaces (Listing 7). ```
{ \"name\":\"AssetName\", \"description\":\"Loremipsum...\", \"image\":\"ipfs://somecontentid\", \"properties\":{ \"simple_property\":\"examplevalue\", \"rich_property\":{ \"name\":\"Name\", \"value\":\"123\", \"display_value\":\"123 ExampleValue\", \"class\":\"emphasis\", \"css\":{ \"color\":\"#ffff\", \"font-weight\":\"bold\", \"text-decoration\":\"underline\" } }, \"array_property\":{ \"name\":\"Name\", \"value\":[1,2,3,4], \"class\":\"emphasis\" } }
```
Listing 8: Collection registration function. ```
functionregisterCollection( uint32 gameId, uint32 collection, stringmemorycollectionCID ) public { require( bytes(_collectionURIis[gameId][collection]).length==0, \"TCGProt:collectionalreadyregistered\" ); } bytes32 role=keccak256(abi.encodePacked(\"MINER_ROLE\",gameId)); require( hasRole(role,msg.sender), \"TCGProt:musthaveadminroletoregistercollection\" ); _collectionURIis[gameId][collection]=string( abi.encodePacked(\"ipfs://\",collectionCID,\"/\") ); }
```
Listing 9: Collection registration function. Collections can only be managed with signatures from registered game developers. During this process, the IPFS content id should already be known, meaning the cards should already have their metadata and images uploaded. The metadata have a predefined format, agreed upon in ERC-1155 standard [34] to be listable in publicly available NFT marketplaces (Listing 7). ```
{ \"name\":\"AssetName\", \"description\":\"Loremipsum...\", \"image\":\"ipfs://somecontentid\", \"properties\":{ \"simple_property\":\"examplevalue\", \"rich_property\":{ \"name\":\"Name\", \"value\":\"123\", \"display_value\":\"123 ExampleValue\", \"class\":\"emphasis\", \"css\":{ \"color\":\"#ffff\", \"font-weight\":\"bold\", \"text-decoration\":\"underline\" } }, \"array_property\":{ \"name\":\"Name\", \"value\":[1,2,3,4], \"class\":\"emphasis\" } }
```


Listing 28 As the contract uses the function to fetch the IPFS address for the metadata (function presented in Listing 8), the cards put in the uploaded folder should have numeric names referencing their card id field. ```
functionuri( uint256_tokenID ) publicview override returns (string memory){ return string( abi.encodePacked( _collectionURIs[_getGameId(_tokenID)][ _getCollectionId(_tokenID) ], Strings.toString(_getCardId(_tokenID)) ); }
```

Listing 8: Function returning metadata address on IPFS. ### Admin Application

The system operator's application was built. It is able to receive requests from game developers for registration.