内部消息
概览
智能合约通过发送所谓的内部消息来相互交互。当内部消息到达其预定目的地时,会代表目的地账户创建一个普通交易,并按照该账户(智能合约)的代码和持久数据的所指定的去处理内部消息。
信息
特别地,这个处理交易可以创建一个或多个出站内部消息,其中一些可能被发送到正在处理内部消息的来源地址。这可以用于创建简单的“客户端-服务器应用程序”,当查询被封装在一个内部消息中并发送到另一个智能合约,该智能合约处理查询并再次作为内部消息发送响应。
这种方法导致需要区分内部消息是作为“查询”、“响应”,还是不需要任何额外处理的(如“简单的资金转移”)。此外,当收到响应时,必须有办法理解它对应于哪个查询。
为了实现这一目标,可以使用以下方法进行内部消息布局(注意TON区块链不对消息体施加任何限制,因此这些确实只是建议)。
内部消息结构
消息体可以嵌入到消息本身中,或者存储在消息引用的单独cell中,如TL-B方案片段所示:
message$_ {X:Type} ... body:(Either X ^X) = Message X;
接收智能合约应至少接受嵌入消息体的内部消息(只要它们适合包含消息的 cell)。如果它接受单独cell中的消息体(使用(Either X ^X)
的right
构造函数),那么入站消息的处理不应依赖于消息体的特定嵌入选项。另一方面,对于更简单的查询和响应来说,完全可以不支持单独cell中的消息体。
内部消息体
消息体通常以以下字段开始:
* 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`.