TON internal msg sending mode

一、Background

TON is a “message-driven” asynchronous blockchain network. Each “Message” will be accepted and processed by the designated smart contract, and the processing of each message corresponds to a “Transaction”.

While smart contracts process inbound messages, they may also send out new outbound messages, thus forming a chain of messages.

When a smart contract sends a new message, there are many issues to consider, such as:

  1. How to handle amounts attached to inbound messages? After deducting the message processing fee, do I need to refund it? How much will be refunded?
  2. If you want to abandon the current contract, how can you accurately remove the remaining balance of the contract through a message?
  3. If you want to transfer a specific amount n to a contract, how to ensure that the amount n will not be used as gas fees, causing the amount to be less than A?
  4. If you want to send multiple messages at once, and some of the notification types have lower priorities, how can you ignore the low-priority message exceptions and ensure that the high-priority messages are sent normally?

二、Modes and flags

In FunC’s standard library stdlib.fc, there is a core function send_raw_message defined as follows:

() send_raw_message(cell msg, int mode)

The mode is used to define the message sending mode, including whether to pay fuel fees separately and how to handle errors. When TON Virtual Machine (TVM) parses and processes messages, it will perform differentiated processing based on the value of mode.

For example, when the mode is set to 1, that is, the SendPayGasSeparately mode is used, which means that the sender’s account will pay the gas fee separately to ensure that the value of the message is completely delivered to the recipient.

What is easily confusing here is that the value of the mode parameter has two variables, namely mode and flag.

To briefly summarize, mode and flag have different functions.

  • mode : Defines the basic behavior of message sending, such as whether to carry balance, whether to wait for message processing results, etc. Different values of mode represent different sending characteristics, and different values can be combined to meet specific sending requirements.
  • flag : As a complement to mode, it is used to adjust specific behaviors of messages, such as paying transfer fees separately or ignoring processing errors. The flag is added to the mode to construct the final message sending mode.

When using the send_raw_message function, it is important to choose the appropriate mode and flag combination according to your needs. As in the scenario below, you can combine them by simply adding patterns and flags together.

  • If you want to send regular messages and pay for transfers separately, use Mode 0 and Flag +1 to get mode = 1 .
  • If you want to send the entire contract balance and destroy it immediately, use Mode 128 and Flag +32 to get mode = 160 .