An Interest In:
Web News this Week
- March 21, 2024
- March 20, 2024
- March 19, 2024
- March 18, 2024
- March 17, 2024
- March 16, 2024
- March 15, 2024
How to create a Smart Contract to mint an NFT
In this article we are going to create a smart contract to mint an NFT on Ethereum.
Setup the project
To start the project we will use the hardhat that will provide us with a boilerplate to deploy the contract, do tests, etc.
Installing the hardhat
We will install hardhat as development dependency using the yarn.
Open a new terminal and run these commands:
mkdir nft-tokencd nft-tokenyarn init -yyarn add hardhat -D
In the same directory where you installed Hardhat run:
npx hardhat
Select Create an empty hardhat.config.js with your keyboard and hit enter.
888 888 888 888 888888 888 888 888 888888 888 888 888 8888888888888 8888b. 888d888 .d88888 88888b. 8888b. 888888888 888 "88b 888P" d88" 888 888 "88b "88b 888888 888 .d888888 888 888 888 888 888 .d888888 888888 888 888 888 888 Y88b 888 888 888 888 888 Y88b.888 888 "Y888888 888 "Y88888 888 888 "Y888888 "Y888 Welcome to Hardhat v2.6.4 ? What do you want to do? Create a basic sample project Create an advanced sample project Create an empty hardhat.config.js Quit
Creating the files and directories
Let's start by creating a directory called contracts in the root folder.
/node_modules/contractshardhat.config.jspackage.jsonyarn.lock
After creating the folder we can create our first file of our contract inside the directory, let's call it: factoryNFT.sol
.
/node_modules/contracts | - factoryNFT.solhardhat.config.jspackage.jsonyarn.lock
Writing the smart contract
Now we go to the most anticipated part of the article, writing our contract.
Note: You can review the basics in my other article: How to create a smart contract to receive donations using Solidity
Let's start defining the pragma version:
factoryNFT.sol
pragma solidity ^0.8.3;
To help us, we will install the openzeppelin contracts package.
yarn add @openzeppelin/contracts @openzeppelin/hardhat-upgrades
Now we can import it into the contract.
factoryNFT.sol
pragma solidity ^0.8.3;import "@openzeppelin/contracts/utils/Counters.sol";import "@openzeppelin/contracts/token/ERC721/extensions/ERC721URIStorage.sol";import "@openzeppelin/contracts/token/ERC721/ERC721.sol";
We made 3 imports:
- Counters: is a useful one that will help us increment a tokenId for each new token.
ERC721URIStorage: we will provide some functions to handle our tokenURI, which contains metadata and image.
ERC721: will we provide some basic functions of the ERC721;
Inheriting the OpenZeppelin contract
Now we can start by defining the name of our contract and inheriting the OpenZeppelin contracts.
factoryNFT.sol
pragma solidity ^0.8.3;import "@openzeppelin/contracts/utils/Counters.sol";import "@openzeppelin/contracts/token/ERC721/extensions/ERC721URIStorage.sol";import "@openzeppelin/contracts/token/ERC721/ERC721.sol";contract FactoryNFT is ERC721URIStorage { using Counters for Counters.Counter; Counters.Counter private _tokenIds; constructor() ERC721("Factory NFT", "FTN") { }}
Creating our Mint function
Let's start by creating our function calling createToken, where it will receive as a parameter, our tokenURI.
factoryNFT.sol
pragma solidity ^0.8.3;import "@openzeppelin/contracts/utils/Counters.sol";import "@openzeppelin/contracts/token/ERC721/extensions/ERC721URIStorage.sol";import "@openzeppelin/contracts/token/ERC721/ERC721.sol";contract FactoryNFT is ERC721URIStorage { using Counters for Counters.Counter; Counters.Counter private _tokenIds; constructor() ERC721("Factory NFT", "FTN") { } function createToken(string memory tokenURI) public returns (uint) { }}
Now let's increment the amount of token in storage and save it in a variable.
factoryNFT.sol
pragma solidity ^0.8.3;import "@openzeppelin/contracts/utils/Counters.sol";import "@openzeppelin/contracts/token/ERC721/extensions/ERC721URIStorage.sol";import "@openzeppelin/contracts/token/ERC721/ERC721.sol";contract FactoryNFT is ERC721URIStorage { using Counters for Counters.Counter; Counters.Counter private _tokenIds; constructor() ERC721("Factory NFT", "FTN") { } function createToken(string memory tokenURI) public returns (uint) { _tokenIds.increment(); uint256 newItemId = _tokenIds.current(); }}
Now we can put the main function of the contract which is to mint our NFT and set its tokenURI.
factoryNFT.sol
pragma solidity ^0.8.3;import "@openzeppelin/contracts/utils/Counters.sol";import "@openzeppelin/contracts/token/ERC721/extensions/ERC721URIStorage.sol";import "@openzeppelin/contracts/token/ERC721/ERC721.sol";contract FactoryNFT is ERC721URIStorage { using Counters for Counters.Counter; Counters.Counter private _tokenIds; constructor() ERC721("Factory NFT", "FTN") { } function createToken(string memory tokenURI) public returns (uint) { _tokenIds.increment(); uint256 newItemId = _tokenIds.current(); _mint(msg.sender, newItemId); _setTokenURI(newItemId, tokenURI); return newItemId; }}
Compiling and testing the Contract
Now to test the contract, we are going to compile it and write a test for it.
First of all let's go to the hardhat.config.js
file and change the solidity version to ^0.8.3.
hardhat.config.js
/** * @type import('hardhat/config').HardhatUserConfig */module.exports = { solidity: "^0.8.3",};
Plugins
Now to test our contract we need to install some plugins for hardhat to help us interact with Ethereum and test our contracts.
yarn add -D @nomiclabs/hardhat-ethers ethers @nomiclabs/hardhat-waffle ethereum-waffle chai
After adding the plugins we need to add a line in hardhat.config.js
to setup the plugins.
hardhat.config.js
require("@nomiclabs/hardhat-waffle");/** * @type import('hardhat/config').HardhatUserConfig */module.exports = { solidity: "^0.8.3",};
Writing the test
Now create a directory called test
in the root folder and add called: factoryNFT.js
.
/node_modules/contracts/test |- factoryNFT.jshardhat.config.jspackage.jsonyarn.lock
Now I am going to put the test below and explain each line to understand it.
const { expect } = require("chai");describe("Minting the token and returning it", function () { it("should the contract be able to mint a function and return it", async function () { const metadata = "https://opensea-creatures-api.herokuapp.com/api/creature/1" //Random metadata url const FactoryContract = await ethers.getContractFactory("FactoryNFT"); // Getting the contract const factoryContract = await FactoryContract.deploy(); //Deploying the Contract const transaction = await factoryContract.createToken(metadata); // Minting the token const tx = await transaction.wait() // Waiting for the token to be minted const event = tx.events[0]; const value = event.args[2]; const tokenId = value.toNumber(); // Getting the tokenID const tokenURI = await factoryContract.tokenURI(tokenId) // Using the tokenURI from ERC721 to retrieve de metadata expect(tokenURI).to.be.equal(metadata); // Comparing and testing });});
Now just compile and run the test and we will have the result!.
npx hardhat compile
npx hardhat test
So we come to the end, soon we will have a tutorial on how to get up to rinkeby testnet.
Follow me on Twitter
Original Link: https://dev.to/emanuelferreira/how-to-create-a-smart-contract-to-mint-a-nft-2bbn
Dev To
An online community for sharing and discovering great ideas, having debates, and making friendsMore About this Source Visit Dev To