Links

Multi Tokens

Terminology

  • Collection - A group of tokens. Also holds data for those tokens and the policies that govern their behavior.
  • Token - A unique asset with a balance
  • Policy - Governs behavior for tokens in a collection
  • Attribute - Metadata for a collection or a token
  • Operator - An account that operates on behalf of another account (transferFrom)
  • Approval - Required for an operator to use an account
  • Freeze/Thaw - If a collection, token, or account is frozen, it cannot transfer tokens
  • Descriptor - Used to create something. For example, a CollectionDescriptor creates a Collection.

Collections

A collection must be created before tokens may be minted. A collection is somewhat akin to an ERC-721 smart contract - its creator has certain privileges, such as minting new tokens or setting metadata for the collection and its tokens.
The first 2000 Collection IDs are reserved for future system collections. Collections created on-chain through this extrinsic start from ID 2001 and are sequentially created.
A deposit of 6.25 ENJ is required to create a collection. The deposit can be recovered by the creator if all tokens are burned and the collection is destroyed.

Custom PolkadotJS explorer pages are available to view collections and tokens. It's located at https://console.enjin.io/ and Multi Tokens page is located in Network tab.
A list of collections is shown with relevant information. Collection rows are expandable to display more details.
Each expanded collection contains information about minted tokens, accounts created with the collection, attributes assigned, as well as different policies set.

Policies

Policies allow controlling behavior of various aspects of tokens in a collection. All policies are contained within the collection, and some of them store data and are configurable. This paradigm was chosen because it allows other blockchains that include pallet-multi-tokens to easily customize its behavior. It also helps the end-user by separating token behavior into separate groups.
There are 5 types of polices:
  • Mint Policy - Handles minting.
  • Burn Policy - Validates burning. Has no configurable parameters.
  • Transfer Policy - Handles transfers, including freezing and allowing transfer_from. Stores the collection freeze state.
  • Attribute Policy - Handles metadata. Does not store data and has no configurable parameters.
  • Market Policy - Handles interfacing with the marketplace. Stores collection royalty.

Tokens

Each token must belong to a Collection, and is created using the mint extrinsic.
There is no distinction between fungible and non-fungible tokens. A non-fungible token is simply a token with a total supply of one. Additional constraints, like a cap, can be applied to a token at the time of minting to make sure the total supply never increases.

Each token has its own page, displaying all relevant details, like minting rules, storage deposits, supply, attributes and more.

How to Create a Collection

A collection is created by using the create_collection extrinsic. The only required parameter is a descriptor which allows customizing the collection's behavior. The descriptor contains all of the policies and some additional settings. Some settings can be changed later using the mutate_collection extrinsic, but the policies currently cannot be changed, so think carefully before choosing the policies.
By default, the policies are flexible, but you can make them more strict. For example, if you want a collection to only contain non-fungible tokens, you can set max_token_supply to Some(1) and force_single_mint to true on the mint policy.
When the collection is created, it will emit a CollectionCreated event. This event contains the collection id that is used to access the collection.

To create a collection, go to the Multi Tokens page and click on the Create Collection button. A form will appear, where you can choose the policies and fill in relevant fields.

How to create a Token

Each token must contain a minimum backing of ENJ to be minted, called Unit Price.
Tokens are created using the mint extrinsic. It only contains two parameters, the recipient and mint params. The mint params is an enum with a few variants. The only important variants are:

CreateToken

This must be used the first time a token is created. The provided token id must not already exist. Some additional settings can be chosen when creating a token, such as setting a cap on the balance or giving it a royalty for the marketplace. If the token is to be an NFT, set the cap to Some(TokenCap::SingleMint) and set initial_supply to 1.
Some of these settings can be changed later by using the mutate_token extrinsic.

To create a token, go to the Multi Tokens page, choose a collection you own and click on the Mint button. A form will appear, where you can choose the initial supply, the recipient of the tokens and more parameters.

Mint

This is used when minting additional balance to an already existing token. The unit price can be supplied if you want to increase it, but it cannot be decreased. Otherwise, set the unit price to None.

To mint additional tokens, go to the existing Token page and click the Mint button. A form will appear, where you can choose the initial supply, the recipient of the tokens and more parameters.

Transfering tokens and NFTs

To perform a transfer, use the transfer extrinsic. There are two types of transfers:

Simple Transfer

A simple transfer is when the origin of the extrinsic is also the sender.

To perform a simple transfer, go to the existing Token page and click the Transfer button. A form will appear, where you can choose the recipient of the tokens and the amount to transfer.

Operator Transfer

An operator transfer allows one account to make transfers on behalf of another account. This is also known as transfer_from. It is the same as SimpleTransfer, but it has a source field. This field is the account that the balance will be transferred from. This requires prior approval.
Approvals can be set for entire collections, or they can be set for specific tokens. They can have expiration times, and specific balances can be set for token approvals. The following extrinsics are used for approvals:
  • approve_collection - Approves all tokens in a collection
  • approve_token - Approves a specific token in a collection for a specific amount. For security reasons, you must specify the exact amount of the previous approval (or zero if there is none) in the current_amount parameter for the extrinsic to succeed
  • unapprove_collection - Removes a collection approval
  • unapprove_token - Removes a token approval

Burning Tokens

Tokens can be burned by calling burn. This works exactly like a transfer, but it will also decrease the total supply of the token.
There is an additional field on the BurnParam called remove_token_storage. If this is set to true, the token will be removed from the storage when it's total supply reaches zero. This can only be done by the token's owner.
If the token is removed from storage, the deposit will be returned to the owner, and it will be as if the token never existed, so it can be recreated in the future.

To burn tokens, go to the existing Token page and click the Burn button. A form will appear, where you can choose the amount to burn.

Setting/Removing Attributes

To add or update metadata for a token or a collection, use the set_attribute extrinsic. Providing token_id adds the attribute to the token, otherwise add it directly to the collection. It's only callable by the collection's owner.
To remove an attribute, use remove_attribute extrinsic. It's only callable by the collection owner. If the token_id is provided, the attribute will be removed from the token. Otherwise, it will be removed from the collection.

Setting Collection Attributes

This is done by clicking the Manage Attributes button under the expanded collection. Use toggle to switch between setting and removing attributes.

Setting Token Attributes

This is done by clicking the Manage Attributes button on the token page. Use toggle to switch between setting and removing attributes.

Freezing

Accounts, collections, and tokens can be frozen to prevent transfers. This is done using the freeze extrinsic, which expects freezing info to be provided. The info specifies whether the collection, token, collection account or token account should be frozen.

Freeze a collection or a collection account

This is done by clicking on Freeze button under expanded collection

Freeze a token or a token account

This is done by clicking on Freeze button on the token page

Thawing

To unfreeze either collection, token, collection account or token account, use the thaw extrinsic. It expects the same info as the freeze extrinsic.

Thaw a collection or a collection account

This is done by clicking on Thaw button under expanded collection

Thaw a token or a token account

This is done by clicking on Thaw button on the token page

Batch operations

It is also possible to perform certain operations in batch. The following operations are supported:

Batch Transfer

Using batch_transfer you can transfer the specific amount of tokens of a collection to list of recipients. If continue_on_failure is false, a single transfer failure will fail all of them. If it is true, execution will continue when a failure is encountered.

Batch Mint

Using batch_mint you can mint the tokens of a collection to a list of recipients consisting of an AccountId and MintParams. If continue_on_failure is false, a single mint failure will fail all operations. If it is true, execution will continue when a failure is encountered.

Batch Set Attribute

Using batch_set_attribute you can set the list of attributes to a collection or a token. If token_id is None, the attribute is added to the collection. If it is Some, the attribute is added to the token.

Remove All Attributes

Removes all attributes from the given collection_id or token_id.
© 2023 Enjin Pte. Ltd.