Semi Fungible Token
Contract Summary
The Semi-Fungible Token (SFT) contract implements the SIP-013 standard, enabling tokens that combine characteristics of both fungible and non-fungible tokens. Built by @MarvinJanssen, this contract allows multiple token classes where each class can have multiple fungible units, similar to ERC-1155 on Ethereum.
Key Features:
SIP-013 Standard Compliance - Implements the official Stacks semi-fungible token trait
Dual Token Architecture - Uses both fungible and non-fungible token primitives for efficient tracking
Per-Token-ID Balances - Each token ID maintains separate balances for different owners
Batch Transfers - Transfer up to 200 different token types in a single transaction
Memo Support - Optional memo field for transfers to include additional metadata
Minting Control - Contract owner can mint new tokens of any token ID
Supply Tracking - Tracks both per-token-ID supply and overall supply across all tokens
What Developers Can Learn:
How to implement SIP-013 semi-fungible token standard
Combining fungible and non-fungible token primitives in a single contract
Efficient batch transfer patterns using fold
Balance tracking with composite map keys (token-id + owner)
NFT tagging technique for ownership discovery
Event emission patterns for indexers and explorers
Function-by-Function Breakdown
SIP-013 Transfer Functions
transfer (token-id uint) (amount uint) (sender principal) (recipient principal)
Transfers a specified amount of a token ID from sender to recipient. Updates both the fungible token balance and NFT ownership tags.
transfer-memo (token-id uint) (amount uint) (sender principal) (recipient principal) (memo (buff 34))
Same as transfer but includes a memo field that is printed as an event. Useful for including payment references or notes.
transfer-many (transfers (list 200 {...}))
Executes multiple transfers in a single transaction using fold. Can transfer up to 200 different token IDs/amounts in one call.
transfer-many-memo (transfers (list 200 {...}))
Batch transfer with memo support, allowing each transfer in the list to include its own memo field.
SIP-013 Query Functions
get-balance (token-id uint) (who principal)
Returns the balance of a specific token ID for a given principal.
get-overall-balance (who principal)
Returns the total balance across all token IDs for a principal using the underlying fungible token.
get-total-supply (token-id uint)
Returns the total supply of a specific token ID across all owners.
get-overall-supply
Returns the total supply of all tokens combined.
get-decimals (token-id uint)
Returns the number of decimals for a token ID (always returns 0 in this implementation).
get-token-uri (token-id uint)
Returns the metadata URI for a token ID (returns none in this implementation).
Minting Functions
mint (token-id uint) (amount uint) (recipient principal)
Mints new tokens of a specific token ID to a recipient. Only callable by the contract owner.
Private Helper Functions
set-balance (token-id uint) (balance uint) (owner principal)
Private function that updates the balance map for a specific token ID and owner combination.
get-balance-uint (token-id uint) (who principal)
Private function that retrieves the balance as a uint, returning 0 if no balance exists.
tag-nft-token-id (nft-token-id {token-id: uint, owner: principal})
Private function that creates or updates NFT ownership tags for discovery. Burns existing tag if present, then mints a new one.
transfer-many-iter (item {...}) (previous-response (response bool uint))
Private fold iterator for batch transfers. Processes each transfer item sequentially, short-circuiting on first error.
transfer-many-memo-iter (item {...}) (previous-response (response bool uint))
Private fold iterator for batch transfers with memos. Same as transfer-many-iter but includes memo handling.
Traits Implemented
sip013-semi-fungible-token-trait
Standard trait for semi-fungible tokens on Stacks, defining the required interface for SFT implementations.
sip013-transfer-many-trait
Extension trait for batch transfer functionality, enabling efficient multi-token transfers.
Key Concepts
Semi-Fungible Token Model
SFTs are tokens where each token ID can have multiple fungible units. Think of it like trading cards - each card design (token ID) is unique, but you can own multiple copies (fungible units) of the same design. This is useful for gaming items, event tickets, or fractional ownership.
Dual Token Architecture
The contract uses both define-fungible-token and define-non-fungible-token primitives. The fungible token tracks overall balances efficiently, while the NFT component provides a discovery mechanism for which token IDs a principal owns.
Supply Tracking at Two Levels
The contract maintains both per-token-ID supply in token-supplies and overall supply using ft-get-supply. This dual tracking enables efficient queries at different granularities without recalculation.
Last updated
Was this helpful?