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

Принятие сообщений и их эффекты

warning

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

accept_message и set_gas_limit могут вызывать неочевидные эффекты, когда вы строго следуете указаниям в справочнике stdlib.

Внешние сообщения

Внешние сообщения обрабатываются следующим образом:

  • gas_limit устанавливается на gas_credit (ConfigParam 20 и ConfigParam 21), что равно 10 тыс. газа.
  • Во время расходования этих кредитов контракт должен вызвать accept_message для set_gas_limit, указав, что он готов платить сборы за обработку сообщения.
  • Если gas_credit достигнут или вычисления завершены, а accept_message не вызван, сообщение будет полностью отброшено (как будто его никогда и не было).
  • В противном случае будет установлен новый лимит газа, равный contract_balance/gas_price (в случае accept_message) или пользовательскому числу (в случае set_gas_limit); после завершения транзакции из баланса контракта будут вычтены полные сборы за вычисления (таким образом, gas_credit действительно является кредитом, а не бесплатным газом).

Обратите внимание, что если после accept_message возникнет какая-либо ошибка (либо в ComputePhase, либо в ActionPhase), транзакция будет записана в блокчейн, а сборы будут вычтены из баланса контракта. Однако хранилище не будет обновлено, и действия не будут применены, как в случае любой транзакции с ошибкой кода выхода.

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

Внутреннее сообщение

По умолчанию, когда контракт получает внутреннее сообщение, лимит газа устанавливается на message_balance/gas_price. Другими словами, сообщение оплачивает его обработку. Используя accept_message/set_gas_limit, контракт может изменить лимит газа во время выполнения.

Обратите внимание, что ручные настройки лимитов газа не влияют на поведение отклонения; сообщения будут возвращены, если они отправлены в режиме отклонения и содержат достаточно денег для оплаты их обработки и создания сообщений о отклонении.

пример

Если в том же примере стоимость вычисления составляет 0,5 (вместо 0,005), возврата не будет (баланс сообщения будет 0,1 - 0,5 - 0,001 = -0,401, то есть возврата не будет), а баланс контракта будет 1 + 0,1 - 0,5 = 0,6 TON.