Token standards
Overview
Tokens deployed on ICP must adhere to a standard. The network's native token, ICP, adheres to its own standard as it is unique on the network in the sense that it is used for network utility and governance. Tokens created for other purposes on the network typically adhere to one of the ICRC standards.
ICRC stands for `Internet Computer Request for Comments'. ICRC standards are proposed by the community working group and are not specific to tokens; they can be created for anything on ICP, such as services, canister calls, or authentication methods. However, this documentation will detail the ICRC standards that are specific to tokens.
In the past, the DIP-721 standard was promoted and used by projects on the network for deploying non-fungible tokens. The ICRC-7 standard has since been developed as a newer alternative to the DIP-721 standard.
How standards are created
The ICRC working group creates an initial proposal for an ICRC standard.
The proposal is agreed upon through a rough consensus of the working group as a starting point for the standard.
The proposal is refined through improvement iterations by the working group.
Once the proposal is deemed ready for implementation by the working group, it is proposed to the NNS through an NNS proposal.
The ICRC standard is either adopted or rejected by the NNS.
ICP tokens
The ICP token is the network's native token used for various utility and governance functions, such as:
Paying for a canister's resources by being converted into cycles.
Rewarding node providers for contributing resources to the network.
Rewarding neurons for staking ICP into the neuron and voting on governance proposals.
View an example dapp for ICP transfers.
ICRC-1
The ICRC-1 standard is for fungible tokens on ICP. It uses an Account
value that corresponds to the pair (principal, subaccount)
, where a principal can have multiple accounts, and each subaccount of a principal is identified by a 32-byte string.
The ICRC-1 standard is considered the 'base' standard and intentionally excludes certain features and functions, such as:
Reliable transaction notifications for smart contracts.
A block structure and the interface for fetching blocks.
Pre-signed transactions.
ICRC-1 supports extensions of this standard to implement these missing functions, and the icrc1_supported_standards
endpoint can be queried to return the name of all supported extensions.
Token metadata
Token metadata is used to provide information about the token, such as the name, symbol, or fee. Available metadata entries for ICRC-1 tokens include:
icrc1:symbol
: The token's currency code, such asvariant { Text = "XTKN" }
.icrc1:name
: The token's name, such asvariant { Text = "Test Token" }
.icrc1:decimals
: The number of decimals used by the token, such asvariant { Nat = 8 }
.icrc1:fee
: The token's default transfer fee, such asvariant { Nat = 10_000 }
.
Example ICRC-1 tokens on ICP include:
View an example dapp for ICRC-1 transfers.
Read the full ICRC-1 standard.
ICRC-2
The ICRC-2 standard is an extension of the ICRC-1 standard that enables additional functionality for icrc2_approve
and icrc2_transfer_from
transactions. Since it is an extension of ICRC-1, it supports the entire ICRC-1 standard's methods and metadata. The approve functionality allows an account owner to delegate token transfers to a third party on the owner's behalf, while the transfer from method enables approved token transactions to be initiated. This approval functionality is common in the Ethereum ecosystem through the ERC-20 token standard.
The approve and transfer from workflow uses two steps:
First, the account owner allows another user to transfer up to X tokens from their account (A) by calling the ledger's
icrc2_approve
method.The user transfers up to X tokens from account A to any account through the
icrc2_transfer_from
method. The number of transfers is not limited as long as the total amount spent is below X.
Example ICRC-2 tokens on ICP include:
View an example of dapp for an ICRC-2 token swap.
View an example of a dapp that enables the transfer_from
workflow.
Read the full ICRC-2 standard.
ICRC-7
ICRC-7 defines a standard for non-fungible tokens (NFTs) on ICP and can be used to create a set of NFTs, also referred to as an NFT collection. It is a minimal standard and can be thought of as the equivalent of the ICRC-1 standard, but for non-fungible tokens instead of fungible tokens. This base standard intentionally excludes some functions, such as:
Reliable transaction notifications for smart contracts.
A block structure and the interface for fetching blocks.
Pre-signed transactions.
ICRC-7 accounts have the same structure and follow the same overall principles as ICRC-1 accounts. ICRC-7 views the ICRC-1 Account
as a primary concept, meaning that operations like transfers always refer to the full account and not only the principal portion. Some methods include an extra optional from_subaccount
or spender_subaccount
parameter that, together with the caller, forms an account to perform the respective operation on. Leaving such subaccount
parameter null
is executed the same as referring to the default subaccount comprised of all zeroes.
An extension of ICRC-7, ICRC-37, extends the standard in the same manner that ICRC-2 extends ICRC-1 as it enables spender approval functionality.
Token metadata
Available metadata entries for ICRC-7 tokens include:
icrc7:symbol
: TypeText
that defines the token's symbol, similar to a token's currency code.icrc7:name
: TypeText
that defines the name of the token.icrc7:description
: TypeText
that provides a description of the token.icrc7:logo
: TypeText
, an optional URL of the token's logo image.icrc7:total_supply
: TypeNat
: The current total number of tokens in existence.icrc7:supply_cap
: TypeNat
, an optional maximum supply of tokens, after which minting new tokens is not possible.
Additional technical metadata elements can be found in the ICRC-7 specification.
Read the full ICRC-7 standard.
ICRC-37
The ICRC-37 standard is an extension of ICRC-7 that provides additional functionality for an approval workflow. This standard adds support for creating approvals, revoking approvals, querying approval information, and making transfers based on approvals. Token ledgers that implement ICRC-37 must implement all of the functions within ICRC-7, but ledgers that support ICRC-7 may choose whether or not to implement ICRC-37 if they intend to offer approve and transfer functionalities. The scope of ICRC-37 was originally part of ICRC-7 but was split into a separate standard for the following reasons:
ICRC-7 and ICRC-37 are much shorter and, hence, easier to navigate on their own.
Ledgers that do not want to implement approval and transfer from semantics do not need to provide dummy implementations of the corresponding methods that fail by default.
Token metadata
ICRC-37 supports all metadata entries in ICRC-7 but also includes the following:
icrc37:max_approvals_per_token_or_collection
: TypeNat
, used to define the maximum number of active approvals the ledger implementation allows per principal or per token.icrc37:max_revoke_approvals
: TypeNat
, an optional number of approvals that may be revoked.
Read the full ICRC-37 standard.
DIP-20
The DIP-20 standard is a fungible token standard for ICP designed to replicate the Ethereum standard ERC-20. DIP-20 is a community-contributed standard that has since been replaced by the ICRC-2 standard.
View the full DIP-20 specification.
DIP-721
The DIP-721 standard is a non-fungible token standard for ICP designed to replicate the Ethereum standard ERC-721. DIP-721 is a community-contributed standard that has since been replaced by the proposed ICRC-7 standard.
View the full DIP-721 specification.