Перейти к основному содержимому

Рецепты режимов сообщений

warning

Эта страница переведена сообществом на русский язык, но нуждается в улучшениях. Если вы хотите принять участие в переводе свяжитесь с @alexgton.

Понимание различных режимов и флагов, доступных для отправки сообщений, имеет решающее значение для обеспечения того, чтобы ваши смарт-контракты вели себя так, как задумано. Хотя в разделе режимы сообщений были предоставлены подробные описания этих режимов и флагов, в этом разделе мы проиллюстрируем их практическое применение на конкретных примерах.

ВАЖНО

Вы можете проверить этот пример в качестве реальной проверки.

Значение сообщения и баланс аккаунта

Пожалуйста, проверьте, как работает get_balance, чтобы лучше понять состояние транзакции.

Существует два способа оплаты действий в блокчейне:

Обычно она взимается с balance контракта, но в определенных случаях будет использоваться часть value сообщения.

Комиссии

Фактические комиссии за транзакции будут варьироваться в зависимости от конфигурации блокчейна, кода смарт-контракта и других факторов. При получении сообщения часть balance контракта будет израсходована на storage fee и gas_fees, если value сообщения выше определенной суммы.

Согласно потоку транзакций существует 5 фаз:

  • Хранилище, состоящее из хранилища аккаунта и импорта in_msg
  • Кредит, где in_msg value добавляется к balance
  • Вычисление, при котором фактический код смарт-контракта выполняется в TVM
  • Действие, где выполняются действия, такие как SENDRAWMSG
  • Отскок, где обрабатывается все, что связано с отскоком

Порядок: storage_fee -> import_fee -> gas_fee -> action_fee + fwd_fee

ВАЖНО

Таблица заполнена из этого примера. Вы можете проверить калькулятор.

Комиссия в проводникеЗначениеКак она получена
Общая комиссия0,001982134газ + хранение + действие + импорт
total_fwd_fees0,001fwd_fee + action_fee + ihr_fee
gas_fees0,0011976фаза вычислений, использованный газ
storage_fees0,000000003фаза хранения, только аккаунт
total_action_fees0,000133331фаза действий, стоимость за действие
import_fee (скрыто)0,0006512стоимость импорта ext_msg
fwd_fee (каждое сообщение)0,000266669стоимость fwd in_msg
ihr_fee (каждое сообщение)0.0006стоимость ihr fwd in_msg
к сведению

Комиссии транзакций, используемые в этих примерах, являются гипотетическими и используются исключительно для иллюстрации, любые сборы, кроме сборов за пересылку сообщений, выходят за рамки данной статьи.

1. Отправить обычное сообщение

Состояние до транзакции: аккаунт A имеет 1 TON, аккаунт B имеет 1 TON

A отправил 0,1 TON B, msg_fwd_fees составляют 0,004 TON, фактическое полученное значение составит 0,096 TON, fwd_fee и action_fee вычтены из value.

Состояние после транзакции: аккаунт A имеет 0,9 TON, аккаунт B имеет 1,096 TON



Режим и флагиКод
mode = 0, без flagsend_raw_message(msg, 0)

2. Отправить обычное сообщение, не отклонять сообщение об ошибке и игнорировать его

Состояние до транзакции: аккаунт A имеет 1 TON, аккаунт B имеет 1 TON

A отправил 0,1 TON на B, msg_fwd_fees составляет 0,004 TON, фактическое полученное значение составит 0,096 TON, fwd_fee и action_fee вычитаются из value. В случае ошибки во время обработки транзакции сообщение не будет возвращено и будет проигнорировано.

Состояние после транзакции: аккаунт A имеет 0,9 TON, аккаунт B имеет 1,096 TON

подсказка

Средства, включенные в проигнорированное сообщение, все равно будут зачислены на адрес получателя. Если ошибок нет, результат такой же, как и mode = 0.



Режим и флагиКод
mode = 0, flag = 2send_raw_message(msg, 2)

3. Отправить обычное сообщение и отклонить сообщение об ошибке действия

Состояние до транзакции: аккаунт A имеет 1 TON, аккаунт B имеет 1 TON

A отправил 0,1 TON на B, msg_fwd_fees составляет 0,004 TON, фактическое полученное значение составит 0,096 TON, fwd_fee и action_fee вычтены из value. В случае ошибки на фазе действия сообщение будет отклонено, а total_fee + fwd_fee будут вычтены из value.

Состояние после транзакции с ошибкой: у аккаунта A 1 - (total_fee + fwd_fee) TON, у аккаунта B 1 TON



подсказка

Если ошибок нет, результат такой же, как у mode = 0.



Режим и флагиКод
mode = 0, flag = 16send_raw_message(msg, 16)

4. Отправить обычное сообщение с разделением комиссий

Состояние до транзакции: аккаунт A имеет 1 TON, аккаунт B имеет 1 TON

A отправил 0,1 TON на B, msg_fwd_fees составляет 0,004 TON, фактическое полученное значение составит 0,1 TON, fwd_fee и action_fee вычтены из balance.

Состояние после транзакции: аккаунт A имеет 0,896 TON, аккаунт B имеет 1,1 TON



Режим и флагиКод
mode = 0, flag = 1send_raw_message(msg, 1)

5. Отправить обычное сообщение с разделением комиссий и отклонить сообщение об ошибке

Состояние до транзакции: аккаунт A имеет 1 TON, аккаунт B имеет 1 TON

A отправил 0,1 TON на B, msg_fwd_fees составляет 0,004 TON, фактическое полученное значение составит 0,1 TON, fwd_fee и action_fee вычтены из balance. В случае ошибки во время фазы действия сообщение будет отклонено, и total_fee + fwd_fee будут вычтены из value.

Состояние после транзакции с ошибкой: у аккаунта A 1 - (total_fee + fwd_fee) TON, у аккаунта B 1 TON



подсказка

Если ошибок нет, результат такой же, как у mode = 1.



Режим и флагиКод
mode = 0, flag = 1 + 16 = 17send_raw_message(msg, 17)

6. Перенести оставшееся значение с новым сообщением

Состояние до транзакции: аккаунт A имеет 1 TON, аккаунт B имеет 1 TON, аккаунт C имеет 1 TON

A отправил 0,1 TON B, после чего B отправил 0,5 TON C с mode = 64, msg_fwd_fees составляет 0,004 TON, фактическое полученное value составит 0,6 TON, total_fee + fwd_fee вычтено из value.

Состояние после транзакции: аккаунт A имеет 0,896 TON, аккаунт B имеет 0,5 TON, аккаунт C имеет 1,6 - (total_fee + fwd_fee) TON

к сведению

Вы можете проверить этот пример. Обратите внимание, что storage_fee включен в total_fee, но всегда оплачивается из balance контракта.

warning

Please note that SENDRAWMSG doesn't update balance.

Если вы попытаетесь отправить несколько сообщений (т. е. режим 0 и режим 64), вы получите код выхода 37.



Режим и флагиКод
mode = 64, без flagsend_raw_message(msg, 64)

7. Перенести оставшееся значение в новое сообщение с разделением комиссий

Состояние до транзакции: аккаунт A имеет 1 TON, аккаунт B имеет 1 TON, аккаунт C имеет 1 TON

A отправил 0,1 TON на B, после чего B отправил 0,5 TON на C с mode = 65, msg_fwd_fees составляет 0,004 TON, фактическое полученное значение составит 0,6 TON, total_fee + fwd_fee вычтено из balance.

Состояние после транзакции: аккаунт A имеет 0,896 TON, аккаунт B имеет 0,5 - (total_fee + fwd_fee) TON, аккаунт C имеет 1,6 TON

к сведению

Вы можете проверить этот пример. Обратите внимание, что storage_fee включен в total_fee, но он всегда оплачивается из balance контракта.



Режим и флагиКод
mode = 64, flag = 1send_raw_message(msg, 65)

8. Перенести оставшееся значение и отклонить сообщение об ошибке

Состояние до транзакции: аккаунт A имеет 1 TON, аккаунт B имеет 1 TON, аккаунт C имеет 1 TON

A отправил 0,1 TON в B, после чего B отправил 0,5 TON в C с mode = 80, msg_fwd_fees составляет 0,004 TON, фактическое полученное значение составит 0,6 TON, total_fee + fwd_fee вычтено из value. В случае ошибки во время фазы действия сообщение будет отклонено, и total_fee + fwd_fee вычтено из value.

Состояние после транзакции с ошибкой: аккаунт A имеет 1 - (total_fee + fwd_fee) TON, аккаунт B имеет 1 TON, аккаунт C имеет 1 TON



подсказка

Если ошибок нет, результат такой же, как mode = 64. Этот режим на самом деле часто используется в TON для переводов жетонов, вы можете проверить его в списке действий C5 кошелька жетона.



Режим и флагиКод
mode = 64, flag = 16send_raw_message(msg, 80)

9. Перенести оставшееся значение в новое сообщение с разделением комиссий и отклонить сообщение об ошибке

Состояние до транзакции: аккаунт A имеет 1 TON, аккаунт B имеет 1 TON, аккаунт C имеет 1 TON

A отправил 0,1 TON в B, после чего B отправил 0,5 TON в C с mode = 80, msg_fwd_fees составляет 0,004 TON, фактическое полученное значение составит 0,6 TON, total_fee + fwd_fee вычтено из value. В случае ошибки во время фазы действия сообщение будет отклонено, и total_fee + fwd_fee вычтено из value.

Состояние после транзакции с ошибкой: аккаунт A имеет 1 - (total_fee + fwd_fee) TON, аккаунт B имеет 1 TON, аккаунт C имеет 1 TON



подсказка

Если ошибок нет, результат такой же, как у mode = 65.



Режим и флагиКод
mode = 64, flag = 16 + 1send_raw_message(msg, 81).

10. Отправить все полученные токены вместе с балансом контракта

Состояние до транзакции: аккаунт A имеет 1 TON, аккаунт B имеет 1 TON, аккаунт C имеет 1 TON

A отправил 0,1 TON на B, после чего B отправил 0,5 TON на C с mode = 128, msg_fwd_fees составляет 0,004 TON, фактическое полученное значение будет 1,1 - total_fee TON, total_fee вычтено из value.

Состояние после транзакции: аккаунт A имеет 0,896 TON, аккаунт B имеет 0 TON, аккаунт C имеет 2,1 - (total_fee + fwd_fee) TON



Режим и флагиКод
mode = 128, без flagsend_raw_message(msg, 128).

11. Отправить все полученные токены вместе с балансом контракта и отклонить сообщение об ошибке

Состояние до транзакции: аккаунт A имеет 1 TON, аккаунт B имеет 1 TON, аккаунт C имеет 1 TON

A отправил 0,1 TON на B, после чего B отправил 0,5 TON на C с mode = 144, msg_fwd_fees составляет 0,004 TON, фактическое полученное значение будет 1,1 - total_fee TON, total_fee вычтено из value.

Состояние после транзакции с ошибкой: аккаунт A имеет 1 - (total_fee + fwd_fee) TON, аккаунт B имеет 1 TON, аккаунт C имеет 1 TON



подсказка

Если ошибок нет, результат такой же, как mode = 128. Этот режим на самом деле часто используется в TON для переводов жетонов, вы можете проверить его в списке действий C5 кошелька жетона.



Режим и флагиКод
mode = 128, flag = 16send_raw_message(msg, 144)

12. Отправить все полученные токены вместе с балансом контракта и уничтожить смарт-контракт

Состояние до транзакции: аккаунт A имеет 1 TON, аккаунт B имеет 1 TON, аккаунт C имеет 1 TON

A отправил 0,1 TON на B, после чего B отправил 0,5 TON на C с mode = 160, msg_fwd_fees составляет 0,004 TON, фактическое полученное значение составит 1,1 - total_fee TON, total_fee вычтено из value.

Состояние после транзакции: аккаунт A имеет 0,896 TON, аккаунт B имеет 0 TON и nonexist, аккаунт C имеет 2,1 - (total_fee + fwd_fee) TON

Когда баланс достигнет 0 TON, уничтожить контракт.



Режим и флагиКод
mode = 128, flag = 32send_raw_message(msg, 160).