ZTP-3525
Introduction
What is the Semi Fungible Token
This standard introduces semi-fungible tokens (SFTs), which allow for dynamic partitioning of tokens into slots, creating a hybrid model that bridges fungible and non-fungible assets. The proposed contract will enhance flexibility, efficiency, and scalability for managing tokenized assets across various use cases, including financial instruments, gaming, and digital ownership.
What is ZTP-3525
ZTP-3525 introduces slot-based token management, where tokens are grouped based on shared characteristics but retain unique balances. This allows for more complex token designs and dynamic allocation of value within a single smart contract.
Semi-Fungibility: Tokens within the same slot act as fungible, while tokens across different slots are non-fungible.
Slot Metadata: Each slot can hold custom metadata, enabling innovative use cases such as dynamic financial instruments or evolving assets.
Batch Operations: The standard supports efficient batch operations, reducing gas costs and improving scalability.
ZTP3525 combines features of fungible and non-fungible tokens, enabling innovative use cases like tokenized subscriptions, multi-asset collateralized loans, dynamic NFTs, shared asset ownership, and loyalty programs. This standard allows tokens to carry both a unique identity and a fungible balance, making it ideal for applications requiring personalized attributes alongside transferable or divisible values. ZTP3525 could power advanced blockchain solutions, such as tradable subscription tokens, customizable financial instruments, interactive game assets, fractionalized ownership, and interoperable reward systems, all while enhancing flexibility and utility in tokenized ecosystems.
Methods
The list below outlines the required methods to be implemented in the contract:
Token definition:
Notes: Token definitions are defined during the init procedure.
init
name
Token Name. Example: “Contract Token”
symbol
Token Symbol. Example: CTK
describe
Token description: “Contract token issued by XYZ”
version
Token version
Example:
Function implementation:
safeTransferFromToken
function safeTransferFromToken(tokenId, toAddress)
The safeTransferFromToken(tokenId, toAddress) function facilitates the secure transfer of a specific token, identified by its tokenId, from the current owner to a designated toAddress. This function ensures that the transfer complies with the token's rules and validates that the recipient can safely handle the token.
transferFromToken
function transferFromToken(tokenId, toAddress)
The transferFromToken(tokenId, toAddress) function executes the transfer of a semi-fungible token identified by tokenId from its current owner to the specified toAddress.
Example:
safeTransferFromBalance
function safeTransferFromBalance(fromTokenId, toTokenId, amount)
The safeTransferFromBalance(fromTokenId, toTokenId, amount) function securely transfers a specified amount of balance from one semi-fungible token (fromTokenId) to another (toTokenId). Unlike transferring an entire token, this function focuses on the fungible value associated with the tokens, ensuring that the balance is accurately moved while preserving the unique identity of both the source and destination tokens.
Example:
transferFromBalance
function transferFromBalance(fromTokenId, toTokenId, amount)
The transferFromBalance(fromTokenId, toTokenId, amount) function transfers a specified amount of balance from one semi-fungible token (fromTokenId) to another (toTokenId). Unlike the safer version, safeTransferFromBalance, this function does not include additional checks for the recipient's ability to handle the balance or compatibility of the tokens.
Example:
approve
function approve(operator, tokenId)
The approve(operator, tokenId) function allows the token owner to grant approval for an operator to manage or transfer a specific token identified by tokenId on their behalf. This approval is specific to the given token, meaning the operator is authorized to perform actions like transferring the token, but only for that particular token ID.
Example:
approveForSlot
function approveForSlot(operator, slotId)
The approveForSlot(operator, slotId) function allows the token owner to grant permission to an operator to manage all tokens associated with a specific slotId. A slot in the ZTP-3525 standard often represents a grouping or categorization of tokens sharing common attributes, such as a shared purpose or financial terms
Example:
approveForAll
function approveForAll(owner, operator)
The approveForAll(owner, operator) function allows the owner of tokens to grant an operator permission to manage all of their tokens without needing individual approvals for each one. This function is often used in scenarios where the owner wants to delegate broad control to an operator, enabling the operator to perform actions like transferring, staking, or interacting with tokens on behalf of the owner.(to), and MUST fire the Transfer event.
Example:
setSlotMetadata
function setSlotMetadata(slotId, tokens, operators, owner)
The setSlotMetadata(slotId, tokens, operators, owner) function allows for the configuration or update of metadata for a specific slotId in a token contract. It enables the assignment of tokens to a slot, designates authorized operators to manage or interact with the tokens, and specifies the owner or controlling address responsible for the slot
Example:
mintToken
function mintToken(toAddress, slotId, tokenId, balance)
The mintToken(toAddress, slotId, tokenId, balance) function is used to mint a new semi-fungible token in a blockchain contract. It assigns a specific tokenId to the newly created token, associates it with a particular slotId (which groups the token with others that share common attributes), and sets the initial balance of the token.
Example:
mintBalance
function mintBalance(tokenId, amount)
The mintBalance(tokenId, amount) function is used to mint additional balance to an existing semi-fungible token identified by its tokenId. This function increases the token's balance by the specified amount, without changing the token's unique identity or slot.
Example:
burnToken
function burnToken(tokenId)
The burnToken(tokenId) function is used to permanently destroy or "burn" a specific semi-fungible token identified by its tokenId. This function reduces the total supply of tokens by removing the specified token from circulation, effectively making it inaccessible for future use or transfer.
Example:
burnBalance
function burnBalance(tokenId, amount)
The burnBalance(tokenId, amount) function is used to destroy or "burn" a specified amount of balance from an existing semi-fungible token identified by its tokenId. Unlike burning the entire token, this function reduces the token's balance by the given amount, effectively decreasing the fungible value associated with the token while retaining its unique identity and slot.
Example:
balanceOf
function balanceOf(address)
The balanceOf(address) function returns the total balance of tokens held by a specific address. In the context of token standards like ZTP-20 or ZTP-3525, it provides the amount of tokens (or the fungible balance) that an address owns.
Example:
ownerOf
function ownerOf(tokenId)
The ownerOf(tokenId) function returns the address of the owner of a specific token identified by its tokenId. This function is commonly used in ZTP-721 (NFT) and ZTP-3525 (semi-fungible) token contracts to determine the current owner of a particular token.
Example:
getApproved
function getApproved(tokenId)
The getApproved(tokenId)function returns the address of the approved operator for a specific token identified by its tokenId. This address is allowed to transfer the token on behalf of the owner.
Example:
isApprovedForAll
functionis ApprovedForAll(owner, operator)
The isApprovedForAll(owner, operator) function checks whether an operator is approved to manage all tokens owned by the owner. This approval is global, meaning the operator can manage any token held by the owner without needing individual approvals for each token.
Example:
isApprovedForSlot
function isApprovedForSlot(slotId, operator) , value)
The isApprovedForSlot(slotId, operator) function checks whether an operator is authorized to manage or interact with all tokens associated with a specific slotId. In token standards like ZTP-3525, where tokens are grouped into slots with shared attributes, this function verifies if the operator has permission to perform actions on all tokens within that slot, such as transfers or other interactions
Example:
slotOf
function slotOf(tokenId)
The slotOf(tokenId) function retrieves the specific slot associated with a given tokenId in the ZTP-3525 token standard. A slot represents a category or grouping of tokens with shared attributes, such as value, purpose, or type.
Example:
contractInfo
function contractInfo()
The contractInfo() function typically returns metadata or key details about the smart contract that governs the token. This can include information such as the contract's name, symbol, total supply, version, or other relevant details defined by the contract.
Example:
tokenURI
function tokenURI(tokenId)
The tokenURI(tokenId) function retrieves the Uniform Resource Identifier (URI) associated with a specific tokenId in a token contract. The URI typically points to a location where metadata about the token is stored, often in JSON format.
Example:
slotURI
function slotURI(slotId)
The slotURI(slotId) function retrieves the Uniform Resource Identifier (URI) associated with a specific slotId in a token contract, typically within the ZTP-3525 standard.
Example:
totalSupply
function totalSupply()
The totalSupply() function returns the total number of tokens that exist within a specific contract or token standard, often used to represent the total circulating supply.
Example:
tokensOfOwner
function tokensOfOwner(address)
The tokensOfOwner(address) function returns a list of token IDs owned by a specific address. In the context of token standards like ZTP-3525, ZTP-721, or ZTP-20, it allows users to query which tokens are owned by a particular wallet or address.
Example:
tokensInSlot
function tokensInSlot(slotId)
The tokensInSlot(slotId) function returns a list of all token IDs associated with a specific slotId. In token standards like ZTP-3525, a slot represents a grouping or categorisation of tokens that share common attributes, such as purpose, value, or functionality.
Example:
getSlotMetadata
function getSlotMetadata(slotId)
The getSlotMetadata(slotId) function retrieves the metadata associated with a specific slotId in a token contract. This metadata can include details about the attributes, rights, or characteristics that are common to all tokens within that slot, such as its purpose, associated values, or restrictions.
Example:
query
function query(input_str)
The query(input_str)function is typically used to search or retrieve information based on a given input string (input_str). The function is designed to process the input, which can be a request or a query, and return relevant results or data from a database, smart contract, or external service.
Example:
main
function main(input_str)
The main(input_str) function serves as the entry point for executing a process that takes an input string (input_str). This function processes the input, which could be a query, command, or data, and then executes a defined set of actions based on that input.
Example:
Full ZTP-3525 contract example:
Use Case
A use case for the ZTP-3525 standard, which is designed for semi-fungible tokens (SFTs) on the Zetrix blockchain, involves creating a tokenized subscription service. Here's how it works:
Tokenized Subscription Service with ZTP-3525
In this scenario, ZTP-3525 tokens are used to represent subscription plans with both unique and fungible properties. Each subscription plan is represented by a token (tokenId) that holds a balance (fungible) to represent usage, duration, or remaining service credits.
Steps for Implementation:
Minting Subscription Tokens: The service provider mints ZTP-3525 tokens for a user, assigning them a
tokenIdlinked to a specific subscription plan (e.g., "Premium Plan" or "Basic Plan"). This token is linked to aslotId, representing the type or category of the subscription (e.g., "Premium", "Basic").Tracking Balance: The
balanceassociated with thetokenIdkeeps track of the subscription's usage, such as how many hours of service or credits remain. For example, a "Premium Plan" token might have a balance of 30, representing 30 days of service left.Transferring or Selling: If the user decides to transfer their remaining subscription balance to someone else (for example, selling part of the remaining credits), they can use
safeTransferFromBalanceortransferFromBalanceto move a portion of their subscription balance to another user's token, allowing partial transfers of service.Slot Management: The service can define different slots for various types of subscriptions (e.g., “Basic”, “Premium”). This allows the operator to manage all tokens within a particular category or plan using the
approveForSlotfunction, where an authorized operator can transfer, manage, or adjust all tokens in the “Premium” slot, for example.Burning Subscription Tokens: When the subscription expires or the service is fully used, the token can be "burned" using the
burnTokenorburnBalancefunction, removing the subscription token from circulation, reflecting that the user has used or forfeited their subscription.
Benefits of Using ZTP-3525 for Subscription Services:
Flexibility: A token can represent both the unique identity of a subscription and the fungible balance of remaining service, allowing seamless management of credits or time-based services.
Partial Transfers: Users can transfer portions of their subscription or balance to others, allowing flexible use of services.
Efficient Slot Management: Subscription plans can be grouped into slots, simplifying management and control for operators (e.g., managing the entire Premium plan in one action).
Transparency: Smart contracts ensure the automatic and transparent management of tokens, including subscription duration and usage.
This use case demonstrates how ZTP-3525’s combination of non-fungible and fungible elements can be leveraged to manage services that require both unique attributes and divisible, transferable balances on the Zetrix blockchain.
Last updated