Creating Your First NFT on Sui Using Move: A Step-by-Step Guide

ยท

Introduction

This comprehensive tutorial explores how to leverage the Move programming language to create and manage Non-Fungible Tokens (NFTs) on the Sui blockchain. Designed for beginners, this guide covers everything from system initialization to NFT minting and burning processes.

Core Features

The NFT system we'll build includes three fundamental functions:

  1. System Initialization: Setting up the NFT module infrastructure
  2. NFT Minting: Creating and distributing unique digital assets
  3. NFT Burning: Removing assets from circulation when needed

Key Structural Components

Our Move module utilizes four primary structures:

// Module initialization marker
public struct LIZHECOMENFT has drop {}

// NFT entity containing metadata
public struct GithubNFT has key, store {
    id: UID,             // Unique identifier
    nft_id: u64,         // Sequential NFT number
    name: String,        // Asset name
    image_url: String,   // Visual representation
    creator: address,    // Creator's wallet
    recipient: address   // Owner's address
}

// Minting event tracker
public struct NFTMinted has copy, drop {
    object_id: ID,       // NFT object reference
    creator: address,    // Origin address
    name: String         // Asset identifier
}

// Anti-duplication mechanism
public struct MintRecord has key {
    id: UID,             // System identifier
    record: Table<address, u64> // Ownership ledger
}

System Parameters

const MAX_SUPPLY: u64 = 10;     // Maximum issuable NFTs
const ENotEnoughSupply: u64 = 0; // Supply exhaustion error
const EDontMintAgain: u64 = 1;   // Duplicate mint prevention

Initialization Process

The init function establishes the NFT ecosystem:

fun init(otw: LIZHECOMENFT, ctx: &mut TxContext) {
    // Metadata field definitions
    let keys = vector[
        utf8(b"name"),
        utf8(b"description"),
        utf8(b"image_url"),
        utf8(b"creator")
    ];
    
    // Metadata templates
    let values = vector[
        utf8(b"{name} #{nft_id}"),
        utf8(b"A NFT for your Github avatar"),
        utf8(b"{image_url}"),
        utf8(b"{creator}")
    ];

    // Recordkeeping initialization
    let mint_record = MintRecord {
        id: object::new(ctx),
        record: table::new<address, u64>(ctx)
    };

    // Module publication
    let publisher = package::claim(otw, ctx);
    let mut display = display::new_with_fields<GithubNFT>(
        &publisher, keys, values, ctx
    );
    
    // System activation
    transfer::share_object(mint_record);
    display::update_version(&mut display);
    transfer::public_transfer(publisher, ctx.sender());
    transfer::public_transfer(display, ctx.sender());
}

NFT Minting Function

The mint function handles asset creation:

public entry fun mint(
    mint_record: &mut MintRecord,
    name: String,
    image_url: String,
    recipient: address,
    ctx: &mut TxContext
) {
    // Duplicate check
    assert!(!table::contains(&mint_record.record, recipient), EDontMintAgain);
    
    // ID assignment
    let nft_id: u64 = table::length(&mint_record.record) + 1;
    table::add(&mut mint_record.record, recipient, nft_id);
    
    // Supply validation
    assert!(nft_id <= MAX_SUPPLY, ENotEnoughSupply);

    // Asset creation
    let nft = GithubNFT {
        id: object::new(ctx),
        nft_id,
        name,
        image_url,
        creator: ctx.sender(),
        recipient
    };

    // Event emission
    event::emit(NFTMinted {
        object_id: object::id(&nft),
        creator: ctx.sender(),
        name: nft.name
    });

    // Asset transfer
    transfer::public_transfer(nft, recipient);
}

NFT Burning Mechanism

The burn function enables asset removal:

public entry fun burn(
    mint_record: &mut MintRecord,
    nft: GithubNFT
) {
    // Record cleanup
    table::remove(&mut mint_record.record, nft.recipient);
    
    // Object destruction
    let GithubNFT { id, nft_id: _, name: _, image_url: _, creator: _, recipient: _ } = nft;
    object::delete(id);
}

Practical Implementation Guide

Contract Deployment

Begin by publishing your Move package:

sui client publish

NFT Minting Command

Execute the minting process:

sui client call \
    --function mint \
    --module lizhecomenft \
    --package <PACKAGE_ID> \
    --args <MINT_RECORD_OBJECT_ID> "My First NFT" "https://example.com/nft.png" <RECIPIENT_ADDRESS> \
    --gas-budget 1000

๐Ÿ‘‰ Learn more about Sui transaction processing

NFT Burning Command

Remove an existing NFT:

sui client call \
    --function burn \
    --module lizhecomenft \
    --package <PACKAGE_ID> \
    --args <MINT_RECORD_OBJECT_ID> <NFT_OBJECT_ID> \
    --gas-budget 1000

๐Ÿ‘‰ Understanding gas fees on Sui

Frequently Asked Questions

What makes Move different for NFT creation?

Move's resource-oriented model provides enhanced security for digital assets, preventing accidental duplication or loss while maintaining strict ownership rules.

Why limit NFT supply to 10 units?

The MAX_SUPPLY constant demonstrates supply control mechanisms. In production systems, this value would typically be much higher or governed by dynamic rules.

How does the anti-duplication system work?

The MintRecord structure maintains a table of recipient addresses, ensuring each wallet can only mint one NFT through the table::contains check.

Can I modify NFT metadata after minting?

This basic implementation uses immutable metadata. Advanced implementations could add update functions or dynamic property systems.

What happens to burned NFTs?

The object::delete call permanently removes the NFT object from the Sui blockchain's global storage, while the mint record tracks this change.

Conclusion

This implementation demonstrates Sui's capabilities for creating and managing digital assets:

  1. Controlled Issuance: The 10-NFT limit shows supply management
  2. Ownership Tracking: Address-based minting prevents duplicates
  3. Lifecycle Management: Complete create/destroy functionality

๐Ÿ‘‰ Explore advanced Sui development techniques

The system provides an excellent foundation for expanding into more sophisticated NFT applications including:

By mastering these core concepts, developers can build increasingly complex digital asset systems on Sui's high-performance blockchain infrastructure.