How to create dynamic NFTs ?
Tags: blockchain, nft, ethereum, smartcontract
Published: 2023-02-11 10:06:41

NFT is a very hot topic 🔥 of discussion these days due to the rise in cryptocurrency and blockchain-related technologies.

## What is a dynamic NFT?
Now whatever NFTs are used currently are static ones, Which means they do not change based on an external trigger. What do I mean by do not change based on the external triggers?

Suppose you own an NFT from a crypto kitties 😺 collection, (If you don't know what is a crypto kitties collection, It is a famous NFT collection of cats arts which you can own and breed to create new kitties based on their attributes.) the NFT that you own is just a JPEG or PNG image at the back end. Now there is a whole story behind how this technology stack works, we will discuss it in another smartbook, but here let's stick to the title. This JPEG or PNG is in a static form means the kitten won't grow older with time or wear outfits according to the weather. Now If we implement something which makes the kitten dynamic then it's called dynamic NFTs.

Now in this smartbook, we will discuss how to mint our own dynamic NFT with the help of revise network.

 

## Technical stack for creating NFT
So the above image shows how the NFT architecture works. 

Some points to consider are -

The digital asset is not stored on the blockchain directly
The digital asset is stored on the cloud storage (it can be centralized [AWS, Google Cloud, etc], or decentralized [IPFS])
The storage link for the digital asset is also not stored in the smart contract directly🙃
There is something called a metadata file that need to be created according to the EIP standard.
This metadata file contains the URL pointing to the digital asset and some attributes like name, description and properties
Now this metadata file is again stored on the cloud storage it can be centralized or decentralized
Now this URL pointing to the metadata file is stored as tokenURI in the smart contract 😇
 

Minting the dynamic NFT 
Now I suppose you are a developer and know the basics of solidity. We are going to use openzeppelin to mint our NFTs. If you don't know what openzeppelin is, it's an open-source contract library that can be used directly to build smart contracts.

 

Minting tokens without any tokenURI (Optional)

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

import "@openzeppelin/contracts/token/ERC721/ERC721.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/utils/Counters.sol";

contract MyToken is ERC721, Ownable {
    using Counters for Counters.Counter;

    Counters.Counter private _tokenIdCounter;

    constructor() ERC721("MyToken", "MTK") {}

    function safeMint(address to) 
         public 
        onlyOwner 
    {
        uint256 tokenId = _tokenIdCounter.current();
        _tokenIdCounter.increment();
        _safeMint(to, tokenId);
    }
}
So the above code is used to create the NFT contract with the help of openzeppelin smart contract. This is very basic smart contract that mints the NFT tokens directly without any tokenURI. 

 

Minting tokens with tokenURI

```
// contracts/GameItem.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import "@openzeppelin/contracts/token/ERC721/extensions/ERC721URIStorage.sol";
import "@openzeppelin/contracts/utils/Counters.sol";

contract GameItem is ERC721URIStorage {
    using Counters for Counters.Counter;
    Counters.Counter private _tokenIds;

    constructor() ERC721("GameItem", "ITM") {}

    function awardItem(address player, string memory tokenURI)
        public
        returns (uint256)
    {
        uint256 newItemId = _tokenIds.current();
        _mint(player, newItemId);
        _setTokenURI(newItemId, tokenURI);

        _tokenIds.increment();
        return newItemId;
    }
}
```
Now in the above example we can set the tokenURI, I have already discussed about how and where the actual digital asset is stored and which tokenURI we are expected to add in the smart contract.

Now we are going to use Revise network to save our digital assets and change it later on to make them dynamic.

now visit the revise network here. and sign in and generate the API key.

Once you have generated the API key let's install the revise SDK on our system. Before that make sure you have nodeJS installed on the system.

 

## Installations
To check if nodeJs is installed on the machine -

node -v

This will return the installed version of nodeJS otherwise the message, "node not found"

To install the nodeJs - 

https://nodejs.org/en/download/

The Revise network page -

https://revise.network/

To install the revise-sdk -

npm install revise-sdk --save
 

--save flag is optional.

To clone the starter pack of revise -

https://github.com/revise-network/nft-tutorial-1

 

Creating Revise project
Now create an empty nodejs project and index.js file and paste the following code in the file 

```
const { Revise } = require("revise-sdk");
const AUTH_TOKEN = "_past your api key"

const revise = new Revise({auth : AUTH_TOKEN});

async function AddNFT(){

    const collection  =  await revise.addCollection
     ({
          name : "_name of your collection",
          uri : "_choose unique uri"
      })

    const nft = await revise.addNFT({
        image : "_url of image", //!change here
        name : "_name of token",
        tokenId : '_id of token',
        description : "_description of token"
    },[
        {mood : 'Happy', stamina : 100}
    ], collection.id)

    console.log("Created NFT successfully, ID:", nft)
    
}

AddNFT()
```
Make sure to replace the API key to AUTH_TOKEN, and choose the unique name of the collection. Also, change all parameters in the addNFT function according to your requirements.

In the array, I have added the additional attributes for the respective NFT.

 

Deploying contract

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

import "@openzeppelin/contracts/token/ERC721/ERC721.sol";

contract MyDNFT is ERC721 {

    string baseuri = "";
    constructor(string memory _baseuri) 
    ERC721("Dynamic NFT", "dNFT")  
    {
        baseuri = _baseuri;
    }

    function mint(address to, uint256 tokenId) 
        public  
    {
        _safeMint(to, tokenId);
    }

    function _baseURI() 
        internal 
        view 
        override(ERC721) 
        returns (string memory)  
   {
        return baseuri;
    }
}
```
Now we will use the above smart contract to mint the NFT collection. Here I have added something called baseuri, this is something that you have to create. It depends on the collection name you have give while adding the NFT to the revise. Suppose your collection name is "MyNFT" then the baseuri will be MyNFT.revise.link.

Now that's it deploy the above smart contract and mint the token, you should see the token metadata along with the digital asset on the opensea. (if you have added the NFT to the revise network, otherwise add the nft again by running the index.js file with node index.js)

 

## Adding dynamic property to the NFT
Create a new file called dynamic.js and paste the following code 

```

const { Revise } = require('revise-sdk')
const AUTH_TOKEN = "_paste your api key"

const revise = new Revise({ auth: AUTH_TOKEN })

const API = async function () {
  const options = [
    {
      mood: 'Angry',
      image:
        '_url pointing to the angry version image of the prajwal',
    },
    {
      mood: 'Shy',
      image:
        '_url pointing to the shy version image of the prajwal',
    },
    {
      mood: 'Denying',
      image:
        '_url pointing to the denying version image of the prajwal',
    },
    {
      mood: 'Loving',
      image:
        '_url pointing to the loving version image of the prajwal',
    },
  ]

  const randomIndex = Math.floor(Math.random() * 4)
  return options[randomIndex]
}

async function run() {
  revise
    .every('2m')
    .listenTo(API)
    .start(async (data) => {
      const prajwal = await revise.fetchNFT(
        '_add your nft id here',
      )

      revise
        .nft(prajwal)
        .setProperty('mood', data.mood)
        .setImage(data.image)
        .save()

      console.log('Curernt mood of prajwal is', data.mood)
    })
}

run()
```
Replace the API key and images url. Also in the fetchNFT add your nft id here. (nftid is printed in the console when you have added the nft to the revise collection.)

Run the file with node dynamic.js

That's all ! Congratulations! 🎉 you have successfully create the dynamic NFT using revise network.

If you want a detailed course on this topic you can visit the following link - 

https://dapp-world.com/course/introduction-to-dynamic-nfts-IsYJ

Thank you!