How to Create an NFT Token
Published: 2023-02-27 15:49:37

---
title: How to Create an NFT Token
published: true
date: 2023-02-27 15:36:47 UTC
tags: 
canonical_url: https://blog.michaeltech.xyz/how-to-create-an-nft-token
---

NFT(Non-Fungible Tokens) are tokens used to represent digital assets with inherent properties that are unique and that cannot be exchanged or interchanged(fungible), in many cases, they are used to represent items like images, art, etc. The Ethereum blockchain has a unique standard called the ERC721 for defining the functionality of these tokens. We will follow the template pattern of using Hardhat, Metamask, Alchemy, etc to build our smart contract just like in our other solidity [tutorials](https://dev.to/imohgenius/deploying-a-custom-created-cryptocurrency-on-the-ethereum-network-dh1-temp-slug-4378925)

### Project Setup

```
mkdir MikNFT
cd MikNFT
npm init -y

npm install --save-dev hardhat
npx hardhat

npm i @openzeppelin/contracts

```

The code below imports the ERC721 library and inherits all the function implementation for ERC721, it also uses the Counters library which will be used for counting the number of tokens and giving each a unique positive integer value.

The contract is initialized with the name and symbol for the token the _mintNFT_ function takes into two parameters the _address_ where the NFT will be sent and the _tokenURI_ which gives the metadata description of the token, it then returns the unique integer id of the token

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

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

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

    constructor() ERC721("MikNFT", "NFT") {}

    function mintNFT(address recipient, string memory tokenURI)
        public

        returns (uint256)
    {
        _tokenIds.increment();

        uint256 newItemId = _tokenIds.current();
        _mint(recipient, newItemId);
        _setTokenURI(newItemId, tokenURI);

        return newItemId;
    }
}

```

after it has successfully complied with this command,

```
npx hardhat compile

```

we'll install the _dotenv_ package to enable us to interact with our environment variables. The environment variables that will be used are the wallet private key, _API\_URL,_ and _API\_KEY,_ these will be kept in a _.env_ file that will be added to the project's _.gitignore_ list as these variables are quite sensitive and are not to be uploaded to a public repository.

```
npm install dotenv --save


API_URL = "https://eth-goerli.g.alchemy.com/v2/api-key"
PRIVATE_KEY = "metamask-private-key"
API_KEY = "api-key"

```

We'll go straight ahead to create our _hardhat.config.js_ in the root folder and _deploy.js_ in the scripts folder respectively, the _deploy.js_ script uses the _Ethers.js_ library to handle the deployment of our smart contract.

```
require('dotenv').config();
require("@nomiclabs/hardhat-ethers");

const { API_URL, PRIVATE_KEY } = process.env;

module.exports = {
  solidity: "0.8.17",
  defaultNetwork: "goerli",
  networks: {
    hardhat: {},
    goerli: {
       url: API_URL,
       accounts: [`0x${PRIVATE_KEY}`]
    }
 },
};



async function main() {

// Grab Contract Factory
  const MikNFT = await ethers.getContractFactory("MikNFT");

     // Start deployment, returning a promise that resolves to a contract object
  const mikNFT= await MikNFT.deploy(); // Instance of the contract 

  console.log(
    "Contract deployed to address:", mikNFT.address );
}

// We recommend this pattern to be able to use async/await everywhere
// and properly handle errors.
main()
.then(()=> process.exit(0))
.catch((error) => {
  console.error(error);
  process.exit(1);
});

```

Let's deploy the smart contract on the goerli testnet

```
npx hardhat run scripts/deploy.js --network goerli

```

At the end of the deployment, the contract address will be shown, this is what we'll use to check the details of our transaction on goerli etherscan

```
Contract deployed to address: 0x52Fb82C6D01F4077F18508C1ab59560c651A9099

```

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1677502583866/aef4ae65-baa1-4ae9-8b6f-8c75fcf82fac.png)

You have successfully deployed your NFT smart contract! The next step is to use the contract to mint an NFT

### Minting NFT

So we will decide what we want to put up as an NFT, I 'dreamed' up a really cool art piece using an AI image generation [tool](https://dream.ai/) called Wombo, you can check it out.

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1677510545877/8f7846e1-dabc-403b-93a7-29759a5d5a2d.png)

The primary way to store NFTs is on IPFS(Interplanetary File System) platforms which are decentralized file-sharing networks for keeping data. We'll use [Pinata](https://www.pinata.cloud/) for our example. After creating an account on the platform, we'll upload our image and copy the hash code or content identifier that was generated from the successful upload, the address of the image will be represented like this [https://gateway.pinata.cloud/ipfs/](https://gateway.pinata.cloud/ipfs/)[<](https://gateway.pinata.cloud/ipfs/QmarPqdEuzh5RsWpyH2hZ3qSXBCzC5RyK3ZHnFkAsk7u2f)hash-code>

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1677505110141/ffd9c678-bd89-4234-89ee-4db404ab322d.png)

Then go ahead to create a nft-metadata.json file that provides all the vital attributes for your NFT, make sure the image points to the address of the image, and when this is done make sure this is also uploaded to Pinata and the URL address noted.

```
{
    "attributes" : [ {
      "trait_type" : "Background",
      "value" : "forest"
    }, {
      "trait_type" : "flag",
      "value" : "Nigeria"
    } ],
    "description" : "car moving in a country background, flag seen in the skyline, locally dressed man",
    "image" : "https://gateway.pinata.cloud/ipfs/Qmcp8yj1rBBSJAHmUq3rd3oYF5Uhy2ftBLGLGG4SpPSvzP",
    "name" : "Nairaland"
}

```

we then create a mint-nft.js file that will execute the minting of our NFT, we'll use the contracts' ABI for that, the ABI is a json formatted interface used to interact with the contract, it is automatically generated by hardhat when the contract is compiled, the ABI for this contract is generated in this location.

```
const contract = require("../artifacts/contracts/MikNFT.sol/MikNFT.json");

```

the contract will use the ether library to connect with our node provider using our API key earlier defined in our .env file, it will also use the wallet's private key, the contract's address and the contract's abi to define the contract

```
require('dotenv').config();
const { AlchemyProvider } = require('@ethersproject/providers');
const ethers= require('ethers');

// Get Alchemy API key
const API_KEY= process.env.API_KEY;
// Define an Alchemy Provider
const provider= new ethers.providers.AlchemyProvider('goerli', API_KEY);

const privateKey=process.env.PRIVATE_KEY;
const signer= new ethers.Wallet(privateKey, provider);
// Get contract ABI and address
const abi=contract.abi;
const contractAddress='0x52fb82c6d01f4077f18508c1ab59560c651a9099';

// Create a contract instance
const myNftContract= new ethers.Contract(contractAddress, abi, signer);

```

the _tokenURI_ for our NFT image will now be used and defined in our script, this is how the final version of our _mint-nft.js_ script will look like

```
const contract = require("../artifacts/contracts/MikNFT.sol/MikNFT.json");
require('dotenv').config();
const { AlchemyProvider } = require('@ethersproject/providers');
const ethers= require('ethers');

// Get Alchemy API key
const API_KEY= process.env.API_KEY;
// Define an Alchemy Provider
const provider= new ethers.providers.AlchemyProvider('goerli', API_KEY);

const privateKey=process.env.PRIVATE_KEY;
const signer= new ethers.Wallet(privateKey, provider);

// Get contract ABI and address
const abi=contract.abi;
const contractAddress='0x52fb82c6d01f4077f18508c1ab59560c651a9099';

// Create a contract instance
const myNftContract= new ethers.Contract(contractAddress, abi, signer);

const tokenUri= "https://gateway.pinata.cloud/ipfs/QmQRJK9mMtueyJN9APfQGCdsT1pHELZ9dKN1mcjaRV8qHo";

// Call mintNFT function
const mintNFT = async () => {
    let nftTxn = await myNftContract.mintNFT(signer.address, tokenUri)
    await nftTxn.wait()
    console.log(`NFT Minted! Check it out at: https://goerli.etherscan.io/tx/${nftTxn.hash}`)
}

mintNFT()
    .then(() => process.exit(0))
    .catch((error) => {
        console.error(error);
        process.exit(1);
    });

```

run the below command to execute our script

```
node scripts/mint-nft.js

```

Our output will be like this

```
NFT Minted! Check it out at: https://goerli.etherscan.io/tx/0x907e775d3b45507eb17af5bd97b65c58457b7354354157c7ef148e32f2f8f31c

```

Awesome! what cool NFT project can you spin-off? Happy NFTing!