NFT Smart Contract Development and Deployment Guide Using Solidity, Hardhat, and OpenZeppelin

·

Understanding NFTs

NFT (Non-Fungible Token) represents unique, indivisible digital assets. Unlike fungible tokens like Bitcoin (where 1 BTC = 1 BTC), NFTs are distinct—think of them as digital collectibles, artwork, or property deeds where each token holds unique attributes.

Key Characteristics:

Project Initialization

Tools We'll Use:

Setup Steps:

mkdir nft-web3-example && cd nft-web3-example
npm init -y
npm install --save-dev hardhat @nomiclabs/hardhat-waffle ethereum-waffle chai @nomiclabs/hardhat-ethers ethers
npx hardhat

Select "Create a basic sample project" during initialization.

Smart Contract Development

Install OpenZeppelin:

npm install @openzeppelin/contracts

Contract Structure (FOOL_NFT.sol):

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.4;

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

contract FoolNFT is ERC721, ERC721URIStorage, Ownable {
    using Counters for Counters.Counter;
    Counters.Counter private _tokenIdCounter;

    constructor() ERC721("FoolNFT", "FOOL") {}

    function safeMint(address to, string memory uri) public onlyOwner {
        uint256 tokenId = _tokenIdCounter.current();
        _tokenIdCounter.increment();
        _safeMint(to, tokenId);
        _setTokenURI(tokenId, uri);
    }

    // Override required functions
    function _burn(uint256 tokenId) internal override(ERC721, ERC721URIStorage) {
        super._burn(tokenId);
    }
    
    function tokenURI(uint256 tokenId) public view override(ERC721, ERC721URIStorage) returns (string memory) {
        return super.tokenURI(tokenId);
    }
}

Node Configuration

Using Infura for Rinkeby Testnet:

  1. Create an account at Infura
  2. Set up a project with Rinkeby network
  3. Configure .env file:

    PUBLIC_KEY=YOUR_METAMASK_ADDRESS
    PRIVATE_KEY=YOUR_PRIVATE_KEY
    INFURA_API=https://rinkeby.infura.io/v3/YOUR_PROJECT_ID
    NETWORK=rinkeby

Acquiring Test ETH:

Visit Rinkeby Faucet to get test Ether for deployment.

Compiling and Deploying

Compile Contract:

npx hardhat compile

Deployment Script (deploy.js):

const hre = require("hardhat");

async function main() {
  const FoolNFT = await hre.ethers.getContractFactory("FoolNFT");
  const contract = await FoolNFT.deploy();
  await contract.deployed();
  console.log("Contract deployed to:", contract.address);
}
main().catch(console.error);

Run Deployment:

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

Minting NFTs

NFT.Storage Setup:

  1. Get API key from nft.storage
  2. Update .env:

    NFT_STORAGE_TOKEN=YOUR_API_KEY

Minting Script:

const { NFTStorage, File } = require('nft.storage');
const fs = require('fs');

async function mintNFT(imagePath) {
  const client = new NFTStorage({ token: process.env.NFT_STORAGE_TOKEN });
  const image = new File([await fs.promises.readFile(imagePath)], "nft.png", { type: "image/png" });
  
  const metadata = await client.store({
    name: "My NFT",
    description: "Unique digital asset",
    image: image
  });
  
  console.log("Metadata URI:", metadata.url);
}

Viewing Your NFT

After minting, find your NFT on:

👉 Discover how to optimize your NFT's visibility

FAQs

What's the gas cost for NFT deployment?

Typical deployment on Rinkeby costs ~0.004 ETH ($10-$20 equivalent in test ETH).

How do I make my NFT collection public?

Add your contract address to NFT marketplaces after verifying the contract on Etherscan.

Can I upgrade my NFT contract later?

Yes, using proxy patterns like OpenZeppelin's Upgradeable Contracts, but requires careful planning.

👉 Learn advanced NFT contract techniques

Next Steps

  1. Build a frontend with web3-react
  2. Implement royalty structures
  3. Create a whitelist system for presales

This guide provides the foundation for creating and deploying NFT contracts. For deeper technical exploration, consider studying ERC-721A and ERC-1155 standards for batch operations.