Комиссии за пересылку
Эта страница переведена сообществом на русский язык, но нуждается в улучшениях. Если вы хотите принять участие в переводе свяжитесь с @alexgton.
В общем случае, если смарт-контракт хочет отправить запрос другому смарт-контракту, он должен заплатить за от правку внутреннего сообщения в смарт-контракт назначения (плата за пересылку сообщений), обработку этого сообщения в пункте назначения (плата за газ) и отправку ответа обратно, если требуется (плата за пересылку сообщений).
В большинстве случаев отправитель прикрепляет небольшое количество Toncoin (например, один Toncoin) к внутреннему сообщению (достаточное для оплаты обработки этого сообщения) и устанавливает его флаг "возврата" (т. е. отправляет внутреннее сообщение, допускающее возврат); получатель возвращает неиспользованную часть полученного значения с ответом (вычитая из него плату за пересылку сообщений). Обычно это достигается путем вызова SENDRAWMSG
с mode = 64
(см. Приложение A документации TON VM).
Если получатель не может проанализировать полученное сообщение и завершает работу с ненулевым кодом завершения (например, из-за исключения десериализации необработанной ячейки), сообщение будет автоматически "возвращено" обратно отправителю, при этом флаг "отклонено" будет снят, а флаг "возвращено" установлен. Тело возвращенного сообщения будет содержать 32-битное значение 0xffffffffff
, за которым последует 256-битное значение исходного сообщения. Важно проверить флаг "возвращенного" входящих внутренних сообщений перед разбором поля op
в смарт-контракте и обработкой соответствующего запроса (в противном случае существует риск того, что запрос, содержащийся в возвращенном сообщении, будет обработан его первоначальным отправителем как новый отдельный запрос). Если установлен флаг "отклонено", специальный код может определить, какой запрос завершился ошибкой (например, путем десериализации op
и query_id
из возвращенного сообщения) и предпринять соответствующие действия. Более простой смарт-контракт мог бы просто игнорировать все возвращенные сообщения (завершаться с нулевым кодом завершения, если установлен флаг "возвращено"). Обратите внимание, что флаг "отклонено" переписывается во время отправки, поэтому его невозможно подделать, и можно с уверенностью предположить, что если сообщение пришло с флагом "отклонено", то это результат отклонения какого-либо сообщения, отправленного получателем.
С другой стороны, получатель может успешно проанализировать входящий запрос и обнаружить, что запрошенный метод op
не поддерживается или что выполнено другое условие ошибки. Затем следует отправить ответ с op
, равным 0xffffffff
или другим подходящим значением, используя SENDRAWMSG
с mode = 64
, как указано выше.
В некоторых ситуациях отправитель хочет как передать отправителю некоторое значение, так и получить либо подтверждение, либо сообщение об ошибке. Например, смарт-контракт валидатора выборов получает запрос на участие в выборах вместе со ставкой в качестве прикрепленного значения. В таких случаях имеет смысл прикрепить, скажем, один дополнительный Toncoin к предполагаемому значению. Если произошла ошибка (например, ставка не может быть принята по какой-либо причине), вся полученная сумма (за вычетом комиссии за обработку) должна быть возвращена отправителю вместе с сообщением об ошибке (например, с помощью SENDRAWMSG
с mode = 64
, как объяснялось ранее). В случае успеха создается сообщение с подтверждением и обратно отправляется ровно один Toncoin (с комиссией за передачу сообщения, вычитаемой из этого значения; это mode = 1
для SENDRAWMSG
).