Token standards
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.
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.
Accounts: Principals and subaccounts
ICP token accounts use principals and their associated subaccount to generate an AccountIdentifier
value to identify the account owner.
ICRC-1 token accounts use 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.
Principals
Every token account is owned by a single principal. Principals are unique identifiers used to identify both users and canisters on ICP.
Subaccounts
Each principal can have multiple accounts identified by a 32-byte
string called a subaccount. Subaccounts are used for organizing funds within a single principal for optimized management and transparency. Subaccounts can be used to distinguish between personal funds and business funds, or separate funds for one project from another.
ICP tokens
The ICP token is the network's native token used for various utility and governance functions, such as:
Converting tokens into cycles.
Rewarding node providers for contributing resources to the network.
Rewarding neurons for staking ICP into a neuron and voting on governance proposals.
ICRC-1
The ICRC-1 standard is for fungible tokens on ICP. It 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 all of the ICRC-1 standard's methods and metadata. The approve
method 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. These workflows are 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 a 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 a subaccount
parameter null
is executed the same as referring to the default subaccount comprised of all zeroes.
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_from
functionalities.
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.