Skip to main content
This article describes the basic ideas and processes behind the implementation of Jettons (aka tokens in Ethereum) in the TON Blockchain. Standardized tokens on TON (see TEPs 0074 and 0089) are implemented using a set of smart contracts, including: It is important to keep in mind that Jetton standards provide only a general scheme of interaction, leaving the specific implementation of related contracts to developers.

Jetton master

Jetton master smart contracts store general information about a particular jetton, such as total supply (the total number of tokens of this type), a metadata link (or the metadata itself) and a code of the standard jetton-wallet smart contract for this jetton. They also have an owner (admin) who, by sending suitable messages to them, mints new tokens, closes the minting, change metadata or transfers the admin rights to another contract. Jetton master contracts also receive notifications about the burning of tokens. When they receive such a notification, they must adjust the total supply accordingly.

Jetton wallet

Jetton wallet smart contracts are used to transfer, receive, and burn jettons. Each jetton wallet contract stores wallet balance information for specific users (owner), address of Jetton master contract (for appropriate minting), and some additional information. In certain cases, Jetton wallets are used for individual token holders for each token type.

Difference between Jetton wallets and regular ones

Although both regular wallets and Jetton wallets are smart contracts, there are some significant differences between them. The regular wallets smart contract are designed for off-chain interaction with their owner. In most implementations, their main purpose is to receive external messages and perform the operations requested in them. It is through a regular wallet that the user sends requests for the transfer of tokens or their burning to the Jetton wallet smart contract. They are designed to store only the native TON Blockchain currency: toncoins or TONs. On the other hand, Jetton wallets smart contracts are designed only for storing and processing tokens. They ignore any external messages and accept only special internal ones. They execute commands received only from the Jetton master, another Jetton wallet or their owner’s regular wallet smart contracts.

Message layouts

Interactions with Jetton contracts, which are most often encountered by users and developers, are:
  • tokens transfer: sending tokens from one Jetton wallet to another;
  • tokens minting: minting new tokens and transferring them to the Jetton wallet;
  • tokens burning: burn a certain number of tokens on the Jetton wallet contract;
  • wallet address providing: find the address of the Jetton wallet corresponding to a regular wallet.
Nota bene: in all schemes below you will see the query id field. Nowadays the field is almost deprecated, and protocols itself doesn’t need it. It is mostly used for easier off-chain parsing and other web2 processing.

Token transfer

Transfer scheme Actor A regular wallet -> actor A Jetton wallet. Transfer message contains the following data:
NameTypeDescription
query_iduint 64Links the three messaging types—transfer, transfer notification, and excesses—to each other. To ensure this process works correctly, always use a unique query ID.
amountVarUInteger 16The total jetton amount to transfer.
destinationMsgAddressThe address of the actor B regular wallet.
response_destinationmaybe MsgAddressThe optional wallet address used to return remaining Toncoin through the excesses message.
custom_payloadmaybe CellThe optional custom data used by either the sender or receiver jetton wallet for internal logic.
forward_ton_amountVarUInteger 16Toncoins to forward to the recipient. Must > 0 to send a transfer notification with forward_payload and must be less than the Toncoin attached to this message.
forward_payloadmaybe CellOptional data. If the first 32 bits equal 0x00000000, it is a text comment.
Actor A Jetton wallet -> actor B Jetton wallet. Internal transfer message contains the following data:
NameTypeDescription
query_iduint 64Links the three messaging types—transfer, transfer notification, and excesses—to each other. To ensure this process works correctly, always use a unique query ID.
amountVarUInteger 16The total jetton amount to transfer.
senderMsgAddressThe address of the actor A regular wallet.
response_destinationmaybe MsgAddressThe optional wallet address used to return remaining Toncoin through the excesses message.
forward_ton_amountVarUInteger 16Toncoins to forward to the recipient. Must > 0 to send a transfer notification with forward_payload and must be less than the Toncoin attached to this message.
forward_payloadmaybe CellOptional data. If the first 32 bits equal 0x00000000, it is a text comment.
Actor B Jetton wallet → actor B regular wallet. The transfer notification message. This is sent only if forward_ton_amount is not zero and contains the following data:
NameTypeDescription
query_iduint 64Links the three messaging types—transfer, transfer notification, and excesses—to each other. To ensure this process works correctly, always use a unique query ID.
amountVarUInteger 16The total jetton amount were transferred.
senderMsgAddressThe address of the actor A regular wallet.
forward_payloadCellSome data.
Actor B Jetton wallet -> actor C smart contract. Excess message body. This is sent only if there are remaining Toncoin after paying the fees. Contains the following data:
NameType
query_iduint 64

Token minting

Minting scheme Admin regular wallet -> Jetton master contract. Mint message contains the following data:
NameTypeDescription
query_iduint 64To ensure this process works correctly, always use a unique query ID.
receiverMsgAddressThe address of the actor A regular wallet.
mintMessageCellThe rest of data as in internal transfer message except query_id field.
The rest of the messages have already been described above when analyzing the transfer process.

Token burning

Burning scheme Actor A regular wallet -> actor A Jetton wallet. Burn message contains the following data:
NameTypeDescription
query_iduint 64To ensure this process works correctly, always use a unique query ID.
amountVarUInteger 16The total jetton amount to burn.
response_destinationmaybe MsgAddressThe optional wallet address used to return remaining Toncoin through the excesses message.
custom_payloadmaybe CellThe optional custom data used by receiver jetton wallet for internal logic.
Actor A Jetton wallet -> Jetton master contract. Burn notification message contains the following data:
NameTypeDescription
query_iduint 64To ensure this process works correctly, always use a unique query ID.
amountVarUInteger 16The total jetton amount was burned.
senderMsgAddressThe address of the actor A regular wallet.
response_destinationmaybe MsgAddressThe optional wallet address used to return remaining Toncoin through the excesses message.

Wallet address providing

This process is very simple. Some actor sends to the Jetton master contract provide_wallet_address message that contains the following fields:
NameTypeDescription
query_iduint 64To ensure this process works correctly, always use a unique query ID.
owner_addressMsgAddressThe address of the actor which Jetton wallet address is needed.
include_addressBoolWhether to include the address of the actor himself in the output message.
Then, the Jetton master contract sends to the actor a message that contains the following fields:
NameTypeDescription
query_iduint 64To ensure this process works correctly, always use a unique query ID.
wallet_addressMsgAddressThe Jetton wallet contract address.
owner_addressmaybe MsgAddressThe address of the owner.

Interaction from UI

There are three actions that can be performed through the UI:
  • [getting wallet balance](how to: get balance);
  • [transfer jettons](how to: transfer);
  • [indexing available jettons](how to: listing).

Applications

The most popular user wallet applications, such as TonKeeper, use their own SQL-like database. When the user receives new jetton for the first time, the application processes the transfer_notification message. Next, information about the number of jettons received is taken from it and it is checked if there is information about this jetton in the applications database. If there is, information is added to the database stating that the user has a new type of jetton in the amount received. If not, the database starts indexing this new jetton and after the validation process begins to show data about it to users. This is how all the jettons that a given user has and their amounts are listed. In order for a user to transfer a given amount of a token to another user, they only need to fill in the destination and amount fields through the application. Next, it will automatically generate a transfer message and send it to the jetton-wallet smart contract associated with the user.

Web services

Various web services, such as Tonviewer, can also be used to obtain information about the types of user jettons and their amounts. Unlike wallet applications, they also have the ability to directly invoke the get methods of related smart contracts. However, they are not designed to generate and send messages.
I