DEV Community

Abdul Azeez V
Abdul Azeez V

Posted on

Make NFT using ERC721

What is ERC721 ?

ERC721 is a standard that describes how to build NFTs on EVM compatible blockchains. We use the OppenZeppelin implementaion of ERC721

Let's make the NFT

First we need to setup the images and the metadata describing each image. We are creating 6 NFTs. So we have 6 images and metadata files in a directory.

Images and Metadata

The Metadata JSON Schema is given Metadata Schema

{
    "name": "MyNFT Collection #1",
    "description": "My First NFT.",
    "image": "ipfs://imageBaseURI/1.png"
}
Enter fullscreen mode Exit fullscreen mode

Metadata needs the image path. So upload images folder to IPFS first. I used pinata here.

IPFS Upload

Now use the image directory CID to correct metadata files.

{
    "name": "MyNFT Collection #1",
    "description": "My First NFT.",
    "image": "https://gateway.pinata.cloud/ipfs/<PASTE_CID_HERE>/1.png"
}
Enter fullscreen mode Exit fullscreen mode

Upload the metadata files to the IPFS. Now we have both NFT images and metadata in IPFS.

Pinata File Upload

Now we can deploy the contract and mint the NFT.

Smart Contract

Lets import packages needed.

// SPDX-License-Identifier: MIT

pragma solidity ^0.8.20;

import "@openzeppelin/contracts/token/ERC721/ERC721.sol";
import "@openzeppelin/contracts/token/ERC721/extensions/ERC721URIStorage.sol";
import "@openzeppelin/contracts/access/Ownable.sol";

Enter fullscreen mode Exit fullscreen mode

Now the contract extends ERC721:

contract MyNFT is ERC721, ERC721URIStorage, Ownable {
    uint256 private _nextTokenId;

    constructor(address initialOwner)
        ERC721("MyNFT", "MNT")
        Ownable(initialOwner)
    {}

    // functions goes here ...
}
Enter fullscreen mode Exit fullscreen mode

Additional functions needed:

    function safeMint(address to, string memory uri) public onlyOwner {
        uint256 tokenId = _nextTokenId++;
        _safeMint(to, tokenId);
        _setTokenURI(tokenId, uri);
    }

    function tokenURI(uint256 tokenId)
        public
        view
        override(ERC721, ERC721URIStorage)
        returns (string memory)
    {
        return super.tokenURI(tokenId);
    }

    function supportsInterface(bytes4 interfaceId)
        public
        view
        override(ERC721, ERC721URIStorage)
        returns (bool)
    {
        return super.supportsInterface(interfaceId);
    }
Enter fullscreen mode Exit fullscreen mode

Complete code

Deploy contract using hardhat

Install hardhat

npx hardhat init
Enter fullscreen mode Exit fullscreen mode

Get a JSON RPC url from Infura/Alchemy. Setup the hardhat.config.json.

Use the script to deploy and mint the NFT:

const hre = require("hardhat");

async function main() {
     // Deploy contract with initial owner address
     const contract = await hre.ethers.deployContract("MyNFT", ["0xcF469d3BEB3Fc24cEe979eFf83BE33ed50988502"], {});

    await contract.waitForDeployment();

    console.log("Contract deployed to:", contract.target);

    const uris = [
      "https://gateway.pinata.cloud/ipfs/<PASTE_CID_HERE>/1.json",
      "https://gateway.pinata.cloud/ipfs/<PASTE_CID_HERE>/2.json",
      "https://gateway.pinata.cloud/ipfs/<PASTE_CID_HERE>/3.json",
        // Add more URIs as needed
    ];

    for (let i = 0; i < uris.length; i++) {
        const recipientAddress = "0xYourRecipientAddressHere"; // Replace with the actual recipient address
        await myNFT.safeMint(recipientAddress, uris[i]);

        console.log(`Minted NFT with URI ${uris[i]} to address ${recipientAddress}`);
  }
}

main().catch((error) => {
    console.error(error);
    process.exitCode = 1;
});
Enter fullscreen mode Exit fullscreen mode

Now we created and deployed an NFT using ERC721

Github | LinkedIn

Top comments (0)