Dynamic NFT Extension
Intro
One of the more common requests we get is "wen dynamic NFTs with Manifold". Well - probably the easiest way is with HTML NFTs as described here. But using an extension to make a dynamic NFT is also possible and desirable in some cases. Here we'll write an extension that displays two different pieces of art depending on the current block timestamp when the token URI is retrieved.
Before we start deploying things, let's take a look at the contract. We'll be making an extension for an ERC721 token, but a similar process can be done for ERC1155s.
Contract
Let's walk through the contract here before we think about deploying it.
The first function we have there is called initialize
and this is where we actually mint the token. It is important to note that we're taking the assumption here that the extension will only be used for one token, or at least that every token minted on this contract has the same set of URIs. When we call this function, we're saving the address of our core contract, and calling the mintExtension
function on it to mint the token.
The supportsInterface
function simply tells other contracts that are calling this one what functions it supports.
The setURIs
function lets us set the two different tokenURIs we want to return, depending on the block number. It also lets us update this information at any time in the future.
Finally, the tokenURI
function is where the "magic" happens. We first check that the core address is the same as we expect, and then if the time of the block is even, we return the first URI, otherwise we return the second.
How to Deploy
As this tutorial is focused on actual contracts and Manifold-specific logic, I won't go too in-depth into tools. I really like Remix for this kind of thing, but use whatever you are most comfortable with! Here is the order of how I would deploy:
Deploy core contract (using Manifold Studio is easiest) - example here
Deploy the extension contract - example here
Register the extension with #14
registerExtension
on your base contract - example hereInitialize the extension with #2
initialize
- example hereSet the two baseURIs for your extension - example here
You should be able to see your token on OpenSea TestNet. Here is mine:
https://testnets.opensea.io/assets/0x2a648332d26747be06a4e110cfb3fbff56c289b3/1
There are just a couple things to note here. The first is that this is token #1 on the core contract. Notice the OpenSea URL which has the address of the core contract. The other thing to note is minute - but the data is cached for performance reasons on OpenSea's side, so even though this technically switches which image quite often, you may not find that to be the case on many marketplace websites. Perhaps yours switches once a month, in which case, there is no issue.
FAQ
Is this contract an ERC721 contract?
No - but it helps you mint a token on an ERC721 contract (your core contract)
Can this deployed contract be re-used?
Not in its current form. However, an extension can be written in such a way that it manages tokens for many different core contracts.
What is the gas cost for deploying an extension like this?
This particular extension cost me 1,515,346 gas to deploy. At gas prices of 40 gwei, that would be about 0.06 ETH.
Last updated