Skip to content

๐ŸŽจ NFT Minting โ€‹

Quest Objective: Mint your first Non-Fungible Token on Ergo Prerequisites: Understanding of tokens Time Required: ~45 minutes Difficulty: โญโญโญ Medium

๐ŸŽฏ What You'll Build โ€‹

By the end of this tutorial, you'll know how to:

  • โœ… Create unique NFTs on Ergo
  • โœ… Add metadata using registers
  • โœ… Follow EIP-4 NFT standards
  • โœ… Include images and descriptions

๐Ÿ–ผ๏ธ NFT Structure on Ergo โ€‹

NFTs on Ergo follow EIP-4 (Ergo Improvement Proposal 4):

mermaid
graph TD
    subgraph "๐Ÿ“ฆ NFT Box"
        B[Box]
        V[value: SAFE_MIN_BOX_VALUE]
        A[assets: tokenId, amount: 1]
        R4[R4: Name]
        R5[R5: Description]
        R6[R6: Decimals = 0]
        R7[R7: Type = NFT]
        R8[R8: SHA256 Hash]
        R9[R9: Link/IPFS]
    end
    
    B --> V
    B --> A
    B --> R4
    B --> R5
    B --> R6
    B --> R7
    B --> R8
    B --> R9

๐Ÿ’ป Complete NFT Minting Example โ€‹

typescript
/**
 * ๐ŸŽจ QUEST: Mint an NFT
 * 
 * Create a unique digital collectible on Ergo
 */

import { 
  TransactionBuilder, 
  OutputBuilder,
  SAFE_MIN_BOX_VALUE,
  SByte,
  SColl
} from "@fleet-sdk/core";

// NFT Metadata
const NFT_DATA = {
  name: "Epic Dragon #001",
  description: "A legendary dragon from the Ergo realm",
  mediaUrl: "ipfs://QmXxx.../dragon.png",
  mediaHash: "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
};

async function mintNFT() {
  console.log("๐ŸŽจ Minting NFT...\n");

  const inputBox = {
    boxId: "nft-box-id-becomes-token-id",
    value: 1_000_000_000n,
    ergoTree: "0008cd...",
    creationHeight: 1_100_000,
    assets: [],
    additionalRegisters: {},
    transactionId: "tx123...",
    index: 0
  };

  // Create NFT output with full metadata
  const nftOutput = new OutputBuilder(
    SAFE_MIN_BOX_VALUE,
    "9f4QF8AD1nQ3nJahQVkMj8hFSVVzVom77b52JU7EW71Zexg6N8v"
  )
  .mintToken({
    amount: 1n,  // NFT = exactly 1 token
    name: NFT_DATA.name,
    decimals: 0,
    description: NFT_DATA.description
  })
  .setAdditionalRegisters({
    // R7: NFT type (1 = image, 2 = audio, 3 = video)
    R7: SColl(SByte, [0x01]).toHex(),
    // R8: SHA256 hash of media file
    R8: SColl(SByte, Buffer.from(NFT_DATA.mediaHash, 'hex')).toHex(),
    // R9: Media URL
    R9: SColl(SByte, Buffer.from(NFT_DATA.mediaUrl)).toHex()
  });

  const tx = new TransactionBuilder(1_200_000)
    .from([inputBox])
    .to(nftOutput)
    .sendChangeTo("9f4QF8AD1nQ3nJahQVkMj8hFSVVzVom77b52JU7EW71Zexg6N8v")
    .payMinFee()
    .build();

  console.log("โœ… NFT Minted!");
  console.log(`   Name: ${NFT_DATA.name}`);
  console.log(`   Token ID: ${inputBox.boxId}`);
  console.log(`   Media: ${NFT_DATA.mediaUrl}`);
  
  return tx;
}

mintNFT();

๐Ÿ“‹ EIP-4 Register Reference โ€‹

RegisterPurposeTypeExample
R4NameColl[Byte]"My NFT"
R5DescriptionColl[Byte]"Description..."
R6DecimalsColl[Byte][0x00] for NFT
R7TypeColl[Byte]0x01=image, 0x02=audio
R8HashColl[Byte]SHA256 of media
R9LinkColl[Byte]IPFS/URL

๐Ÿš€ Next Quest โ€‹

Ready for smart contracts? Continue to Smart Contracts โ†’!

Released under the MIT License.