NFT ERC1155 for game Players and Accessories, and how to bind them together?

I’m creating a simple NFT collection.

The idea is to create game Players and Accessories for them. Namely, each Player is an NFT, and each Accessory is an NFT too.

Each owner of Player will be able to buy Accessories for Player.

I’ve created a simple contract but I can’t figure out how to work with the two entities - Players and Accessories - in a relational manner.

    pragma solidity ^0.8.9;

    import "@openzeppelin/contracts/token/ERC1155/ERC1155.sol";
    import "@openzeppelin/contracts/access/Ownable.sol";
    import "@openzeppelin/contracts/utils/Strings.sol";

    contract MyPlayer is ERC1155, Ownable { 
      constructor() ERC1155("game123.example.com/{id}.json") {
      }

    function mint(address account, uint256 id, uint256 amount, bytes memory data)
        public
        onlyOwner
      {
        _mint(account, id, amount, data);
      }

    function mintBatch(address to, uint256[] memory ids, uint256[] memory amounts, bytes memory data)
        public
        onlyOwner
      {
        _mintBatch(to, ids, amounts, data);
      }
   }

Will I have to create a separate NFT contract for Accessories too? If so, how?
Or will the existing contract do for both?

In other words, to bind the Players and Accessories together? In a simple way.

An Accessory can only be bought for an already possessed Player.

1 Like

Hi @timanidari and welcome to Infura community.

To achieve the desired functionality of binding players and accessories together in a simple manner, you can use the same ERC1155 contract for both players and accessories. However, you will need to modify the contract and add additional logic to handle the relationship between players and accessories.

Here’s an updated version of the contract that includes the necessary modifications:

pragma solidity ^0.8.9;

import "@openzeppelin/contracts/token/ERC1155/ERC1155.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/utils/Strings.sol";

contract MyGame is ERC1155, Ownable {
    mapping(uint256 => uint256[]) private playerAccessories;
    mapping(uint256 => uint256) private accessoryPlayer;
  
    constructor() ERC1155("game123.example.com/{id}.json") {
    }

    function mintPlayer(address account, uint256 playerId, uint256 amount, bytes memory data) public onlyOwner {
        _mint(account, playerId, amount, data);
    }

    function mintAccessory(address account, uint256 accessoryId, uint256 amount, bytes memory data) public onlyOwner {
        _mint(account, accessoryId, amount, data);
    }
  
    function setAccessoryForPlayer(uint256 playerId, uint256 accessoryId) public {
        require(balanceOf(msg.sender, playerId) > 0, "You must possess the player.");
        require(balanceOf(msg.sender, accessoryId) > 0, "You must possess the accessory.");
        
        // Associate the accessory with the player
        playerAccessories[playerId].push(accessoryId);
        accessoryPlayer[accessoryId] = playerId;
    }
  
    function getPlayerAccessories(uint256 playerId) public view returns (uint256[] memory) {
        return playerAccessories[playerId];
    }
  
    function getAccessoryPlayer(uint256 accessoryId) public view returns (uint256) {
        return accessoryPlayer[accessoryId];
    }
}

Here’s an overview of the changes made to the contract:

  1. Added two mappings: playerAccessories and accessoryPlayer. These mappings are used to store the relationship between players and their accessories.
  2. Added a mintAccessory function, which allows you to mint/accessories as NFTs.
  3. Added a setAccessoryForPlayer function, which allows a player to associate an accessory with themselves. This function performs checks to ensure that the player and accessory exist and are owned by the caller.
  4. Added two additional functions, getPlayerAccessories and getAccessoryPlayer, to retrieve the accessories associated with a player and the player associated with an accessory, respectively.

With these modifications, you can now mint players and accessories as separate NFTs and associate accessories with players by calling the setAccessoryForPlayer function.

1 Like

This topic was automatically closed after 30 days. New replies are no longer allowed.