Найти тему

Gas Management

📚Lecture Notes

  • В виртуальной машине Ethereum, если пользователь предоставляет слишком мало газа, все будет возвращено.
  • Если они предоставят достаточно, фактические расходы будут автоматически рассчитаны и вычтены из их баланса.

В Solidity газ не вызывает особого беспокойства для контрактных разработчиков. Если пользователь предоставляет слишком мало газа, все будет возвращено, как будто ничего не произошло (но газ не будет возвращен). Если они предоставят достаточно, фактические расходы будут автоматически рассчитаны и вычтены из их баланса.

В TON ситуация другая:

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

Если "группа контрактов" обменивается сообщениями, то контроль и расчет должны осуществляться в каждом сообщении. TON не может автоматически рассчитать газ. Полное выполнение транзакции со всеми ее последствиями может занять много времени, и к концу у пользователя может не быть достаточно тонкоинов в кошельке. Здесь используется принцип переносимой стоимости.

Calculate Gas and Check msg_value

Мы можем использовать нашу блок-схему сообщений для оценки стоимости каждого обработчика в каждом из сценариев и вставить проверку достаточности msg_value.

  • Найдите "точки входа" в потоке сообщений.
  • Оцените стоимость каждого обработчика.
  • Проверьте "точки входа", что msg_value достаточно.
  • Вы не можете требовать достаточно с маржой везде (скажем, 1 TON). Газ делится между "следствиями".

Допустим, ваш контракт отправляет три сообщения, тогда вы можете отправить только 0,33 ton каждому. Это означает, что они должны "требовать" меньше. Важно тщательно рассчитать потребности в газе для всего вашего контракта.

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

Return Gas Excesses Carefully

  • Если избыточный газ не будет возвращен отправителю, средства будут накапливаться в ваших контрактах с течением времени.
  • Ничего страшного, но неоптимального. Вы можете добавить функцию для выгребания излишеств.
  • Популярные контракты, такие как TON Jetton, возвращаются отправителю с сообщением op::excesses.

Если избыточный газ не будет возвращен отправителю, средства будут накапливаться в ваших контрактах с течением времени. В принципе, ничего страшного, это просто неоптимальная практика. Вы можете добавить функцию для сгребания эксцессов, но популярные контракты, такие как TON Jetton, все равно возвращаются отправителю с сообщением op::excesses.

send_raw_message(msg, SEND_MODE_CARRY_ALL_REMAINING_MESSAGE_VALUE) pass the rest of gas.
  • Useful if message flow is linear: each handler sends only one message.

TON has a useful mechanism: SEND_MODE_CARRY_ALL_REMAINING_MESSAGE_VALUE = 64.

При использовании этого режима в send_raw_message() остальная часть газа будет перенаправлена дальше вместе с сообщением (или обратно) новому получателю. Удобно, если поток сообщений линейный: каждый обработчик сообщений отправляет только одно сообщение. Но бывают случаи, когда не рекомендуется использовать этот механизм:

storage_fee
is deducted from the balance of the contract, not from the incoming gas.

Storage_fee вычитается из баланса контракта, а не из входящего газа. Так что если в вашем контракте нет других нелинейных обработчиков, то со временем storage_fee может съесть весь баланс, потому что все, что приходит, должно выйти.

  • Emitting event eats contract balance, not gas.

If your contract emits events, i.e. sends a message to an external address. The cost of this action is deducted from the balance of the contract, and not from msg_value.

  • Attaching value to the message or using SEND_MODE_PAY_FEES_SEPARETELY eats contract balance.
var msg = begin_cell().store_uint(0x18, 6).store_slice(destination)
.store_coins(10000000) ;; This will be deducted from contract balance
.store_uint(1, 1 + 4 + 4 + 64 + 32 + 1 + 1).store_ref(msg_body);
send_raw_message(msg.end_cell(), 0);

emit_log_cell_ref(query_id, ... ;; This also spends contract balance

Если ваш контракт прилагает значение при отправке сообщений или использует SEND_MODE_PAY_FEES_SEPARETELY = 1. Эти действия вычитаются из остатка контракта, что означает, что возврат неиспользованного означает "работа в убыток".

Common way to calculate gas cost

Вот фрагмент кода из TON Wallet. Это распространенный способ сохранить стабильный баланс контракта.

-2

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

Resume

  • TON требует от разработчиков преднамеренных усилий для управления газом: рассчитайте расходы и проверьте, достаточно ли предусмотрено.
  • Стоимость газа может возрасти с течением времени, если использовать "неограниченную структуру данных".
  • TON рекомендует вернуть эксцессы отправителю - это также на разработчике.
  • Если закончится газ, транзакция будет частично выполнена. Это может быть критической проблемой.
BitStake NEWS