Part 2 of 4 - A Hardhat NFT Smart Contract
We’re going to leverage OpenZeppelin smart contracts for our Hardhat NFT smart contract. From our allcode-polygon-nft directory, we’ll install the OpenZeppelin contracts by running the following command
npm install @openzeppelin/contracts
pragma solidity ^0.8.0;
import "@openzeppelin/contracts/token/ERC721/ERC721.sol";
import "@openzeppelin/contracts/utils/Counters.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
contract AllCodeNFT is ERC721, Ownable {
//imported from OpenZeppelin
using Counters for Counters.Counter;
using Strings for uint256;
Counters.Counter private _tokenIds;
mapping (uint256 => string) private _tokenURIs;
constructor() ERC721("AllCodeNFT", "ANFT") {
}
//Sets the metadata associated with the token. The metadata will be the ipfs hash.
function _setTokenURI(uint256 tokenId, string memory _tokenURI) internal virtual
{
_tokenURIs[tokenId] = _tokenURI;
}
//grabs the tokenURI for the tokenid. effectively grabbing the metadata.
function tokenURI(uint256 tokenId) public view virtual override
returns (string memory)
{
require(_exists(tokenId), "The MetaData for this tokenId does not exist in this contract");
string memory _tokenURI = _tokenURIs[tokenId];
return _tokenURI;
}
//mints a token by taking the metadata passed into the uri,
//and associated that metadata with the recipients address.
//next we assign the uri metadata to the tokenId.
function mint(address recipient, string memory uri) public
returns (uint256)
{
_tokenIds.increment();
uint256 newItemId = _tokenIds.current();
_mint(recipient, newItemId);
_setTokenURI(newItemId, uri);
return newItemId;
}
}
We’ll start by killing the Greeting.sol file in the contracts directory.
Next, we’ll delete the contracts folder in the artifacts directory.
Next, we need to update our test file. Inside the test folder, edit the sample-test.js file by replacing the contents with the following:
const { expect } = require("chai");
describe("NFT Mint", function() {
it("Deploy the NFT contract, mint a token, and ensure that we have the right metadata associated with the tokenId", async function() {
const NFT = await ethers.getContractFactory("AllCodeNFT");
const nft = await NFT.deploy();
const URI = "ipfs://QmVH5T7MFVU52hTfQdWvu73iFPEF3jizuGfyVLccTmBCX2";
await nft.deployed();
await nft.mint("0x44f2b515211953d5f07038be619D58a91accB8E7", URI)
expect(await nft.tokenURI(1)).to.equal(URI)
});
});
In this test script, we’re going to deploy the NFT Contract, mint a token, and then ensure that the token that is minted on the blockchain has the same URI. The URL comes from our Pinata deployment, here. In the invocation of the mint function, you’ll want to replace the address with your address, and the URI with the hash that you acquired from Pinata.
Let’s try running this against the hardhat in-memory network. To run against the hardhat in-memory network, we’ll go into our hardhat.config.js to make the following changes:
- We’ll change the default network from Matic to Hardhat.
- We’ll comment out the Matic network
Your hardhat.config.js should look like this
const { expect } = require("chai");
describe("NFT Mint", function() {
it("Deploy the NFT contract, mint a token, and ensure that we have the right metadata associated with the tokenId", async function() {
const NFT = await ethers.getContractFactory("AllCodeNFT");
const nft = await NFT.deploy();
const URI = "ipfs://QmVH5T7MFVU52hTfQdWvu73iFPEF3jizuGfyVLccTmBCX2";
await nft.deployed();
await nft.mint("0x44f2b515211953d5f07038be619D58a91accB8E7", URI)
expect(await nft.tokenURI(1)).to.equal(URI)
});
});
Now, we’ll run the test by running the following command:
npx hardhat test
const { expect } = require("chai");
describe("NFT Mint", function() {
it("Deploy the NFT contract, mint a token, and ensure that we have the right metadata associated with the tokenId", async function() {
const NFT = await ethers.getContractFactory("AllCodeNFT");
const nft = await NFT.deploy();
const URI = "ipfs://QmVH5T7MFVU52hTfQdWvu73iFPEF3jizuGfyVLccTmBCX2";
await nft.deployed();
await nft.mint("0x44f2b515211953d5f07038be619D58a91accB8E7", URI)
expect(await nft.tokenURI(1)).to.equal(URI)
});
});
Once the test passes, now we’re ready to mint the NFTs on the Mumbai testnet.