tick-tock
, merge
, and split
can also initiate transactions.
Each transaction consists of up to five phases:
- Storage phase: calculates storage fees for the contract based on the space it occupies in the blockchain state.
- Credit phase: updates the contract balance by accounting for incoming message values and storage fees.
- Compute phase: executes the contract code on the TON Virtual Machine (TVM). The result includes
exit_code
,actions
,gas_details
,new_storage
, and other data. - Action phase: processes actions from the compute phase if it succeeds.
Actions may include sending messages, updating contract code, or modifying libraries. If an action fails (for example, due to a lack of funds), the transaction may revert or skip the action, depending on its mode. For example,mode = 0, flag = 2
means that any errors arising while processing this message during the action phase are ignored. - Bounce phase: If the compute phase ends with an error and the inbound message has the bounce flag set, this phase generates a bounce message. If the send_msg action failed and it had the +16 flag set, then the bounce phase will also be triggered.
Compute, Action and Bounce phases may be skipped
Execution order notesFor non-bounceable messages:
Credit → Storage → Compute → Action → BounceFor bounceable messages:
Storage → Credit → Compute → Action → Bounce
Fee deduction sequence
- Import fee (before the first phase)
- Storage fee (storage phase)
- Gas fee (compute phase)
- Action fee + forward fee (action phase)
- Additional forward fees (bounce phase)
Storage phase
Cannot be skipped. In this phase, the blockchain processes fees related to the account’s persistent storage. Let’s start by looking at the TL-B schema:storage_fees_due
field is of type Maybe
because it is only present when the account has insufficient balance to cover the storage fees. When the account has enough funds, this field is omitted.
Note: Grams are unsigned integers, so account balances cannot be negative.The
AccStatusChange
field indicates whether the account’s status changed during this phase. For example, see account status variety.
Credit phase
Cannot be skipped. This phase is relatively small and straightforward. The main logic of this phase is to credit the contract’s balance with the remaining value from the incoming message. The credit phase is serialized in TL-B as follows:Field | Type | Description |
---|---|---|
due_fees_collected | Maybe Grams | Amount of previously due storage fees collected (present only if storage fees were due and collected in this phase). |
credit | CurrencyCollection | The amount credited to the account as a result of receiving the incoming message. |
Compute phase
The compute phase is one of the most complex stages of a transaction. This is where the smart contract code, stored in the account’s state, is executed. Unlike previous phases, the TL-B definition for the compute phase includes multiple variants.When the compute phase is skipped
To start, note that the compute phase can be skipped entirely. In that case, the reason for skipping is explicitly recorded and can be one of the following:Skip reason | Description |
---|---|
cskip_no_state | The smart contract has no state and, therefore, no code, so execution is not possible. |
cskip_bad_state | Raised in two cases: when the fixed_prefix_length field has an invalid value or when the StateInit provided in the incoming message does not match the account’s address. |
cskip_no_gas | The incoming message did not provide enough TON to cover the gas required to execute the smart contract. |
cskip_suspended | The address is suspended; execution is disabled (used to limit early miner accounts). |
Bad stateThe
fixed_prefix_length
field can be used to specify a fixed prefix for the account address, ensuring that the account resides in a specific shard.
This topic is outside the scope of this guide, but more information is available in Shards page.Action phase
Once the smart contract code has finished executing, the Action phase begins. If any actions were created during the compute phase, they are processed at this stage. There are precisely 4 types of actions in TON:Type | Description |
---|---|
action_send_msg | Sends a message. |
action_set_code | Updates the smart contract’s code. |
action_reserve_currency | Reserves a portion of the account’s balance. This is especially useful for gas management. |
action_change_library | Changes the library used by the smart contract. |
Bounce phase
If the Compute phase or Action phase ends with an error, and the incoming message has thebounce
flag set, the system triggers the Bounce phase.
Bounce on errorFor the bounce phase to trigger due to an error in the action phase, the failed action must have flag 16 set, which enables bounce on error.
tr_phase_bounce_negfunds
type is not used in the current version of the blockchain. The other two types function as follows:
Type | Description |
---|---|
tr_phase_bounce_nofunds | Indicates that the account does not have enough funds to process the message that should be bounced back to the sender. |
tr_phase_bounce_ok | Indicates that the system successfully processes the bounce and sends the message back to the sender. |
msg_fees
and fwd_fees
are calculated from the total_fwd_fees
:approximately goes to
msg_fees
and go to fwd_fees
.
See Fees → Forward fee for more info.
Key points
- If the receiver cannot parse the message and terminates with a non-zero exit code, the message bounces back automatically.
- The bounced message has its
bounce
flag cleared andbounced
flag set, and contains0xffffffff
(32-bit) op code followed by the original message body. - Always check the
bounced
flag before parsingop
to avoid treating a bounce as a new query.