Skip to main content

Value as Token

The user's total digital utility in the MOI network can be easily identified by looking at their MOI token balance.

Total Digital Utility (TDU) is a multidimensional digital asset representation used by MOI protocol to map the ownership of all assets belonging to the user.

To create a digital asset (fungible and non-fungible) on the MOI network and assign it a user’s TDU, developers need to follow the following standard:

package DigitalAsset

type AssetID string
type address []byte

// Interface definition
type DigitalAsset interface {
//Methods
transfer(to address, id AssetID, value int, msgData []byte)
transferBatch(to address, ids []AssetID, values []int, msgData []byte)
safeTransferFrom(from address, to address, id AssetID, value int, msgData []byte)
safeTransferFromBatch(from address, to address, ids []AssetID, values []int, msgData []byte)
balanceOf(owner address, id AssetID)
BalanceOfBatch([]address, []id)
setApprovalForAll(operator address, approve bool)
isApprovedForAll(owner address, operator address)
setApproval(operator address, id AssetID, approve bool)
isApproved(owner address, operator address, id AssetID)
symbol(id AssetID)
totalSupply(id AssetID)
dimension(id AssetID)
Mint(to address, id AssetID, value int, msgData []byte)
Burn(owner address, id AssetID, value int)
}

transfer rules

  • The Caller must have enough balance to transfer the mentioned number of tokens in value
  • The to address must exist, else the tokens will not be transferred, and the account state remains unchanged with minor debits to pay the execution cost incurred

transferBatch rules

  • For each ID mentioned by the caller in the ids field, there must be enough balance to transfer the correspondingly mentioned number of tokens in values
  • The to address must exist, else the tokens will not be transferred, and the account state remains unchanged with minor debits to pay the execution cost incurred

safeTransferFrom rules

  • The Caller must be approved to manage the tokens being transferred out of the from account
  • MUST revert if to address is the invalid (zero or not found)
  • The Interaction will be reverted if the balance of holder for token id is lower than the value sent to the recipient
  • After the above conditions are met, if the to address is a contract, the calling function should call onMOITokenReceived implemented by the receiving contract and act accordingly
  • The msgData argument provided by the sender for the transfer MUST be passed with its contents unaltered to the onMOITokenReceived hook function via its msgData argument
  • Execution may fail and revert the states on any other error

safeTransferFromBatch rules

  • The Caller must be approved to manage the tokens being transferred out of the from account
  • MUST revert if to address is the invalid (zero or not found)
  • The Interaction will be reverted if the length of ids is not the same as the length of values
  • The Interaction will be reverted if any of the balance(s) of the holder(s) for the token(s) in ids is lower than the respective amount(s) in values sent to the recipient
  • The balance changes MUST occur in the array order they were submitted (ids[0]/values[0] before ids[1]/values[1], and so on correspondingly)
  • After the above conditions are met, if the to address is a contract, the calling function should call onMOITokenBatchReceived on the to address and act accordingly
  • Execution may fail and revert the states on any other error

Minting/Burning rules

  • Mint/create or Burn/destroy operations are specialized transfers and so will likely be accomplished with custom transfer functions rather than safeTransferFrom or safeBatchTransferFrom
  • from address should be a zero address while performing a create operation
  • to address should be set to zero address while burning the tokens
  • Mint and burn requests are also interactions and results in a change to the account states if signed by the appropriate users

In order to accept transfers, the receiver contract should implement the following interface:

type Receiver interface {
onKIPMOITokenReceived(operator address, from address, id int, value int, msgData []byte)
onKIPMOITokenBatchReceived(operator address, from address, id []int, value []int, msgData []byte)
}

onMOITokenReceived rules

  • The operator argument MUST be the address of an account/contract that is approved to make the transfer (SHOULD be msg.sender)
  • The from argument MUST be the address of the holder whose balance is decreased.
    • from MUST be 0x0 for a mint
  • The id argument MUST be the token type being transferred
  • The value argument MUST be the number of tokens the holder balance is decreased by and match what the recipient balance is increased by
  • The msgData argument MUST contain the information provided by the sender for the transfer with its contents unaltered i.e., it MUST pass on the unaltered msgData argument sent via the safeTransferFrom or safeBatchTransferFrom call for this transfer. Based on the custom definition of this function, suitable actions will be taken by the execution engine. The recipient contract MAY accept an increase of its balance by returning the acceptance magic value bytes4(blake2b("onMOITOKENReceived(address,address,int,int,bytes)")), If the return value is bytes4(blake2b("onMOITOKENReceived(address,address,int,int,bytes)")) the transfer MUST be completed or MUST revert if any other conditions are not met for success
  • The recipient contract MAY reject an increase of its balance by calling revert, f the recipient contract throws/reverts the transaction MUST be reverted
  • If the return value is anything other than bytes4(blake2b("onMOITOKENReceived(address, address, int, int, bytes)")) the transaction MUST be reverted
  • onMOITOKENReceived (and/or onMOITOKENBatchReceived) MAY be called multiple times in a single transaction and the following requirements must be met:
    • All callbacks represent mutually exclusive balance changes.
    • The set of all calls to onMOITOKENReceived and onMOITOKENBatchReceived describes all balance changes that occurred during the transaction in the order submitted
  • A contract MAY sMOI calling the onMOITOKENReceived hook function if the transfer operation is transferring the token to itself

onMOITokenBatchReceived rules

  • The operator argument MUST be the address of an account/contract that is approved to make the transfer (SHOULD be msg.sender)
  • The from argument MUST be the address of the holder whose balance is decreased.
    • from MUST be 0x0 for a mint
  • The ids argument MUST be the list of tokens being transferred
  • The values argument MUST be the list of number of tokens (matching the list and order of tokens specified in ids) the holder balance is decreased by and match what the recipient balance is increased by
  • The msgData argument MUST contain the information provided by the sender for the transfer with its contents unaltered
    • i.e. it MUST pass on the unaltered msgData argument sent via the safeBatchTransferFrom call for this transfer
  • The recipient contract MAY accept an increase of its balance by returning the acceptance magic value bytes4(keccak256("onMOITOKENBatchReceived(address,address,int[],int[],bytes)"))
    • If the return value is bytes4(blake2b("onMOITOKENBatchReceived(address,address,int[],int[],bytes)")) the transfer MUST be completed or MUST revert if any other conditions are not met for success.
  • The recipient contract MAY reject an increase of its balance by calling revert
    • If the recipient contract throws/reverts the transaction MUST be reverted
  • If the return value is anything other than bytes4(blake2b("onMOITOKENBatchReceived(address, address, int[], int[], bytes)")) the transaction MUST be reverted
  • onMOITOKENBatchReceived MAY be called multiple times in a single transaction and the following requirements must be met:
    • All callbacks represent mutually exclusive balance changes
    • The set of all calls to onMOITOKENReceived and onMOITOKENBatchReceived describes all balance changes that occurred during the transaction in the order submitted
  • A contract MAY sMOI calling the onMOITOKENBatchReceived hook function if the transfer operation is transferring the token(s) to itself