Внутренние сообщения
Эта страница переведена сообществом на русский язык, но нуждается в улучшениях. Если вы хотите принять участие в переводе свяжитесь с @alexgton.
Общие сведения
Смарт-контракты взаимодействуют друг с другом, отправляя так называемые внутренние сообщения. Когда внутреннее сообщение достигает своего адресата, создается обычная транзакция от имени акккаунта получателя, а внутреннее сообщение обрабатывается в соответствии с кодом и постоянными данными этого аккаунта (смарт-контракт).
В частности, транзакция обработки может создавать одно или несколько исходящих внутренних сообщений, некоторые из которых могут быть адресованы исходному адресу обрабатываемого внутреннего сообщения. Это можно использовать для создания простых "клиент-серверных приложений", когда запрос инкапсулируется во внутреннее сообщение и отправляется другому смарт-контракту, который обрабатывает запрос и снова отправляет ответ в качестве внутреннего сообщения.
Этот подход приводит к необходимости различать, предназначено ли внутреннее сообщение как "запрос", "ответ" или не требует никакой дополнительной обработки (например, "простой денежный перевод"). Кроме того, при получении ответа должен быть способ определить, какому запросу он соответствует.
Для достижения этой цели можно использовать следующие подходы к внутреннему макету сообщения (обратите внимание, что блокчейн TON не накладывает никаких ограничений на тело сообщения, поэтому это всего лишь рекомендации).
Внутренняя структура сообщения
Тело сообщения может быть встроено в само сообщение или сохранено в отдельной ячейке, на которую ссылается сообщение, как указано во фрагменте схемы TL-B:
message$_ {X:Type} ... body:(Either X ^X) = Message X;
Принимающий смарт-контракт должен принимать как минимум внутренние сообщения со встроенными телами сообщений (всякий раз, когда они помещаются в ячейку, содержащую сообщение). Если он принимает тела сообщений в отдельных ячейках (используя конструктор right
из (Either X ^X)
), обработка входящего сообщения не должна зависеть от конкретного варианта встраивания, выбранного для тела сообщения. С другой стороны, совершенно допустимо не поддерживать тела сообщений в отдельных ячейках для более простых запросов и ответов.
Внутреннее тело сообщения
Тело сообщения обычно начинается со следующих полей:
* A 32-bit (big-endian) unsigned integer `op`, identifying the `operation` to be performed, or the `method` of the smart contract to be invoked.
* A 64-bit (big-endian) unsigned integer `query_id`, used in all query-response internal messages to indicate that a response is related to a query (the `query_id` of a response must be equal to the `query_id` of the corresponding query). If `op` is not a query-response method (e.g., it invokes a method that is not expected to send an answer), then `query_id` may be omitted.
* The remainder of the message body is specific for each supported value of `op`.