Mastering Onchain NFT

What is NFT?

NFT (ERC721) is a non-fungible token asset that is used to represent unique digital assets. It is basically used to represent a real world as an asset on the blockchain which is attached to a particular user as the authorized owner of the asset.

The process of creating NFT is minting. Each NFT created is minted to an Ethereum address, which ownership can be transferred to another user.

Example of use cases:

  1. Digital Arts

  2. Real Statment Documents

  3. Events Tickets

  4. Music Arts

To get started we will be utilizing Hardhat which you can check out the documentation out.

On your terminal run

npx hardhat init

You should have this result when you finish initializing your hardhat project.

You need to install Openzeppelin smart contract which we will be utilizing

yarn add @openzeppelin/contracts or npm install @openzeppelin/contracts

After you initialize your project create a file name OnchainNft.sol inside your contract folder of the hardhat project you created

To get started with the writing of the Onchain NFT smart contract, in the OnchainNFT.sol file you created

Copy and paste this code

// SPDX-License-Identifier: MIT
pragma solidity 0.8.28;

import "@openzeppelin/contracts/token/ERC721/extensions/ERC721URIStorage.sol";
import {Base64} from "@openzeppelin/contracts/utils/Base64.sol";

We declare the license of this this smart with // SPDX-License-Identifier: MIT, after which the pragma solidity 0.8.28; is the version which we want to use for our smart contract. We import this from Openzeppelin contract we installed import "@openzeppelin/contracts/token/ERC721/extensions/ERC721URIStorage.sol"; an extension of ERC721 this allows us to store the metadata of the NFT we want to create which serves as our token identifiers and includes the;

  1. name

  2. imageURl

  3. description

  4. Attributes

The next import import {Base64} from "@openzeppelin/contracts/utils/Base64.sol"; is to encode data into a binary data format to a readable text format, solidity does not accept images or large files

Copy and paste this code

contract OnchainNft is ERC721URIStorage {
// every other codes will be writing in this code block
}

The above code is the code block where we are going to write all our code, and your code must not be outside the curly braces of the OnchainNFT. The OnchainNft contract inherits from ERC721URIStorage, which is an extension of the ERC-721 Non-Fungible Token (NFT) standard.

Remember inside the curly braces of OnchainNft to put the next line of codes

    uint256 public tokenCounter; // counter
    constructor() ERC721("OnchainNFT", "ONFT") {
        tokenCounter = 0;
    }

We declare a uint256 public tokenCounter; keep track of the number of tokens we have minted or created in our OnChain NFT contract. This is a function in solidity constructor() ERC721("OnchainNFT", "ONFT") { tokenCounter = 0; } which is called once when we want to deploy our contract, we use to it set a variable that we need to initialize at the deployed time, which gives us access to set our tokenCounter = 0; to be zero since we have not created any NFT. Remember our contract was inherited ERC721URIStorage from Openzeppelin which is an extension of ERC721 the contract, you can read more about it. We declare the name of our NFT smart contract name and the symbol ERC721("OnchainNFT", "ONFT") .

In Lines 16 to 20, the function allows us to mint a new NFT to the person calling this function and assigns it metadata (imageURI) which is the parameter we are passing inside the function. It follows the ERC-721 NFT standard, and increases the tokenCounter++.

This function is an internal function that does not modify the state of the chain only returning "data:application/json;base64," It overrides the _baseURI() function from OpenZeppelin's ERC721 contract and sets a custom base URI for NFTs which allows us to be able to read the endcode binary data. We will use this function in the next function when we want to get the URL of previous NFT we created

This function overrides OpenZeppelin’s tokenURI(uint256 tokenId) function from ERC721URIStorage to get the on-chain NFT metadata. To break it down: This function does not modify the state of the blockchain it only reads the state of the blockchain. It replaces the tokenURI from the ERC721URIStorage contract.

The string memory imageURI = ERC721URIStorage.tokenURI(tokenId); is fetching the storeURI image which we stored in the mintNft function above.

In lines 29 to 30, where we are returning string(abi.encodePacked(….)) We are using encodePacked to pack multiple variables together rather than encode which return string we expect will be longer, you can read this article encoding article.

_baseURI We are calling the function that we created earlier to return the "data:application/json;base64," for a proper JSON-readable data. Base64.encode(bytes(…)) this is from Openzeppelin we installed to encode the NFT metadata from bytes to the base64 string so that our NFT website can understand our on-chain NFT.

The abi.encodePacked( '{"name": "', name(), '", "description": "An onchain NFT", ', '"attributes": [{"trait_type": "onchainNft", "value": 100}], ', '"image": "', imageURI, '"}' ) house the metadata JSON format of our NFT metadata packing the multiple variables. This name() is our NFT name which is OnchainNFT as description, attributes, and image that we already described above.

We have been able to successfully implemented Onchain NFT, you can check the github repo for the interaction https://github.com/Amity808/onchainNFT .

Thank You For Reading Along.

0
Subscribe to my newsletter

Read articles from Muhdsodiq Bolarinwa directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Muhdsodiq Bolarinwa
Muhdsodiq Bolarinwa