DEV Community

Cover image for How to Create an NFT(ERC-721) using OpenZeppelin
Abdul Maajid
Abdul Maajid

Posted on

How to Create an NFT(ERC-721) using OpenZeppelin

Introduction

Now a days blockchain is very trending lot of people are earning by selling and creating NFTs. If you want to build your own NFT collection. So in this article, I will create a non-fungible-token (NFT) and deploy to a public testnet.

What is NFT?

NFT stands for Non Fungible token is used to identify something or someone in a unique way. NFTs are tokens that we can use to represent ownership of any unique item. By NFTS we can tokenize things like art, collectibles, even any real state property. They can have only one owner at a time and they're secured by the Ethereum blockchain. Only owner can transfer ownership of NFT.

NFT Standard(ERC-721)

The ERC-721 is the most common NFT standard. If your Smart Contract implements certain standardized API methods, it can be called an ERC-721 Non-Fungible Token Contract.

These methods are specified in the EIP-721. Open-source projects like OpenZeppelin have simplified the development process by implementing the most common ERC standards as a reusable library.
Here is the final Contract code for NFT which we will deploy to testnet(Ropsten).

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

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

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

    Counters.Counter private _tokenIdCounter;

    constructor() ERC721("ZPunks", "ZPK") {}

    function _baseURI() internal pure override returns (string memory) {
        return "https://ipfs.infura.io:5001/api/v0/cat?arg=";
    }

    function safeMint(address to, string memory uri) public onlyOwner {
        uint256 tokenId = _tokenIdCounter.current();
        _tokenIdCounter.increment();
        _safeMint(to, tokenId);
        _setTokenURI(tokenId, uri);
    }

    // The following functions are overrides required by Solidity.

    function _burn(uint256 tokenId) internal override(ERC721, ERC721URIStorage) {
        super._burn(tokenId);
    }

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

Lets break it to understand every function purpose.

pragma solidity ^0.8.2;
Enter fullscreen mode Exit fullscreen mode

First of all we are setting our solidity version for this contract. In this contract I am setting ^0.8.2 which means to install version 0.8.2 or the latest minor or patch version such as 0.8.7.
And after that we are importing all required files from openzeppelin library. And then inheriting in our main contract.

using Counters for Counters.Counter;
Counters.Counter private _tokenIdCounter;
Enter fullscreen mode Exit fullscreen mode

Here we are using openzeppelin's counter library for saving NFT ids in contract.

constructor() ERC721("ZPunks", "ZPK") {}
function _baseURI() internal pure override returns (string memory) {
    return "https://ipfs.infura.io:5001/api/v0/cat?arg=";
}
Enter fullscreen mode Exit fullscreen mode

After that we are setting NFT name and symbol in constructor. After setting NFT name we set base uri of NFT's data. I set IPFS uri you can set your own api uri too.

function safeMint(address to, string memory uri) public onlyOwner {
    uint256 tokenId = _tokenIdCounter.current();
    _tokenIdCounter.increment();
    _safeMint(to, tokenId);
    _setTokenURI(tokenId, uri);
}
Enter fullscreen mode Exit fullscreen mode

Then we have function for mint our nft. In this function we have two parameters first is the address of the nft owner and second is Hash of data you stored. In this function onlyOwner modifier is used which means this function can only be called by Owner of this contract.

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

Then in the last we have tokenUri function which we will use to retrieve our NFT's stored uri Metadata.

Deploy Contract

Now Lets deploy our NFT contract. I will deploy contract on Polygon Mumbai testnet. You can choose any testnet to deploy. If you want to deploy on Polygon Mumbai tesnet you can add network on metamask using following congiuration.

Network Name: Polygon Testnet

Chain ID: 80001

RPC URL: https://rpc-mumbai.maticvigil.com/

Currency Symbol: MATIC

Block Explorer URL: https://mumbai.polygonscan.com/

We will deploy our contract using remix IDE. Now let open remix IDE. And create new file and name MyNFT.sol.
Screenshot from 2022-01-29 12-44-27.png
After creating new file now copy the above contract code and paste in new created file and save.
Screenshot from 2022-01-29 12-45-26.png
Now lets move to compile section and compile our contract. Here we can see the compiler at top here we can select solidity version. I am using v0.8.7 you can use which you want to use and then press compile button.
Screenshot from 2022-01-29 12-45-53.png
Now lets move to deployment section to deploy our contract on Polygon Mumbai testnet. Here we can see on top ENVIRONMENT change this to Injected Web3 and change contract to contract name you have in file.
Screenshot from 2022-01-29 12-47-59.png
And then click on deploy button and approve transaction after a while you contract will be deployed on blockchain and you can interact with contract and mint your NFT.
Screenshot from 2022-01-29 12-50-13.png
Here we can see all the functions from our contract file. We can mint our first nft using function named safeMint it needs two params one is address and IPFS Hash of nft which you can get after uploading image to IPFS.
Congratulations! on creating your NFT contract.

I hope you found this article useful, if you need any help please let me know in the comment section. Would you like to buy me a coffee, You can do it Here

Let's connect on Twitter and LinkedIn.

👋 Thanks for reading, See you next time

Discussion (4)

Collapse
marsifeanyi profile image
Marcellus Ifeanyi

Great Article.

please can you explain the work of this function

function _burn(uint256 tokenId)
internal
override(ERC721, ERC721URIStorage)
{
super._burn(tokenId);
}

Collapse
abdulmaajid profile image
Abdul Maajid Author

Here we are simply overriding function from ERC721 contract and ERC721URIStorage contract which will be used to burn an NFT and will decrease total supply.

Collapse
saadbh13 profile image
SAAD Bh

My brother Abdul Majeed is with you Saad, can you explain to us how to create a symbol and make it available for sale and purchase, may God reward you with goodness

Collapse
abdulmaajid profile image
Abdul Maajid Author

In the above contract you can see the constructor here we are passing NFT name and symbol check it out.
constructor() ERC721("ZPunks", "ZPK") {}