消息概览
TON 是一个异步区块链,其结构与其他区块链非常不同。因此,新开发者经常对 TON 中的低级事物有疑问。在本文中,我们将探讨与消息传递相关的一个问题。
什么是消息?
消息是在actor(用户、应用程序、智能合约)之间发送的数据包。它通常包含指导接收方执行某种操作的信息,如更新存储或发送新消息。
这种通信方式让人想起将卫星发射到太空。我们知道我们构成的消息,但在发射后,需要进行单独的观察来找出我们将获得什么结果。
什么是交易?
TON 中的一笔交易包括以下内容:
- 最初触发合约的传入消息(存在特殊的触发方式)
- 由传入消息引起的合约行动,例如更新合约的存储(可选)
- 发送给其他参与者的所生成的传出消息(可选)
技术上,合约可以通过特殊功能如 Tick-Tock 触发,但这个功能更多用于 TON 内部的区块链核心合约。
并非每笔交易都会导致传出消息或对合约存储的更新——这取决于合约代码所定义的操作。
如果我们看以太坊或几乎任何其他同步区块链,每笔交易可以包含几个智能合约调用。例如,如果选定的交易对没有流动性,DEX可以在一笔交易中执行多次交换。
在异步系统中,您无法在同一笔交易中从目标智能合约获得响应。合约调用可能需要几个区块来处理,具体取决于来源和目的地之间的路由长度。
为了实现无限分片范式,必须确保完全并行化,这意味着每笔交易的执行都独立于其他交易。因此,与其进行影响和改变多个合约状态的交易,不如每笔 TON 交易只在单个智能合约上执行,智能合约通过消息进行通信。这样,智能合约只能通过调用它们的函数与特殊消息相互作用,并稍后通过其他消息获得响应。
在 交易布局 页面上有更详细和准确的描述。
什么是逻辑时间?
在这样一个异步和并行智能合约调用的系统中,定义处理操作顺序可能很难。这就是为什么 TON 中的每个消息都有它的 逻辑时间 或 Lamport time(后面简称 lt)。它用于理解哪个事件引发了另一个以及验证者首先需要处理什么。
严格保证由消息产生的交易将具有大于消息的 lt 的 lt。同样,某笔交易中发送的消息的 lt 严格大于引起它的交易的 lt。此外,从一个账户发送的消息和在一个账户上发生的交易也是严格有序的。
对于图像中的情况,结果是:in_msg_lt < tx0_lt < out_msg_lt
由此,对于每个账户,我们总是知道交易、接收消息和发送消息的顺序。
此外,如果账户 A 向账户 B 发送了两条消息,可以保证具有较低 lt 的消息将被更早处理:
如果 msg1_lt < msg2_lt
=> tx1_lt < tx2_lt
。
否则,尝试同步交付将需要在处理一个分片之前知道所有其他的状态,从而破坏了并行并破坏有效的分片。
对于每个区块,我们可以将 lt 范围定义为从第一笔交易开始,到区块中最后一个事件(消息或交易)的 lt 结束。区块的排序方式与 TON 中的其他事件相同,因此如果一个区块依赖于另一个区块,它具有更高的 lt。一个分片中的子区块的 lt 高于其父区块。一个主链区块的 lt 高于它所列出的分片区块的 lts,因为主区块依赖于所列分片区块。每个分片区块包含对创建分片区块时最新(创建分片区块时)主区块的有序引用,因此分片区块的 lt 高于引用的主区块的 lt。
消息传递
幸运的是,TON 的工作方式是任何内部消息都一定会被目标账户接收。消息不会在来源和目的地之间的任何地方丢失。外部消息有点不同,因为它们被接受到区块中是由验证者自行决定的,但是,一旦消息被接受进入传入消息队列,它将被传递。
传递顺序
因此,看起来 lt 解决了消息传递顺序的问题,因为我们知道具有较低 lt 的交易将首先被处理。但这并不适用于每个场景。
假设有两个合约 - A 和 B。A 收到一个外部消息,触发它向 B 发送两个内部消息,我们称这些消息为 1 和 2。在这个简单的情况下,我们可以 100% 确定 1 将在 2 之前被 B 处理,因为它具有较低的 lt。
但这只是一个简单的案例,当我们只有两个合约时。我们的系统在更复杂的情况下是如何工作的?
多个智能合约
假设我们有三个合约 - A、B 和 C。在一笔交易中,A 发送两个内部消息 1 和 2:一个给 B,另一个给 C。尽管它们是按确切顺序创建的(1,然后是 2),但我们无法确定 1 将在 2 之前被处理。这是因为从 A 到 B 和从 A 到 C 的路由可能在长度和验证者集中有所不同。如果这些合约位于不同的分片链中,其中一条消息可能需要几个区块才能到达目标合约。
为了更清晰,假设我们的合约在 msg1
和 msg2
由 B
和 C
合约执行后发送回消息 msg1'
和 msg2'
。结果将在合约 A
上实现 tx2'
和 tx1'
。我们有两种可能的交易路径,
- 第一种可能的顺序是
tx1'_lt < tx2'_lt
:
- 第二种可能的顺序是
tx2'_lt < tx1'_lt
:
同样,当两个合约 B 和 C 向一个合约 A 发送消息时,情况也是如此。即使 B -> A
的消息在 C -> A
之前发送,我们也无法知道哪一个将先被送达。B -> A
的路由可能需要更多的分片链转运。
在多个智能合约互动的许多可能的场景中,消息传递顺序可能是任意的。唯一的保证是,来自任何合约 A 到任何合约 B 的消息将按照它们的逻辑时间顺序处理。下面是一些示例。
结论
TON 区块链的异步结构为消息传递保证带来挑战。逻辑时间有助于确定事件和交易顺序,但由于分片链中的路由不同,它并不能保证多个智能合约之间的消息传递顺序。尽管存在这些复杂性,TON 仍然能够确保内部消息的传递,维护网络的可靠性。开发人员必须适应这些细微差别,以充分利用 TON 的潜力构建创新的去中心化应用程序。