A Complete Guide On Creating Nestable NFTs with ERC-7401

A Complete Guide On Creating Nestable NFTs with ERC-7401

·

6 min read

Non-fungible tokens (NFTs) have transformed the digital asset landscape, offering verifiable ownership on the blockchain. ERC7401 is a new NFT standard that introduces the concept of nesting multiple child NFTs within a parent NFT. In this tutorial, We will explore the features of ERC-7401, its use cases, and provide a step-by-step tutorial on how to create nestable NFTs using this standard.

ERC7401: Parent Goverened NFT Nesting

ERC-7401 establishes a standardized interface for parent-governed nestable NFTs, enhancing consistency and interoperability across various implementations. It is an improved version of ERC-6059, and allows for an inter-NFT relationship and interactions. The ability of NFT to own other NFTs can extend the utility, usability, and compatibility of tokens.

ERC721 VS ERC7401

Ownership

  • ERC721 follows a basic ownership model where each token is unique and can be owned by a single address(EOA or Smart contract).

  • ERC-7401 introduces the concept of nestable tokens, where one NFT can own other NFTs, enabling hierarchical ownership structures and complex relationships between tokens.

Token Transfer

  • ERC-721 allows for the transfer of individual tokens between addresses, with each token representing a unique asset

  • ERC-7401 defines parent-child relationships for NFTs, allowing a parent token to own multiple child tokens and manage their interactions.

Interactions

  • ERC-721 tokens have limited interaction capabilities, primarily focused on ownership transfer and querying token metadata.

  • ERC-7401 enables interaction between nested NFTs, supporting use cases such as bundling tokens together, creating membership-based systems, and facilitating delegated voting in DAOs.

Utility

  • Each ERC-721 token is owned by a single address, typically an Externally Owned Account (EOA) or a smart contract.

  • ERC-7401 expands the utility of NFTs by allowing them to own other tokens, leading to greater flexibility, usability, and compatibility within the NFT ecosystem.

Use-Cases

Bundling and Collecting: Users can bundle multiple NFTs together into a single parent NFT, enabling the sale or transfer of multiple tokens as a single unit. This is useful for collectors who wish to manage and trade their NFT collections more efficiently.

Membership and Delegation: NFTs can represent memberships to organizations, or DAOs. With ERC-7401, these membership NFTs can own other tokens, such as rewards or bonus NFTs, simplifying the distribution and management of membership benefits. Additionally, the ability to delegate ownership or voting rights to other NFTs facilitates governance within decentralized communities.

Game Items and Virtual Assets: In gaming, virtual items and assets can be represented as NFTs. With ERC-7401, players can bundle multiple items or assets into a single parent NFT, making it easier to manage and trade their in-game belongings.

Multimedia Content Distribution: Content creators can bundle various multimedia assets, such as images, videos, and audio files, into a single-parent NFT. This parent NFT can then be sold or licensed as a single entity, simplifying the distribution process and ensuring that all associated assets are transferred together.

Creating and Deploying Nested NFT Contract Using ERC7401

The NestableNFT contract inherits from ‘NestableToken’, implementing ERC7401. It enables minting, transferring, and nesting NFTs. Owners can mint regular NFTs or nest them within others.

Explaining core functionality in the Nestable Token contract

  • _mint() function mints a new NFT and assigns ownership to the specified address. It emits transfer and nest transfer events, indicating the minting and nesting of the new token.
function _mint(
        address to,
        uint256 tokenId,
        bytes memory data
    ) internal virtual {
        _innerMint(to, tokenId, 0, data);
   emit Transfer(address(0), to, tokenId);
   emit NestTransfer(address(0), to, 0, 0, tokenId);
   _afterTokenTransfer(address(0), to, tokenId);
   _afterNestedTokenTransfer(address(0), to, 0, 0, tokenId, data);
    }
  • _nestMint() function to mint a new NFT and nest it with another NFT specified by ‘destinationId’. It first checks if the recipient address is a contract and supports the ERC-7401 interface. Then, it mints the new NFT and nests it within the parent NFT ensuring compatibility and integrity.
function _nestMint(
        address to,
        uint256 tokenId,
        uint256 destinationId,
        bytes memory data
    ) internal virtual {
        // It seems redundant, but otherwise it would revert with no error
        if (!to.isContract()) revert IsNotContract();
        if (!IERC165(to).supportsInterface(type(IERC7401).interfaceId))
            revert MintToNonNestableImplementer();
        _innerMint(to, tokenId, destinationId, data);
        _sendToNFT(address(0), to, 0, destinationId, tokenId, data);
    }
  • transferFrom() function enables token owners to transfer their NFTs to another address. It requires the sender to have approval or be the direct owner of the token being transferred. The function then internally calls the _transfer function inherited from NestableToken to execute the transfer.
function transferFrom(
        address from,
        address to,
        uint256 tokenId
    ) public virtual onlyApprovedOrDirectOwner(tokenId) {
        _transfer(from, to, tokenId, "");
    }
  • nestTransferFrom() function enables token owners to transfer their NFTs and nest them within another NFT specified by ‘destinationId’. It requires the sender to have approval or be the direct owner of the token being transferred. The function then internally calls the ‘_nestTransfer’ function.
function nestTransferFrom(
        address from,
        address to,
        uint256 tokenId,
        uint256 destinationId,
        bytes memory data
    ) public virtual onlyApprovedOrDirectOwner(tokenId) {
        _nestTransfer(from, to, tokenId, destinationId, data);
    }

Follow this Step-by-Step Procedure to create Nestable NFT.

To get started clone the working repository created using Scaffold-Eth 2 x Buildbear that lets you create your own private Sandbox, forked for various EVM and EVM-compatible blockchain networks, with your own Token faucet and blockchain explorer.

git clone https://github.com/sanamummer/erc7401.git
cd erc7401
yarn install

Create your private Sandbox using the below command. BuildBear SandBox details are stored in packages/buildbear/sandbox.json.

yarn fork-bb

To deploy the contract run the command

yarn deploy

You will get a similar output like this after successful deployment.

On a second terminal, start your NextJS app:

yarn start

Visit your app on: http://localhost:3000. You can interact with your smart contract using the Debug Contracts page.

Interacting with the smart contract

To Interact with the contract we need balance in our account. To add some test tokens from the faucet, navigate to the faucet URL which can be found herepackages/buildbear/sandbox.json.

Now call the mint function to mint an NFT to your wallet address with Id 1. Then call nestMint function to nest a new NFT with Id 2 to a parent NFT which we minted, with destinationId 1. Make sure to pass the Nestable NFT contract address.

Call the nestTransfer function and transfer a NFT to the parent NFT with Id 1.

Congratulations!! We have successfully implemented ERC7401 for nesting NFT.

About BuildBear

BuildBear is a platform tailored for DApp development and testing. Developers gain the freedom to construct a personalized Private Testnet sandbox across a variety of blockchain networks. The liberty to mint unlimited Native and ERC20 tokens, coupled with rapid transaction times on BuildBear (under 3 seconds!), enhances the DApp development lifecycle manifold. The platform comes equipped with tools designed for real-time testing and debugging, ensuring developers can keep tabs on intricate blockchain transactions with unparalleled ease.

Connect with us on Twitter | LinkedIn | Telegram | GitHub

Author: Sana