Semi-Fungible Tokens
A guide to help you create your own semi-fungible tokens
Semi-fungible tokens (SFTs) are a hybrid token structure that embraces parts of both FTs (fungible tokens) and NFTs. SFTs are interchangeable (like FTs) and can be traded between users like cash—1 SFT has the same value as another SFT in the same collection. But each SFT also has a unique identifier (like NFTs).
SFTs are also particularly well suited for Web3 gaming and applications that need to issue lots of different tokens because SFTs enable different asset classes to be managed by a single smart contract (which as a developer is easier to manage and as a user results in cheaper transaction fees).
Custom Development
For developers who want full control over their SFT implementation, here’s how to create a custom SIP-013 SFT on Stacks using Clarity. But before you deploy the SFT contract, you must have your SFT contract conform to the SIP-013 trait standard.
Define SIP-013 semi-fungible token trait
Below is an implementation of the SIP-013 trait standard for semi-fungible tokens. You can use the existing minimal standard SIP-013 trait or extend it by adding in your own custom traits. But the requirements of the SIP-013 traits are necessary to have at the minimum.
All we are doing here is defining the function signatures for functions we'll need to implement in our SFT contract, which we can see a simple version of below.
[optional] transfer-many specification
SIP013 Semi-fungible tokens can also optionally implement the trait sip013-transfer-many-trait to offer a built-in "transfer-many" features for bulk token transfers.
(define-trait sip013-transfer-many-trait
(
;; Transfer many tokens at once.
(transfer-many ((list 200 {token-id: uint, amount: uint, sender: principal, recipient: principal})) (response bool uint))
;; Transfer many tokens at once with memos.
(transfer-many-memo ((list 200 {token-id: uint, amount: uint, sender: principal, recipient: principal, memo: (buff 34)})) (response bool uint))
)
)Implement SIP-013 trait in SFT contract
Any SFT contract that wants to conform to the SIP-013 semi-fungible token standard for Stacks needs to have this trait "implemented" in their SFT contract. See the below minimal SFT contract example of how this is done.
This is the Clarity code we need in order to create a SFT, with an additional function, mint that allows us to actually create a new SFT. This mint function is not needed to adhere to the trait.
The token contract example above is passing in already deployed traits on mainnet into the impl-trait function. You can use these same deployed traits for your own SFT contract as well.
Deployed SIP-013 trait contracts you can directly implement in your custom token contract:
[mainnet] SPDBEG5X8XD50SPM1JJH0E5CTXGDV5NJTKAKKR5V.sip013-semi-fungible-token-trait
[mainnet] SPDBEG5X8XD50SPM1JJH0E5CTXGDV5NJTKAKKR5V.sip013-transfer-many-trait
Reminder: when implementing these deployed traits in your contract, be sure to also add them as contract requirements in Clarinet.
Best Practices
Additional Resources
Last updated
Was this helpful?
