A fungible token standard for the DFINITY Internet Computer.
A standard token interface is a basic building block for many applications on the Internet Computer, such as wallets and decentralized exchanges, in this specification we propose a standard token interface for fungible tokens on the IC. This standard provides basic functionality to transfer tokens, allow tokens to be approved so they can be spent by a third-party, it also provides interfaces to query history transactions.
-
Metadata: basic token information
type Metadata = { logo : Text; // base64 encoded logo or logo url name : Text; // token name symbol : Text; // token symbol decimals : Nat8; // token decimal totalSupply : Nat; // token total supply owner : Principal; // token owner fee : Nat; // fee for update calls }
-
TxReceipt: receipt for update calls, contains the transaction index or an error message
public type TxReceipt = { #Ok: Nat; #Err: { #InsufficientAllowance; #InsufficientBalance; #ErrorOperationStyle; #Unauthorized; #LedgerTrap; #ErrorTo; #Other: Text; #BlockUsed; #AmountTooSmall; }; }; when the Transaction status is #failed, an error should be returned instead of a transaction id
-
TxRecord: history transaction record
public type Operation = { #approve; #mint; #transfer; #transferFrom; }; public type TransactionStatus = { #succeeded; #failed; }; public type TxRecord = { caller: ?Principal; op: Operation; // operation type index: Nat; // transaction index from: Principal; to: Principal; amount: Nat; fee: Nat; timestamp: Time.Time; status: TransactionStatus; };
caller
in TxRecord is optional and only need to be non-empty fortransferFrom
calls
The update calls described in this section might choose to charge fee
amount of tokens to prevent DDoS attack, this is necessary because of the reverse gas model of the IC.
All update functions are allowed to trap, instead of returning an error in order to take advantage of the canisters automatic, atomic state rollback.
Please keep in mind that as of now the canisters' stable memory is limited to 8GB. This forces token implementations to come up with their own scalable transaction storage implementation that offloads the data to separate canisters. An other limitation of the Dfinity blockchain is that currently inter-canister query calls are not supported. These limitations together mean that getTransaction and getTransactions functions temporarily have to be update functions.
Transfers value
amount of tokens to user to
, returns a TxReceipt
which contains the transaction index or an error message.
public shared(msg) func transfer(to: Principal, value: Nat) : async TxReceipt
Transfers value
amount of tokens from user from
to user to
, this method allows canster smart contracts to transfer tokens on your behalf, it returns a TxReceipt
which contains the transaction index or an error message.
public shared(msg) func transferFrom(from: Principal, to: Principal, value: Nat) : async TxReceipt
Allows spender
to withdraw tokens from your account, up to the value
amount. If it is called again it overwrites the current allowance with value
. There is no upper limit for value
.
public shared(msg) func approve(spender: Principal, value: Nat) : async TxReceipt
Returns the logo of the token.
public query func logo() : async Text
Returns the name of the token.
public query func name() : async Text
Returns the symbol of the token.
public query func symbol() : async Text
Returns the decimals of the token.
public query func decimals() : async Nat8
Returns the total supply of the token.
public query func totalSupply() : async Nat
Returns the balance of user who
.
public query func balanceOf(who: Principal) : async Nat
Returns the amount which spender
is still allowed to withdraw from owner
.
public query func allowance(owner: Principal, spender: Principal) : async Nat
Returns the metadata of the token.
public query func getMetadata() : async Metadata
The following update calls should be authorized, only the owner
of the token canister can call these functions.
Mint value
number of new tokens to user to
, this will increase the token total supply, only owner
is allowed to mint new tokens.
public shared(msg) func mint(to: Principal, value: Nat): async TxReceipt
Burn value
number of new tokens from user from
, this will decrease the token total supply, only owner
or the user from
him/herself can perform this operation.
public shared(msg) func burn(from: Principal, value: Nat): async TxReceipt
aaaaa-aa
is the IC management canister id, it's not a real canister, just an abstraction of system level management functions, it can be used as blackhole address.
Change the name of the token, no return value needed.
public shared(msg) func setName(name: Text)
Change the logo of the token, no return value needed. The logo
can either be a base64 encoded text of the logo picture or an URL pointing to the logo picture.
public shared(msg) func setLogo(logo: Text)
Set fee to newFee
for update calls(approve
, transfer
, transferFrom
), no return value needed.
public shared(msg) func setFee(newFee: Nat)
Set fee receiver to newFeeTo
, no return value needed.
public shared(msg) func setFeeTo(newFeeTo: Principal)
Set the owner of the token to newOwner
, no return value needed.
public shared(msg) func setOwner(newOwner: Principal)
Returns the history size.
public query func historySize() : async Nat
Returns transaction detail of the transaction identified by index
. If the index
is out of range, the execution traps. Transactions are indexed from zero.
public query func getTransaction(index: Nat) : async TxRecord
Returns an array of transaction records in the range [start, start + limit)
. To fend off DoS attacks, this function is allowed to trap, if limit is greater than the limit allowed by the token. This function is also allowed to trap if start + limit > historySize()
public query func getTransactions(start: Nat, limit: Nat) : async [TxRecord]
Returns an array of transaction records in range [start, start + limit)
related to user who
. Unlike getTransactions
function, the range [start, start + limit) for getUserTransactions is not the global range of all transactions.
The range [start, start + limit) here pertains to the transactions of user who
.
Implementations are allowed to return less TxRecords than requested to fend off DoS attacks.
public query func getUserTransactions(who: Principal, start: Nat, limit: Nat) : async [TxRecord]
Returns total number of transactions related to the user who
.
public query func getUserTransactionAmount(who: Principal) : async Nat