Рецепты режимов сообщений
Эта страница переведена сообществом на русский язык, но нуждается в улучшениях. Если вы хотите принять участие в переводе свяжитесь с @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_fees | 0,001 | fwd_fee + action_fee + ihr_fee |
gas_fees | 0,0011976 | фаза вычислений, использованный газ |
storage_fees | 0,000000003 | фаза хранения, только аккаунт |
total_action_fees | 0,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, без flag | send_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 = 2 | send_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 = 16 | send_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 = 1 | send_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 = 17 | send_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
контракта.
Please note that SENDRAWMSG
doesn't update balance.
Если вы попытаетесь отправить несколько сообщений (т. е. режим 0 и режим 64), вы получите код выхода 37.


Режим и флаги | Код |
---|---|
mode = 64, без flag | send_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 = 1 | send_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 = 16 | send_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 + 1 | send_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, без flag | send_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 = 16 | send_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 = 32 | send_raw_message(msg, 160) . |