Pulling It Together

Figure 1 shows a diagram of the contracts after the previous instalment.

Figure 1: Contract structure

I want the game accessible through as few Smart Contracts as possible, so the front-end code doesn’t get too complicated. Hence the reason for SomethingHere .

I’ve created a contract in place of SomethingHere is called TennisPlayer . This is shown in Figure 2.

Figure 2: TennisPlayer.sol

Notice how myPlayers() on line 9 uses the _tokensOfOwner() function inherited from ERC721Enumerable . As mentioned earlier, this allows the front-end to load all players owned by the user.

Creating New Players

In part one, I created the newPlayer() function in TennisPlayerBase with the custom access modifier onlyOwner (inherited from Openzeppelin’s Ownable contract). This means that only the owner of the token can create new players, and no one else. It has to be this way if the game is to be in control of setting the starting attributes of new players. Otherwise, a user can create a new player and max out the stats on immediately.

For this to work, we need an overarching Game contract which itself creates the TennisPlayer ERC721 token contract when it is deployed, hence becoming the owner.

Figure 3 shows the contract which does this, Game.sol.

Figure 3: Game.sol

Notice the default attribute values from lines 11 to 16. Every new player starts with these. In future, an element of randomness could be introduced so each new player has slightly different strength and weaknesses. (although randomness is a sticking point)

The contract also stores an address called publicTokenAddress representing the location of our ERC721 token on line 9. This is retrieved by the constructor when the token is created on line 19.

The newPlayer() function is exposed publically on line 22, taking only the name, age and height of the new player from the user. This is the entry point into the game.