Skip to main content

Build a Dynamic NFT on Base with Irys

In this tutorial, you will create a dynamic NFT using Irys' mutable references.

Overview

Dynamic NFTs are NFTs whose metadata evolves over time. They are commonly used in:

  • Gaming projects where in-game assets evolve as players progress
  • Loyalty programs where NFTs evolve as users accumulate points

Objectives

By the end of this tutorial, you should be able to:

  • Permanently upload data onchain using Irys
  • Create NFT metadata and use it to mint an NFT
  • "Mutate" (change) the NFT metadata using Irys' mutable references

Prerequisites

  1. Setup a Coinbase Wallet: You'll need a web3 wallet; you'll use it to deploy the NFT contract and to sign and pay for uploads to Irys. We recommend using the Coinbase Wallet.

  2. Wallet Funding: You'll need to fund your wallet with some Base Sepolia tokens. You can do this for free using the Base Faucet.

About Irys

Irys is a provenance layer. Data uploaded to Irys is:

  • Permanent and immutable
  • Onchain
  • Censorship-resistant
  • Blockchain agnostic
  • Unconstrained (you can upload files of any size)

When you store your NFT assets on Irys and mint them using a smart contract on Base, you can guarantee the NFT will be retrievable forever. Creators can rest assured that their works will endure indefinitely, while collectors can feel secure knowing their NFTs are permanently preserved.

Irys + Base

Irys has a pay-once-store-forever model and accepts payment for storage using multiple tokens, including ETH on Base.

Mutable references

Data on Irys is permanent and immutable, but you use Irys' mutable references to simulate mutability and create dynamic NFTs that evolve based on onchain or offchain actions.

Overview

With mutable references, you create a single, static URL that is linked to a series of transactions. You can add a new transaction to the series at any time, and the URL will always resolve to the most recent transaction.

You'll mint your NFT using a mutable reference URL, and then push updates to that URL. The URL won't change, but the metadata it resolves to will.

About

This tutorial focuses on creating a SuperMon NFT, similar to one used in a web3 game that would evolve during gameplay. The NFT starts with a basic appearance and can be "upgraded" twice. You will use the Irys CLI to "mutate" the metadata, simulating the automatic changes that would occur through player interactions in an actual game.

Smart contract

You're building an NFT, which means you need a smart contract. Here's a simple one you can use to mint the NFT you'll create.

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

// Import OpenZeppelin's ERC721 and ERC721URIStorage contracts
// These URLs are compatible with Remix IDE
import "@openzeppelin/contracts/token/ERC721/ERC721.sol";
import "@openzeppelin/contracts/token/ERC721/extensions/ERC721URIStorage.sol";
import "@openzeppelin/contracts/access/Ownable.sol";

contract SuperMon is ERC721URIStorage {
uint256 private _tokenIdCounter;

// No arguments in the constructor, the owner will be the contract deployer
constructor() ERC721("SuperMon", "SMON") {
_tokenIdCounter = 0;
}

// Mint function to create a new NFT
function mint(address to, string memory uri) public {
uint256 tokenId = _tokenIdCounter;
_tokenIdCounter += 1;
_safeMint(to, tokenId);
_setTokenURI(tokenId, uri);
}
}

Deploy the smart contract using Remix.

Irys CLI

You'll use the Irys CLI to upload images and metadata.

Installing the CLI

Install the Irys CLI globally using the -g flag. Depending on your setup, you may need to use sudo.

npm i -g @irys/sdk
# Or
sudo npm i -g @irys/sdk

Using private keys

When executing CLI commands involving funding and signing, you must provide a private key. Use the -w flag to specify a private key along with the -t flag to signal you're using ETH on Base.

irys -w <base-private-key> -t base-eth

Uploading the images

All NFTs

Download a zip containing PNGs for each level, and save them on your local drive.

Next, fund the Irys Devnet node with 0.1 Base Sepolia ETH to pay for your uploads.

In all of these CLI examples, make sure to replace the value of the -w parameter with your own private key.

irys fund 100000000000000000 \
-n devnet \
-t base-eth \
-w 6dd5e....54a120201cb6a \
--provider-url https://sepolia-explorer.base.org/

The fund command accepts a value in atomic units, 0.1 ETH is equal to 100000000000000000 in atomic units.

Next, use the Irys CLI to upload each of the images to the Irys Devnet.

Uploads to Irys' devnet are kept for ~60 days and are paid for using free tokens available from faucets [Base Sepolia]. Uploads to Irys' mainnet are permanent and can be paid for using ETH on Base.

irys upload image-level-1.png \
-n devnet \
-t base-eth \
-w 6dd5e....54a120201cb6a \
--provider-url https://sepolia.base.org

irys upload image-level-2.png \
-n devnet \
-t base-eth \
-w 6dd5e....54a120201cb6a \
--provider-url https://sepolia.base.org

irys upload image-level-3.png \
-n devnet \
-t base-eth \
-w 6dd5e....54a120201cb6a \
--provider-url https://sepolia.base.org

Uploading the metadata

Create three metadata files similar to the ones below. Make sure to change the value of the image field to match the URLs generated in the previous step.

{
"name": "SuperMon",
"symbol": "SMON",
"image": "https://gateway.irys.xyz/QH3rksVhbFg5L9vvjGzb4POUibCEG-TGPInmofp-O-o",
"description": "Super dooper, changing shapes, changing power",
"attributes": [
{
"trait_type": "supermon-level",
"value": "1"
}
]
}
{
"name": "SuperMon",
"symbol": "SMON",
"image": "https://gateway.irys.xyz/QH3rksVhbFg5L9vvjGzb4POUibCEG-TGPInmofp-O-o",
"description": "Super dooper, changing shapes, changing power",
"attributes": [
{
"trait_type": "supermon-level",
"value": "2"
}
]

}
{
"name": "SuperMon",
"symbol": "SMON",
"image": "https://gateway.irys.xyz/QH3rksVhbFg5L9vvjGzb4POUibCEG-TGPInmofp-O-o",
"description": "Super dooper, changing shapes, changing power",
"attributes": [
{
"trait_type": "supermon-level",
"value": "3"
}
]

}

And upload just the first file using the Irys CLI.

irys upload metadata-level-1.json \
-n devnet \
-t base-eth \
-w 6dd5e....54a120201cb6a \
--provider-url https://sepolia-explorer.base.org

The CLI will return a URL similar to https://gateway.irys.xyz/NDtKvjlmZL2iXUPmX6P-BuvtnvAEFkUiQWG8ToyK5FM. To convert that to a mutable references URL, interpolate it by adding /mutable/ after the domain and before the transaction ID.

Your final URL will be similar to https://gateway.irys.xyz/mutable/NDtKvjlmZL2iXUPmX6P-BuvtnvAEFkUiQWG8ToyK5FM.

Minting the NFT

To mint your NFT in Remix:

  1. Return to Remix.
  2. Under "Deployed Contracts", locate your contract and expand it to see its functions.
  3. Under the Mint function, enter the wallet address you want to mint the NFT to and the metadata URL (e.g. https://gateway.irys.xyz/mutable/NDtKvjlmZL2iXUPmX6P-BuvtnvAEFkUiQWG8ToyK5FM) from the previous step.
  4. Click Transact.

Image Level 3

You can now view the NFT on the Opensea Testnet.

Mutating the metadata

To now "mutate" the NFT, upload a new version of the metadata tagging it as having a Root-TX equal to the transaction ID of your first transaction. In my example, I pass the value of NDtKvjlmZL2iXUPmX6P-BuvtnvAEFkUiQWG8ToyK5FM, however make sure to change this to match your unique transaction ID.

irys upload metadata-level-2.json \
-n devnet \
-t base-eth \
-w 6dd5e....54a120201cb6a \
--tags Root-TX NDtKvjlmZL2iXUPmX6P-BuvtnvAEFkUiQWG8ToyK5FM \
--provider-url https://sepolia-explorer.base.org

Return to Opensea and request that it refresh your metadata.

Image Level 3

Give it a few minutes and your updated NFT should be visible.

Free metadata uploads

Uploads of less than 100 KiB are free on Irys, which is more than enough for most metadata files. This means projects can let users "evolve" their NFTs without having to pay gas fees.

Caching

Wallets and NFT websites typically cache metadata to optimize performance, this can affect the visibility of updates to dynamic NFTs. While OpenSea offers a feature for users to manually request metadata refreshes, not all platforms provide this level of control. When building dynamic NFT projects, make sure to thoroughly test and understand the implications of caching on your platform.

Irys SDK

This tutorial used the Irys CLI to permanently upload data. Irys also has a JS-SDK that can be used on the server and in the browser.

Conclusion

In this tutorial, you learned how to permanently upload data to Irys using their CLI and how to create a dynamic NFT. Data on Irys is onchain, permanent and immutable. When your NFT images and metadata are on Irys, you can guarantee to your users that the NFT will be retrievable forever.

Dynamic NFTs are commonly used with gaming projects, similar to the one we built in this tutorial. However, there are countless other applications too. For example:

  • Points programs: Create an NFT representing a user's participation in a points program. As the user earns more points, the NFT evolves.
  • Sports NFTs: Create an NFT from a sports team that changes whenever the team wins an important game.
  • Holiday NFTs: Create an NFT that changes seasonally to represent different holidays.
  • Activity tracking: Create a health and wellness NFT that changes based on data from an activity tracker.

We use cookies and similar technologies on our websites to enhance and tailor your experience, analyze our traffic, and for security and marketing. You can choose not to allow some type of cookies by clicking . For more information see our Cookie Policy.