Write and deploy NFT Smart Contracts

Prajwal Bati
4 min readMar 2, 2023

--

NFT created using data from Substrapunks

In this article, we will setup hardhat to write nft smartcontract, compile and deploy in goerli test network. Please make sure you have metamask account, alchemy account and api key for goerli testnet and other dev environment setup. You need to have some test ether in your metamask account in order to deploy contact. Use goerli faucet to get free test ether if you do not have in your account.

This is the 1st part of NFT tutorial series. You can find 2nd and 3rd part in links below:
2nd part: Create NFT collection and metadata
3rd part: Mint NFTs with web3.js

1. Initialization

First of all, create a folder and navigate into it.

mkdir my-nft
cd my-nft

Initialize the project with npm init.

npm init

Now install hardhat library. It is a development environment to compile and deploy smartcontract.

npm install — save-dev hardhat
npx hardhat
hardhat initialization

Make sure you select create empty hardhat.config.js . We will setup the config file later. It will create an empty hardhat.config.js file in our root directory.

2. Write smart contract

Now create contracts folder and scripts folders inside your project.

mkdir contracts
mkdir scripts

Contracts folder contains smartcontracts of our nft. Scripts folder contains the script to deploy and mint nft.

Now all the setup part is done, let's move to coding part. We will write our nft smartcontract using solidity programming language.

First, install openzeppelin library. We will be extending common contracts from openzeppelin in our contract.

npm install @openzeppelin/contracts

Now create a new file MyNFT.sol and paste the following code.

//Contract based on [https://docs.openzeppelin.com/contracts/3.x/erc721](https://docs.openzeppelin.com/contracts/3.x/erc721)
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.1;

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

contract MyNFT is ERC721URIStorage, Ownable {
using Counters for Counters.Counter;
Counters.Counter private _tokenIds;

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

function mintNFT(address recipient, string memory tokenURI)
public onlyOwner
returns (uint256)
{
_tokenIds.increment();

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

return newItemId;
}
}

Import statements at the top contain the standard implementation ERC-721 which we extend in our contract.

The constructor function has two parameters. The first one is the name for our nft and the second one is a symbol of our nft. You can change it to whatever name and symbol you like.

Function mintNFT with mint the nft to the provided address. Parameter tokenURI is the URL to the metadata of the nft. We will discuss on how to create metadata and its url in another article.

3. Compile and Deploy

After our contract is ready, we need to deploy our contract to the ethereum network. We will be deploying our nft in goerli test network. We need the private key of our metamask account and the alchemy api url which we will set in our .env file. Also do not forget to add .env in .gitignore file since we do not want to expose private keys to public.

Install dotenv package.

npm install dotenv --save

Create a .env file and add alchemy api url and private key in it as below. You can get alchemy api url from alchemy account and metamask private key from metamask.

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

Install ethers js.

npm install --save-dev @nomiclabs/hardhat-ethers ethers@^5.0.0

Next, we will update our hardhat.config.js file. It should look like this.

/**
* @type import('hardhat/config').HardhatUserConfig
*/
require('dotenv').config();
require("@nomiclabs/hardhat-ethers");
const { API_URL, PRIVATE_KEY } = process.env;
module.exports = {
solidity: "0.8.1",
defaultNetwork: "goerli",
networks: {
hardhat: {},
goerli: {
url: API_URL,
accounts: [`0x${PRIVATE_KEY}`]
}
},
}

We have added network details for goerli testnet. We can add support for other networks as required.

Now let’s compile our code using the hardhat compile command.

npx hardhat compile

This command will successfully compile our code if there are no errors. It will first download the solidity compiler if not exists and then compile our code. Compile command will create two folders artifacts and cache which contains build files with contract abi and interfaces. We need to add these folders to the .gitignore file so that they won’t end up in our repo.

Now that our config file is completed and code is compiled, lets write our deploy script. Create deploy.js file inside scripts folder and write below code.

const {ethers} = require('hardhat');

async function main() {
const MyNFT = await ethers.getContractFactory("MyNFT");

// Start deployment, returning a promise that resolves to a contract object
const nft = await MyNFT.deploy();
await nft.deployed();
console.log("Contract deployed to address:", nft.address);
}

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

Above script will take the instance of our smartcontract and deploy it. We then console log the address of deployed nft. We will need the address later for minting nft. So keep the address safe somewhere.

Now lets deploy our contract with following command.

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

In above command, goerli is the name of network we placed in hardhat config file.

After successfully running the command, you can see output in your terminal like below. Address will be different in each deploy.

Contract deployed to address: 0x609A789767b3eE5c4f9b226A284D09f697C79EeE

Our nft is now deployed in goerli test network. You can find your contract in goerli etherscan. You can get full source code in github repo.

We will learn how to create nft metadata and mint nft in another article.
2nd part: Create NFT collection and metadata
3rd part: Mint NFTs with web3.js

Sign up to discover human stories that deepen your understanding of the world.

Free

Distraction-free reading. No ads.

Organize your knowledge with lists and highlights.

Tell your story. Find your audience.

Membership

Read member-only stories

Support writers you read most

Earn money for your writing

Listen to audio narrations

Read offline with the Medium app

--

--

Prajwal Bati
Prajwal Bati

Written by Prajwal Bati

Full Stack | MERN | MEAN | Blockchain | Javascript

No responses yet

Write a response