К основному содержанию
T TON Adoption
← Словарь
NODE/03 · Term

Bounce / non-bounce сообщение

Флаг в сообщении TON, определяющий поведение при ошибке. Bounceable возвращает TON отправителю, если получатель не принял; non-bounceable отправляет безвозвратно.

Синонимы: bounceable, non-bounceable, баунс сообщение, отскок

Bounce-флаг — это бит в заголовке сообщения TON, определяющий, что произойдёт, если получающий контракт по какой-то причине не смог обработать сообщение. Это критически важная особенность TON, не имеющая прямого аналога в Ethereum.

Два режима

  • Bounceable (bounce = true). Если получающий контракт упал с ошибкой или его не существует, сообщение возвращается отправителю — TON-сумма приходит обратно (минус потраченный газ). Это режим по умолчанию для сообщений между смарт-контрактами.
  • Non-bounceable (bounce = false). Сообщение уходит «безвозвратно». Если получатель не принял — TON остаются на его адресе (даже если контракт там не развёрнут). Используется для развёртывания новых контрактов и для отправки на свежие, ещё не активные адреса.

Зачем это нужно

В Ethereum любой transfer — синхронный: либо прошёл, либо ревертнул всю транзакцию. В TON всё асинхронно — отправитель не знает, дойдёт ли сообщение до получателя в следующем блоке. Bounce-механизм решает эту проблему:

  • Если jetton wallet получателя сломан — TON и jetton-ы вернутся обратно, не потеряются.
  • Если контракт случайно отправил на несуществующий адрес — деньги не уйдут в пустоту.
  • Если контракт упал из-за ошибки в коде — отправитель получит уведомление и сможет повторить.

В адресе тоже есть bounce-флаг

Сам адрес TON в base64-форме содержит этот флаг:

  • EQ... — bounceable. Кошельки и большинство контрактов используют этот вариант. Если адрес контракт «не понял» — деньги вернутся.
  • UQ... — non-bounceable. Используется для отправки на новые адреса, на которых ещё нет развёрнутого контракта.

Когда вы копируете адрес с биржи или из кошелька, формат подбирается автоматически. Но при ручной отправке стоит проверять: если адрес ещё не активирован (no contract on chain), отправка в bounceable-режиме приведёт к возврату средств с потерей газа.

Практический пример

Сценарий: вы только что создали кошелёк, поделились адресом, и кто-то отправляет вам 100 TON.

  • Если адрес был передан в bounceable-форме (EQ...), а ваш кошелёк ещё не развёрнут — TON уйдут отправителю обратно с минусом ~0,01 TON газа. Раздражает.
  • Если адрес в non-bounceable-форме (UQ...) — TON останутся на адресе, и вы их получите при первом своём действии, развернув кошелёк через первое исходящее сообщение.

Поэтому новые кошельки рекомендуют делиться адресом в UQ-форме, пока не сделана первая исходящая транзакция.

Технически

Bounce-сообщения автоматически формируются TVM при ошибке исполнения. У такого сообщения есть стандартный префикс — первые 32 бита payload равны 0xFFFFFFFF. Получатель (изначальный отправитель) может проверить этот префикс в своём коде и обработать ошибку: записать в логи, попробовать снова, уведомить пользователя.

В стандартном wallet-контракте bounce-сообщения тихо принимаются и отображаются в истории как «возврат». В кастомных контрактах разработчику нужно явно прописать обработку bounce, иначе ошибки будут теряться.

См. также