Внутренние и внешние сообщения

Internal и external messages в TON: кто кого вызывает, как устроена асинхронная модель и чем сообщение отличается от «транзакции EVM».

Сообщения — единица взаимодействия

В TON аккаунты общаются сообщениями, а не синхронными вызовами функций в одной атомарной цепочке (как привычный call в EVM). Есть два типа:

  • External — приходит извне сети (обычно от кошелька пользователя)
  • Internal — идёт от аккаунта к аккаунту внутри сети

Транзакция на аккаунте — это обработка одного входящего сообщения (плюс порождение исходящих).


External vs internal

External inInternal
ИсточникВне сети (подписанный запрос кошелька)Другой аккаунт / контракт
Value (Gram)Не несёт value само по себе как перевод «из воздуха»Может нести Gram + тело
Типичный путьПользователь → кошелёк-контрактКошелёк → dApp / jetton / NFT

Пользователь почти никогда не шлёт external напрямую в произвольный dApp-контракт. Стандартный путь:

  1. Кошелёк принимает external (с подписью).
  2. Кошелёк отправляет internal сообщения в целевые контракты.
tact (fallback highlight)
// Tact 1.6+
contract Echo {
    // internal message от другого контракта/кошелька
    receive(msg: String) {
        // обработка тела сообщения
    }

    // empty internal — часто для простых сигналов
    receive() {
        // noop / accept funds
    }
}

Как это работает

  1. Узел принимает external → проверяет и создаёт транзакцию на аккаунте-получателе.
  2. Контракт может эмитировать одно или несколько исходящих internal-сообщений.
  3. Каждое исходящее позже обработается отдельной транзакцией на получателе.
  4. Очерёдность задаётся логическим временем (lt) и маршрутизацией шардов.

Это асинхронная модель: «вызвал контракт B» означает «отправил сообщение», а не «дождался return value в той же транзакции». Ответ — отдельным сообщением назад, если ты так спроектировал протокол.


Частые ошибки

Ждать синхронный return как в Solidity call → проектируй request/response сообщениями и храни pending-состояние.

Считать, что external можно слать в любой контракт «как eth_sendRawTransaction на любой адрес» → большинство контрактов принимают value/логику через internal от доверенных отправителей; точка входа пользователя — кошелёк.

Игнорировать bounce → failed internal с bounceable-флагом вернёт value отправителю; обработай bounce-ветку, если это важно для учёта средств.


Что дальше

Материалы gramdocs.tech носят образовательный характер и не являются финансовой, юридической или инвестиционной рекомендацией. Работа с блокчейном TON и токеном Gram связана с рисками потери средств. Правовая информация