🛠️
Stacks Documentation
  • Start Here
  • 🧠Concepts
    • Stacks 101
      • What Is Stacks?
      • Bitcoin Connection
      • Proof of Transfer
      • Stacks Among Other Layers
      • Financial Incentive and Security Budget
    • Network Fundamentals
      • Network Basics
      • Mainnet and Testnets
      • Accounts
      • Authentication
      • Bitcoin Name System
      • SIPs
      • Technical Specifications
    • Block Production
      • Mining
      • Signing
      • Bitcoin Finality
      • Bitcoin Reorgs
      • Stacking
    • Transactions
      • How Transactions Work
      • Post Conditions
    • Clarity
      • Overview
      • Decidability
    • sBTC
      • Core Features
      • sBTC Operations
        • Deposit
        • Withdrawal
        • Deposit vs Withdrawal Times
      • Emily API
      • Peg Wallet UTXO
      • Clarity Contracts
        • sBTC Registry
        • sBTC Token
        • sBTC Deposit
        • sBTC Withdrawal
      • Auxiliary Features
        • Transaction Fee Sponsorship
        • Signer Wallet Rotation
      • Walkthroughs
        • Signer Process Walkthrough
        • sBTC Transaction Walkthrough
      • sBTC FAQ
    • Gaia
      • Configuration
      • Deploy Gaia Hub
      • Amazon EC2
      • Linux
      • Mac OS
  • 🛠️Guides & Tutorials
    • Developer Quickstart
    • Clarity Crash Course
    • Build a Borrowing & Lending Protocol
    • Bitcoin Integration
      • Sending Bitcoin with Leather Wallet
      • Verifying a Bitcoin Transaction
      • Parsing a Bitcoin Transaction
    • Create Tokens
      • Creating a NFT
      • Creating a Fungible Token
    • Build a Frontend
      • Post Conditions with Stacks.js
      • Authentication with Stacks.js
      • Sending Transactions with Stacks.js
    • Testing Smart Contracts
      • Fuzz Testing
    • Run a Node
      • Run a Node with Docker
      • Run a Node with Digital Ocean
      • Run a Node with a Hosted Provider
      • Run a Node with Quicknode
      • Run a Bitcoin Node
      • Run a Pruned Bitcoin Node
    • Run a Miner
      • Miner Prerequisites
      • Miner Costs and Fees
      • Mine Testnet Stacks Tokens
      • Mine Mainnet Stacks Tokens
      • Verify Miner
    • Run a Signer
      • Signer Quickstart
      • How to Read Signer Logs
      • How to Monitor a Signer
      • Best practices for running a Signer
      • OpSec Best Practices
    • sBTC
      • How to Run an sBTC Signer
      • Best practices for running an sBTC Signer
      • How to Use the sBTC Bridge
      • Earn sBTC Rewards
    • Stack STX
      • Solo Stack
      • Operate a Pool
      • Stack with a Pool
      • Increase Stacked Position
      • Stop Stacking
    • Oracles
    • Community Tutorials
  • 📚Reference
    • API
    • Clarity Types
    • Clarity Functions
    • Clarity Keywords
    • Stacks Node Configuration
    • Signer Configuration
    • Stacks Tooling
  • 🏗️Example Contracts
    • Audited Starter Contracts
    • Stacking
    • BNS
    • Multi Send
  • 🧡Press & Top Links
    • 🔶2024
      • 🔸January 2024
      • 🔸February 2024
      • 🔸March 2024
      • 🔸April 2024
      • 🔸May 2024
      • 🔸June 2024
      • 🔸July 2024
      • 🔸August 2024
      • 🔸September 2024
      • 🔸October 2024
      • 🔸November 2024
      • 🔸December 2024
    • 🔶2025
      • 🔸January 2025
      • 🔸February 2025
      • 🔸March 2025
      • 🔸April 2025
      • 🔸May 2025
  • 🧡Bitcoin Theses and Reports
    • 🟠Bitcoin Theses
    • 📙Bitcoin Reports
  • Contribute
Powered by GitBook
On this page
  • Trait
  • Clarity Code

Was this helpful?

  1. Guides & Tutorials
  2. Create Tokens

Creating a NFT

PreviousCreate TokensNextCreating a Fungible Token

Last updated 10 months ago

Was this helpful?

Clarity makes creating NFTs incredibly easy. With built-in functions for creating and working with the token, you can have an NFT created in less than 10 minutes of work.

Let's see how.

:::tip For a more in-depth discussion of NFTs in Clarity and how to create them, check out the . :::

Trait

The first thing we need when we create an NFT is a trait. A trait is an interface that allows us to create an NFT with a defined set of functions. Its primary purpose is to ensure that NFTs are composable and different tools know how to interact with them.

By implementing a trait that the community agrees on, all protocols and products know how they can interact with an NFT.

The official mainnet trait can be and looks like this:

(define-trait nft-trait
  (
    ;; Last token ID, limited to uint range
    (get-last-token-id () (response uint uint))

    ;; URI for metadata associated with the token
    (get-token-uri (uint) (response (optional (string-ascii 256)) uint))

     ;; Owner of a given token identifier
    (get-owner (uint) (response (optional principal) uint))

    ;; Transfer from the sender to a new principal
    (transfer (uint principal principal) (response bool uint))
  )
)

All we are doing here is defining the function signatures for functions we'll need to implement in our Clarity contract, which we can see a simple version of below.

Clarity Code

This is the Clarity code we need in order to create an NFT, with one additional function, mint that allows us to actually create a new NFT. This mint function is not needed to adhere to the trait.

(impl-trait 'SP2PABAF9FTAJYNFZH93XENAJ8FVY99RRM50D2JG9.nft-trait.nft-trait)

(define-non-fungible-token amazing-aardvarks uint)

(define-data-var last-token-id uint u0)

(define-constant contract-owner tx-sender)
(define-constant err-owner-only (err u100))
(define-constant err-not-token-owner (err u101))

(define-read-only (get-last-token-id)
    (ok (var-get last-token-id))
)

(define-read-only (get-token-uri (token-id uint))
    (ok none)
)

(define-read-only (get-owner (token-id uint))
    (ok (nft-get-owner? amazing-aardvarks token-id))
)

(define-public (transfer (token-id uint) (sender principal) (recipient principal))
    (begin
        (asserts! (is-eq tx-sender sender) err-not-token-owner)
        (nft-transfer? amazing-aardvarks token-id sender recipient)
    )
)

(define-public (mint (recipient principal))
    (let
        (
            (token-id (+ (var-get last-token-id) u1))
        )
        (asserts! (is-eq tx-sender contract-owner) err-owner-only)
        (try! (nft-mint? amazing-aardvarks token-id recipient))
        (var-set last-token-id token-id)
        (ok token-id)
    )
)
🛠️
NFTs chapter in the Clarity book
found on the Stacks Explorer