Create ERC-721 NFT

This tutorial will walk you through the steps to create and deploy an ERC-721 token on the Fiefdom Playground Testnet.

ERC-721 tokens, known for their non-fungible characteristics, are perfect for representing unique assets such as game items or digital art for Profile Picture (PFP) projects. This guide is tailored specifically for developers looking to explore and innovate on the Fiefdom Playground Testnet before the mainnet becomes available.


  • Node.js and npm installed on your development machine.

  • A crypto wallet compatible with Ethereum and Fiefdom, such as MetaMask, configured for the Fiefdom Playground Testnet.

  • Familiarity with Solidity and the basics of smart contract development.

Step 1: Project Setup

  1. Create a Project Directory: Make a new directory for your project and navigate into it.

  2. Initialize a Node.js Project: Run npm init -y to create a package.json file.

  3. Install Hardhat: Execute npm install --save-dev hardhat to add Hardhat to your project.

Step 2: Hardhat Project Configuration

  1. Initialize Hardhat: In your project directory, run npx hardhat. Opt for "Create an empty hardhat.config.js" when prompted.

  2. Install OpenZeppelin Contracts: Run npm install @openzeppelin/contracts to get secure ERC-721 implementations.

Step 3: Crafting Your ERC-721 Token Contract

  1. Create a Contracts Directory: Inside your project, make a contracts folder.

  2. Write Your ERC-721 Contract: In contracts, create a file named GameItem.sol or PFPProject.sol. Insert your ERC-721 code, extending OpenZeppelin’s ERC721URIStorage for easy metadata management:

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

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

contract GameItem is ERC721URIStorage {
    using Counters for Counters.Counter;
    Counters.Counter private _tokenIds;

    constructor() ERC721("GameItem", "GMIT") {}

    function mintItem(address player, string memory tokenURI)
        returns (uint256)
        uint256 newItemId = _tokenIds.current();
        _mint(player, newItemId);
        _setTokenURI(newItemId, tokenURI);
        return newItemId;

Step 4: Compiling the Contract

  1. Adjust hardhat.config.js: Modify your Hardhat configuration to include the Fiefdom Playground Testnet details:


module.exports = {
  solidity: "0.8.0",
  networks: {
    fiefdomPlayground: {
      url: "",
      accounts: [/* Your private key */],
      chainId: 712,

Replace /* Your private key */ with your wallet's private key, ensuring proper security practices to protect it.

  1. Compile Your Contract: Run npx hardhat compile.

Step 5: Deploying to the Fiefdom Playground Testnet

  1. Script Creation: In a new scripts directory, add a deploy.js file with deployment logic:

async function main() {
    const [deployer] = await ethers.getSigners();
    console.log("Deploying contracts with the account:", deployer.address);

    const GameItem = await ethers.getContractFactory("GameItem");
    const gameItem = await GameItem.deploy();

    console.log("GameItem deployed to:", gameItem.address);

main().catch((error) => {
  1. Execute Deployment: Deploy your ERC-721 token by running:

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

Enhancing Your ERC-721 Tokens with IPFS for Metadata Storage

Integrating InterPlanetary File System (IPFS) for storing and referencing the metadata of your ERC-721 tokens on the Fiefdom Playground Testnet adds an extra layer of decentralization and permanence to your digital assets.

This approach ensures that your NFTs are not just uniquely identifiable on the blockchain but also securely linked to immutable metadata and media files. Here's how to incorporate IPFS into your ERC-721 token deployment for game items or PFP projects.

Understanding IPFS and Metadata

IPFS is a peer-to-peer protocol for storing and sharing data in a distributed file system. In the context of NFTs, IPFS can host metadata and associated media files (images, videos, etc.), making them accessible through a unique hash known as a Content Identifier (CID). This method guarantees that once your NFT's metadata is on IPFS, it cannot be altered, ensuring the longevity and integrity of the asset's information.

Preparing Your Metadata

  1. Create Metadata JSON: Each NFT should have a corresponding metadata file in JSON format that describes its attributes. For a game item or PFP, this might include name, description, image, and attributes specific to the asset:

  "name": "Epic Sword of Truth",
  "description": "A legendary sword wielded by heroes of old.",
  "image": "ipfs://<YourImageCID>",
  "attributes": [
      "trait_type": "Damage",
      "value": 100
      "trait_type": "Durability",
      "value": "High"
  1. Upload to IPFS: Use an IPFS client or service like Pinata, Infura, or IPFS Desktop to upload your metadata files. Each file will receive a unique CID.

Integrating IPFS with Your ERC-721 Contract

When deploying your GameItem or PFPProject contract, the tokenURI for each minted token should point to its metadata file stored on IPFS.

  1. Minting with IPFS Metadata: In your smart contract's minting function, ensure the tokenURI parameter references the IPFS CID of your metadata JSON file. The ipfs:// URI scheme followed by the CID constitutes the full token URI.

function mintItem(address player, string memory tokenURI)
    returns (uint256)
    uint256 newItemId = _tokenIds.current();
    _mint(player, newItemId);
    _setTokenURI(newItemId, tokenURI); // tokenURI is the IPFS link
    return newItemId;
  1. Example Token URI: If your metadata file's CID on IPFS is QmXkWfWGPxbQtjThvWEPXzNQHgHQ8Z8poL5ZbQmBL4Z7Rs, the tokenURI would be ipfs://QmXkWfWGPxbQtjThvWEPXzNQHgHQ8Z8poL5ZbQmBL4Z7Rs.

Deploying and Testing

Follow the previously outlined steps to deploy your ERC-721 contract to the Fiefdom Playground Testnet, ensuring that when you mint NFTs, you provide the correct IPFS-based tokenURI for each. This setup not only secures your NFT metadata on a decentralized storage platform but also aligns with the best practices of NFT creation, ensuring asset integrity and accessibility.

Last updated