Creating a Tokenized Lootbox Game Smart Contract on Ethereum

Posted By : Ashish

Feb 27, 2024

Within the quickly developing realm of blockchain gaming, tokenized loot boxes have become a fascinating fusion of virtual cash and gaming fun. With blockchain development services, you can create a unique gaming experience where players can purchase, earn, and open loot boxes containing a range of tokenized things by utilizing the Ethereum network and the ERC1155 multi-token standard. Using the "MyToken" contract as a foundational example, this blog post will walk you through the process of creating a tokenized loot-box game using the ERC1155 standard.

 

Core Concept of the Tokenized Loot-box Game

 

The essence of our game revolves around loot boxes"”special tokens that can contain an array of other tokenized items, ranging from common to rare. Players can acquire loot boxes through gameplay, purchases, or trading with other players. Opening a loot box reveals its contents, adding an element of surprise and anticipation to the gaming experience.

 

The "MyToken" Contract: A Blueprint

 

Our game's backbone is the "MyToken" smart contract, which implements the ERC1155 standard along with additional functionalities for managing loot boxes. Let's dissect the main components and functionalities that make this contract suitable for our game:

 

  1. ERC1155 Foundation: This allows for efficient handling of multiple token types, essential for distinguishing between different loot boxes and items within our game.
  2. LootBox Functions: These provide the game developers (contract owners) with exclusive rights to mint new items and loot boxes.

 

Also, Check |  Game On! Mastering Web3 Game Development

 

Prerequisites:-

 

  • Nodejs installed
  • Solidity Familiarity
  • ERC 1155 Familiarity

 

Implementing the Game Logic

 

Step 1: Setting up the Hardhat Environment

 

Create a new folder for the project. 

Use the following command:-  

npx hardhat 

And create a hardhat project.

 

We can now create our solidity contract in the contract folder by deleting the lock.sol file provided by hardhat. 

 

run
npm install @openzeppelin/contracts

 

You may also like | A Guide on How to Develop a Dutch Auction Smart Contract

 

Step 2: Smart Contract Development

 

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;


// Importing ERC1155, Ownable, and ERC1155Burnable contracts from OpenZeppelin.
import "@openzeppelin/contracts/token/ERC1155/ERC1155.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/token/ERC1155/extensions/ERC1155Burnable.sol";


// MyToken is a contract that combines ERC1155 for multi-token functionality,
// Ownable for ownership management, and ERC1155Burnable for token burnability.
contract MyToken is ERC1155, Ownable, ERC1155Burnable {
  // Private variable to keep track of the next item ID.
  uint256 private _nextItemId = 1;
  // Private variable to keep track of the next loot box ID.
  uint256 private _nextBoxId = 1;


  // Struct representing a loot box, which contains arrays of item IDs and quantities.
  struct LootBox {
      uint256[] itemIds;
      uint256[] itemQuantities;
  }


  // Mapping from loot box ID to LootBox struct, storing each loot box's details.
  mapping(uint256 => LootBox) private lootBoxes;


  // Event emitted when a loot box is opened.
  event LootBoxOpened(uint256 indexed boxId, address opener);


  // Constructor sets the base URI for token metadata and transfers ownership.
  constructor(string memory uri, address initialOwner) ERC1155(uri) Ownable(initialOwner) {
  }


  // Function to create a new loot box. Only the owner can call this function.
  function createLootBox(uint256[] memory itemIds, uint256[] memory itemQuantities) public onlyOwner {
      require(itemIds.length == itemQuantities.length, "Mismatch between item IDs and quantities");
      uint256 newBoxId = _nextBoxId++;
      lootBoxes[newBoxId] = LootBox(itemIds, itemQuantities);
  }


  // Function to open a loot box, burning one instance of the box and minting one of the items inside.
  function openLootBox(uint256 boxId) public {
      require(balanceOf(msg.sender, boxId) > 0, "You do not own this loot-box");
      _burn(msg.sender, boxId, 1); // Burn one loot box from the caller's balance.


      LootBox memory box = lootBoxes[boxId];
      // Generate a random index to determine which item to mint.
      uint256 randomIndex = uint256(keccak256(abi.encodePacked(block.timestamp, msg.sender))) % box.itemIds.length;
      uint256 itemId = box.itemIds[randomIndex];
      uint256 quantity = box.itemQuantities[randomIndex];


      _mint(msg.sender, itemId, quantity, ""); // Mint the item to the caller.
      emit LootBoxOpened(boxId, msg.sender); // Emit an event for opening the loot box.
  }


  // Allows the owner to mint a new item directly to an address.
  function mintItem(address to, uint256 id, uint256 quantity, bytes memory data) public onlyOwner {
      _mint(to, id, quantity, data);
  }


  // Allows the owner to mint a new loot box and assigns it to an address.
  function mintLootBox(address to, uint256[] memory itemIds, uint256[] memory itemQuantities, uint256 quantity) public onlyOwner {
      createLootBox(itemIds, itemQuantities); // Create the loot box first.
      _mint(to, _nextBoxId - 1, quantity, ""); // Then mint it to the specified address.
  }


  // Function for the owner to set a new URI for all token types.
  function setURI(string memory newuri) public onlyOwner {
      _setURI(newuri);
  }


  // Function for the owner to mint tokens of a given ID and amount to a specified account.
  function mint(address account, uint256 id, uint256 amount, bytes memory data) public onlyOwner {
      _mint(account, id, amount, data);
  }


  // Function for the owner to mint multiple tokens of different IDs to a specified account.
  function mintBatch(address to, uint256[] memory ids, uint256[] memory amounts, bytes memory data) public onlyOwner {
      _mintBatch(to, ids, amounts, data);
  }
}

 

  • Create MyToken Contract:

 

  • Create a new Solidity file named MyToken.sol.
  • Copy the provided Solidity code into MyToken.sol.

 

  • Understand Contract Components:

 

  • ERC1155: This is a multi-token standard allowing the contract to manage multiple token types.
  • Ownable: Provides basic authorization control functions, simplifying the implementation of "user permissions".
  • ERC1155Burnable: Allows tokens to be burnt, removing them from the total supply.

 

  • Implement Constructor: The constructor sets the base URI for token metadata and optionally transfers ownership to another address. Be prepared to provide the URI and the initial owner's address upon deployment.

 

  • Implement Loot Box Logic:

 

  • createLootBox: Allows the contract owner to create new loot boxes, each defined by arrays of item IDs and their quantities.
  • openLootBox: Allows a loot box owner to open it, burning the loot box token and minting one of the items inside to the opener.

 

  • Implement Minting Functions:

 

  • mintItem: For the contract owner to mint a specific item directly to an address.
  • mintLootBox: For the contract owner to mint a loot box (after creating it) directly to an address.
  • mint: For minting tokens of a given ID to a specific account.
  • mintBatch: Allows the owner to mint multiple types of tokens to a specified account in a single transaction.

 

  • Utility Functions:

 

  • setURI: To update the base URI for all token types.
  • Private variables _nextItemId and _nextBoxId are used to keep track of the IDs for new items and loot boxes, ensuring uniqueness.

 

Explore More | Smart Contract Development Using Python

 

Step 3: Minting Loot Boxes

 

The game developer mints a variety of loot boxes, each characterized by a unique ID and containing a predefined set of items. This step involves calling the mintLootBox function to distribute the loot boxes to players.

 

Step 4: Acquiring and Opening Loot Boxes

 

Players acquire loot boxes through gameplay, purchases, or trades. To open a loot box, a player calls the openLootBox function, which burns the loot box token and randomly selects an item from its contents to mint to the player's address.

 

Also, Read | Creating a Staking Smart Contract on Solana using Anchor

 

Conclusion

 

Building a tokenized loot-box game with ERC1155 offers a unique opportunity to blend blockchain technology with engaging gameplay elements. The "MyToken" contract serves as a solid foundation, showcasing how to manage loot boxes and items within a unified framework. By embracing this technology, developers can create rich, interactive gaming experiences that leverage the power of blockchain for transparency, ownership, and traceability of digital assets. As the blockchain gaming industry continues to grow, innovative applications like tokenized loot boxes will undoubtedly play a significant role in shaping its future. Interested in developing a similar project for a wider audience, get in touch with smart contract developers to get started. 

Leave a

Comment

Name is required

Invalid Name

Comment is required

Recaptcha is required.

blog-detail

April 4, 2024 at 10:13 am

Your comment is awaiting moderation.

By using this site, you allow our use of cookies. For more information on the cookies we use and how to delete or block them, please read our cookie notice.

Chat with Us
Contact Us

Oodles | Blockchain Development Company

Name is required

Please enter a valid Name

Please enter a valid Phone Number

Please remove URL from text