Non-fungible tokens on Stacks
Creating non-fungible tokens on Stacks
Non-fungible tokens or NFTs are digital assets registered on a blockchain with unique identifiers and properties that distinguish them from each other.
This contract example implements a basic NFT collection that conforms to the SIP-009 NFT standard.
Key Components
Trait Implementation
(impl-trait 'SP2PABAF9FTAJYNFZH93XENAJ8FVY99RRM50D2JG9.nft-trait.nft-trait)
The contract implements the SIP-009 NFT trait, which is a standardized interface ensuring your NFTs will be compatible with wallets, marketplaces, and other applications in the Stacks ecosystem.
NFT Definition
(define-non-fungible-token Your-NFT-Name uint)
This creates your NFT collection with Your-NFT-Name as the identifier. Each token will have a unique integer ID.
State Variables
(define-data-var last-token-id uint u0)
(define-data-var base-uri (string-ascii 80) "https://your.api.com/path/to/collection/{id}")
Constants
(define-constant CONTRACT_OWNER tx-sender)
(define-constant COLLECTION_LIMIT u1000)
(define-constant ERR_OWNER_ONLY (err u100))
(define-constant ERR_NOT_TOKEN_OWNER (err u101))
(define-constant ERR_SOLD_OUT (err u300))
These define important values used throughout the contract:
SIP-009 Required Functions
1. Get Last Token ID
(define-read-only (get-last-token-id)
(ok (var-get last-token-id))
)
Returns the ID of the most recently minted NFT.
2. Get Token URI
(define-read-only (get-token-uri (token-id uint))
(ok (some (var-get base-uri)))
)
Returns the metadata URI for a given token. This implementation returns the same URI for all tokens, but you could modify it to return token-specific URIs.
3. Get Owner
(define-read-only (get-owner (token-id uint))
(ok (nft-get-owner? Your-NFT-Name token-id))
)
Returns the current owner of a specified token using Clarity's built-in nft-get-owner? function.
4. Transfer Function
(define-public (transfer (token-id uint) (sender principal) (recipient principal))
(begin
(asserts! (is-eq tx-sender sender) ERR_NOT_TOKEN_OWNER)
(nft-transfer? Your-NFT-Name token-id sender recipient)
)
)
Allows an owner to transfer their NFT to another account:
Minting Function
(define-public (mint (recipient principal))
(let ((token-id (+ (var-get last-token-id) u1)))
(asserts! (< (var-get last-token-id) COLLECTION_LIMIT) ERR_SOLD_OUT)
(asserts! (is-eq tx-sender CONTRACT_OWNER) ERR_OWNER_ONLY)
(try! (nft-mint? Your-NFT-Name token-id recipient))
(var-set last-token-id token-id)
(ok token-id)
)
)
This function creates a new NFT and assigns it to the specified recipient:
Swap insights and ask questions about “Build On Stacks”.
Ask a question or share your thoughts about this lesson.