Skip to content

External Messages

External messages are messages that don’t have a sender and can be sent by anyone in the world. External messages are useful tools for integrating with off-chain systems or for general contract maintenance. Handling external messages differs from handling internal messages. In this section, we will cover how to handle external messages.

How External Messages are Different

External messages differ from internal messages in the following ways:

Contracts Pay for Gas Usage Themselves

When processing internal messages, the sender usually pays for gas usage. When processing external messages, the contract pays for gas usage. This means that you need to be careful with gas usage in external messages. You should always test your contracts’ gas usage and verify that everything is working as intended.

Messages Have to Be Accepted Manually

External messages are not accepted automatically. You need to accept them manually. This is done by calling the acceptMessage function. If you don’t call the acceptMessage function, the message will be rejected. This mechanism prevents the spamming of external messages.

10k Gas Limit Before Message Acceptance

The 10k gas amount is a very small limit, and Tact itself can consume a sizable amount of gas before it even reaches your code. You should always test the gas usage of your contracts and verify that everything is working as intended.

Unbounded Gas Usage After Message Acceptance

After accepting a message, the contract can use as much gas as it wants. This is allowed to let the contract carry out any kind of processing. You should always test the gas usage of your contracts, verify everything is working as intended, and avoid possible vulnerabilities that could drain the contract balance.

No Context Available

When processing an external message, the context and sender functions are not available. This is because there is no context available for external messages. Therefore, you cannot use the context and sender functions in external messages. You need to carefully test your contract to ensure that it does not use the context and sender functions.

Enable External Messages Support

To enable external message support, please enable it in the project configuration file:

{
"options": {
"external": true
}
}

External receivers

External receivers are defined in the same way as internal ones, but using the external keyword instead of receive:

contract SampleContract {
external("Check Timeout") {
// Check for contract timeout
require(self.timeout > now(), "Not timed out");
// Accept message
acceptMessage();
// Timeout processing
self.onTimeout();
}
}

External receivers follow the same execution order conventions as internal receivers.