Перейти к содержанию
Learning Platform
Глоссарий Troubleshooting
Урок 06.02 · 25 мин
Средний
JettonTransferMessagesOpcodesTON

Поток перевода Jetton

Поток перевода Jetton — это цепочка из 3-4 сообщений между контрактами, и непонимание этого потока приводит к потере токенов, неправильному отображению балансов и ошибкам интеграции. Подобно банковскому переводу, где деньги проходят через несколько этапов (списание, клиринг, зачисление, уведомление), Jetton-перевод включает burn у отправителя, mint у получателя и уведомление конечного контракта.

В предыдущем уроке мы разобрали архитектуру Jetton 2.0: Jetton Master + отдельный Jetton Wallet для каждого пользователя. Теперь разберём, как именно происходит перевод токенов между двумя пользователями — это цепочка из 4 сообщений, каждое в отдельной транзакции.


Интерактивная диаграмма

Переключайтесь между вкладками, чтобы увидеть архитектуру, поток перевода и минтинг:

Jetton 2.0: шардированная архитектура токенов
Jetton Master
Мастер
Jetton Wallet A
Шардчейн A
Jetton Wallet B
Шардчейн B
Total Supply1,000,000
Balance A600,000
Balance B400,000
Jetton Master
Jetton Wallet A
deploys / manages
Jetton Master
Jetton Wallet B
deploys / manages
Каждый пользователь имеет свой отдельный Jetton Wallet контракт, развёрнутый в его шардчейне. В отличие от ERC-20, балансы не хранятся в одном контракте.

4 шага перевода Jetton

Когда User A хочет перевести токены User B, происходит следующая цепочка сообщений:

User A              Jetton Wallet A       Jetton Wallet B       User B
  |                       |                     |                  |
  |-- 1. transfer ------->|                     |                  |
  |   (0xf8a7ea5)         |                     |                  |
  |                       |-- 2. internal_ ---->|                  |
  |                       |   transfer          |                  |
  |                       |                     |-- 3. transfer -->|
  |                       |                     |   _notification  |
  |                       |                     |   (0x7362d09c)   |
  |<----------- 4. excesses (0xd53276db) -------|                  |
  |                       |                     |                  |

Рассмотрим каждый шаг подробно.


Шаг 1: transfer (0xf8a7ea5)

User A отправляет сообщение в свой Jetton Wallet A (не напрямую получателю!):

ПолеОписание
destinationАдрес TON-кошелька User B
amountКоличество токенов для перевода
response_destinationКуда вернуть неиспользованный TON (обычно = User A)
forward_ton_amountСколько TON переслать User B вместе с уведомлением
forward_payloadПроизвольные данные для User B (например, комментарий к платежу)

Jetton Wallet A уменьшает свой баланс на amount и формирует следующее сообщение.

WARNING

User A отправляет transfer в свой Jetton Wallet, а не в Jetton Wallet получателя. Это ключевое отличие от ERC-20, где transfer(to, amount) вызывается на контракте токена. В TON каждый пользователь взаимодействует только со своим Jetton Wallet.


Шаг 2: internal_transfer

Jetton Wallet A отправляет internal_transfer в Jetton Wallet B:

ПолеОписание
amountКоличество переводимых токенов
fromАдрес TON-кошелька User A (отправитель)
response_destinationКуда вернуть excesses
forward_ton_amountСколько TON переслать получателю
forward_payloadДанные для получателя

Jetton Wallet B увеличивает свой баланс на amount. Если Jetton Wallet B не существовал ранее, он будет развёрнут автоматически — именно поэтому отправитель должен приложить достаточно TON для покрытия газа деплоя.


Шаг 3: transfer_notification (0x7362d09c)

Jetton Wallet B отправляет уведомление User B (получателю):

ПолеОписание
query_idИдентификатор запроса (для отслеживания)
amountКоличество полученных токенов
senderАдрес отправителя (User A)
forward_payloadДанные от отправителя

Это уведомление опционально — оно отправляется только если forward_ton_amount > 0. Смарт-контракты используют transfer_notification для реагирования на входящие токены (например, DEX обрабатывает swap при получении Jetton).


Шаг 4: excesses (0xd53276db)

Jetton Wallet B возвращает неиспользованный TON на response_destination (обычно User A):

Отправитель (User A) должен приложить достаточно TON для оплаты всей цепочки из 4 транзакций. Excesses-сообщение гарантирует, что лишние средства вернутся.

TIP

Всегда указывайте response_destination = адрес отправителя. Если не указать, неиспользованный TON останется на Jetton Wallet B и будет потерян. Для gas recovery это критично — цепочка из 4 транзакций может стоить 0.05-0.15 TON в зависимости от нагрузки сети.


Газ и forward_ton_amount

Правильная оценка газа — ключевой аспект Jetton-переводов:

Прикреплённые TON User A должны покрыть
├── Газ транзакции 1 (transfer)~0.01 TON
├── Газ транзакции 2 (internal_transfer)~0.01 TON
├── Газ транзакции 3 (transfer_notification)~0.01 TON
├── Газ транзакции 4 (excesses)~0.005 TON
├── forward_ton_amount (для User B)по запросу
└── Деплой Jetton Wallet B (если новый)~0.05 TON

Если User A приложит недостаточно TON, одна из транзакций в цепочке не будет выполнена из-за нехватки газа.


Bounce-обработка

Что происходит, если транзакция в цепочке не может быть выполнена?

Сценарий: Jetton Wallet B не может принять internal_transfer

Если internal_transfer bounced (отскочил), Jetton Wallet A получает bounce-сообщение и восстанавливает свой баланс. Токены не теряются — они возвращаются отправителю.

Это важнейший механизм безопасности Jetton 2.0:

  1. Jetton Wallet A уменьшил баланс и отправил internal_transfer
  2. Jetton Wallet B не смог обработать (ошибка, нехватка газа)
  3. TON отправляет bounce-сообщение обратно в Jetton Wallet A
  4. Jetton Wallet A обрабатывает bounce и прибавляет токены обратно
NOTE

Bounce-обработка в Jetton — это реализация паттерна, который мы разбирали в M03, урок 05 (Messages и Bouncing). Каждый Jetton Wallet обязан обрабатывать bounced internal_transfer, восстанавливая баланс отправителя.


Opcodes: справочник

OpcodeHexСообщениеНаправление
transfer0xf8a7ea5Инициация переводаUser -> свой Jetton Wallet
internal_transfer-Межкошельковый переводJetton Wallet A -> Jetton Wallet B
transfer_notification0x7362d09cУведомление получателяJetton Wallet B -> User B
excesses0xd53276dbВозврат газаJetton Wallet B -> response_destination
burn0x595f07bcСжигание токеновUser -> свой Jetton Wallet
burn_notification0x7bdd97deУведомление о сжиганииJetton Wallet -> Jetton Master

Практическое значение

Понимание потока перевода Jetton необходимо для:

  • Разработки DEX: DEX-контракт реагирует на transfer_notification для обработки swap-запросов
  • Оценки газа: правильный расчёт прикреплённых TON для всей цепочки
  • Отладки: отслеживание 4 транзакций в эксплорере при проблемах с переводом
  • Безопасности: корректная обработка bounce-сообщений предотвращает потерю токенов

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

  1. Не отправляют forward_ton_amount при переводе, из-за чего получатель не получит уведомление (transfer_notification) и не узнает о входящем переводе.
  2. Путают transfer и internal_transfer: transfer инициируется владельцем кошелька, а internal_transfer — это внутреннее сообщение между Jetton Wallet контрактами.
  3. Не обрабатывают excesses: после успешного перевода неизрасходованные TON отправляются на response_destination; если он не указан, TON теряются.
  4. Считают перевод завершённым после отправки transfer, хотя на самом деле нужно дождаться подтверждения всей цепочки сообщений.

Проверка знанийKnowledge check
Почему User A отправляет transfer в свой Jetton Wallet, а не напрямую получателю?
ОтветAnswer
Потому что баланс User A хранится в его Jetton Wallet контракте. Только этот контракт может уменьшить баланс и инициировать internal_transfer в Jetton Wallet получателя. User A не имеет прямого доступа к контракту получателя -- это фундаментальное свойство шардированной архитектуры TON.

Закончили урок?

Отметьте его как пройденный, чтобы отслеживать свой прогресс

Войдите чтобы оценить урок

Прогресс модуля
0 из 6