Skip to content

Deploy an ERC-721 Using Hardhat

Beginner

Introduction

Non-Fungible Tokens (NFTs) represent unique digital assets commonly used for digital art, collectibles, gaming, and identity verification.

This guide demonstrates how to deploy an ERC-721 NFT contract to Polkadot Hub TestNet. You'll use OpenZeppelin's battle-tested NFT implementation and Hardhat, a comprehensive development environment with built-in testing, debugging, and deployment capabilities. You can generate a custom NFT contract with the OpenZeppelin Contracts Wizard for Polkadot, then use it in this Hardhat workflow. Hardhat uses standard Solidity compilation to generate EVM bytecode, making it fully compatible with Polkadot Hub's EVM environment.

Prerequisites

Before you begin, ensure you have the following:

  • A basic understanding of Solidity programming and ERC-721 non-fungible tokens.
  • Node.js v22.13.1 or later installed.
  • Test tokens for gas fees, available from the Polkadot faucet. See Get Test Tokens for a guide to using the faucet.
  • A wallet with a private key for signing transactions.

Set Up Your Project

  1. Use the following terminal commands to create a directory and initialize your Hardhat project inside of it:

    mkdir hardhat-nft-deployment
    cd hardhat-nft-deployment
    npx hardhat@^2.27.0 init
    
  2. Install the OpenZeppelin contract dependencies using the command:

    npm install @openzeppelin/contracts
    

Configure Hardhat

Open hardhat.config.ts and update to add polkadotTestnet to the networks configuration as highlighted in the following example code:

hardhat.config.ts
import type { HardhatUserConfig } from 'hardhat/config';

import hardhatToolboxViemPlugin from '@nomicfoundation/hardhat-toolbox-viem';
import { vars } from 'hardhat/config';

const config: HardhatUserConfig = {
  plugins: [hardhatToolboxViemPlugin],
  solidity: {
    version: '0.8.28',
    settings: {
      optimizer: {
        enabled: true,
        runs: 200,
      },
    },
  },
  networks: {
    polkadotTestnet: {
      url: 'https://services.polkadothub-rpc.com/testnet',
      chainId: 420420417,
      accounts: [vars.get('PRIVATE_KEY')],
    },
  },
};

export default config;

Tip

Visit the Hardhat Configuration variables documentation to learn how to use Hardhat to handle your private keys securely.

Create the Contract

Follow these steps to create your smart contract:

  1. Delete the default contract file(s) in the contracts directory.

  2. Create a new file named MyNFT.sol inside the contracts directory.

  3. Add the following code to create the MyNFT.sol smart contract:

    contracts/MyNFT.sol
    // SPDX-License-Identifier: MIT
    pragma solidity ^0.8.20;
    
    import "@openzeppelin/contracts/token/ERC721/ERC721.sol";
    import "@openzeppelin/contracts/access/Ownable.sol";
    
    contract MyNFT is ERC721, Ownable {
        uint256 private _nextTokenId;
    
        constructor(
            address initialOwner
        ) ERC721("MyToken", "MTK") Ownable(initialOwner) {}
    
        function safeMint(address to) public onlyOwner {
            uint256 tokenId = _nextTokenId++;
            _safeMint(to, tokenId);
        }
    }
    

Compile the Contract

Compile your MyNFT.sol contract using the following command:

npx hardhat compile

You will see a message in the terminal confirming the contract was successfully compiled, similar to the following:

npx hardhat compile Downloading solc 0.8.28 Downloading solc 0.8.28 (WASM build) Compiled 1 Solidity file with solc 0.8.28 (evm target: cancun)

Deploy the Contract

You are now ready to deploy the contract to your chosen network. This example demonstrates deployment to the Polkadot TestNet. Deploy the contract as follows:

  1. Delete the default file(s) inside the ignition/modules directory.

  2. Create a new file named MyNFT.ts inside the ignition/modules directory.

  3. Open ignition/modules/MyNFT.ts and add the following code to create your deployment module:

    ignition/modules/MyNFT.ts
    import { buildModule } from '@nomicfoundation/hardhat-ignition/modules';
    
    export default buildModule('MyNFTModule', (m) => {
      const initialOwner = m.getParameter('initialOwner', 'INSERT_OWNER_ADDRESS');
      const myNFT = m.contract('MyNFT', [initialOwner]);
      return { myNFT };
    });
    

    Replace INSERT_OWNER_ADDRESS with your desired owner address.

  4. Deploy your contract to Polkadot Hub TestNet using the following command:

    npx hardhat ignition deploy ignition/modules/MyNFT.ts --network polkadotTestnet
    
  5. Confirm the target deployment network name and chain ID when prompted:

    npx hardhat ignition deploy ignition/modules/MyNFT.ts --network polkadotHubTestnet ✔ Confirm deploy to network polkadotTestnet (420420417)? … yes   Hardhat Ignition 🚀   Deploying [ MyNFTModule ]   Batch #1 Executed MyNFTModule#MyNFT   Batch #2 Executed MyNFTModule#MyNFT.safeMint   [ TokenModule ] successfully deployed 🚀   Deployed Addresses   MyNFTModule#MyNFT - 0x1234.......

Congratulations! You've successfully deployed an ERC-721 NFT contract to Polkadot Hub TestNet using Hardhat. Consider the following resources to build upon your progress.

Where to Go Next

  • Guide Deploy an ERC-20


    Walk through deploying a fully-functional ERC-20 to Polkadot Hub using Hardhat.

    Get Started

  • Guide Create a DApp


    Learn step-by-step how to build a fully functional dApp that interacts with a smart contract deployed via Hardhat.

    Get Started

Last update: February 13, 2026
| Created: January 14, 2026