Forward fees
This page explains how smart contracts handle message forwarding fees and value transfers between contracts.
Overview
When a smart contract sends a query to another smart contract, it must pay for:
- Sending the internal message (message forwarding fees)
- Processing the message (gas fees)
- Sending back the answer, if required (message forwarding fees)
Standard message handling
In most cases, the sender:
- Attaches enough Toncoin to cover gas and forwarding fees to the internal message
- Sets the
bounce
flag (sends a bounceable internal message)
The receiver then returns the unused portion of the received value with the answer, deducting message forwarding fees.
In Jettons it is typically done using RAWRESERVE
with SENDRAWMSG
+ mode = 128/130/144
.
Message bouncing
Automatic bouncing
If the receiver cannot parse the received message and terminates with a non-zero exit code (for example, due to an unhandled cell deserialization exception), the message automatically bounces back to its sender. The bounced message:
- Has its
bounce
flag cleared - Has its
bounced
flag set - Contains
0xffffffff
(32-bit) followed by the original message body (256-bit)
Handling bounced messages
Always check the bounced
flag of incoming internal messages before parsing the op
field. This prevents processing a bounced message as a new query.
If the bounced
flag is set:
- You can identify the failed query by deserializing
op
andquery_id
- Take appropriate action based on the failure
- Alternatively, terminate with zero exit code to ignore bounced messages
The bounced
flag is set by the protocol during bounce; a message with this flag indicates a bounced message. See also: non-bounceable messages.
Error handling
If the receiver successfully parses the incoming query but:
- The requested method
op
is not supported - Another error condition is met
Send a response with op
equal to 0xffffffff
or another appropriate value using SENDRAWMSG
with mode = 64
.
Value transfer with confirmation
Some operations require both value transfer and confirmation. For example, the validator elections smart contract receives:
- An election participation request
- The stake as the attached value
Implementation
- The sender should attach an additional amount of Toncoin sufficient to cover fees (in addition to the main transfer value, e.g., the stake)
- If an error occurs (e.g., stake not accepted):
- Return the full received amount minus processing and forwarding fees
- Include an error message using
SENDRAWMSG
withmode = 64
- On success:
- Create a confirmation message
- Return exactly one Toncoin (fees paid from balance)
- Use
SENDRAWMSG
withmode = 1