在 Arbitrum 推出 Nitro 之际,我们回顾一下 Arbitrum 的架构。Arbitrum 作为乐观证明的先行者,其架构部分有很多值得学习的地方。
Arbitrum 是一个 EVM 兼容的乐观证明 L2。虽然 EVM 兼容,但是在一些变量上会有所区别。例如我们在 L2 获取 block.number
时,我们得到的是 Arbitrum 上的区块高度,而不是以太坊上的区块高度。
下图是 Arbitrum 的框架图。基本分为 L2 和一系列部署在 L1 上的智能合约。
Arbitrum 部署在 L1 上的桥组件负责 L1 和 L2 的沟通。这个组件包含 4 个智能合约:Inbox,Outbox,Rollup 和 Dispute。在这里可以找到这些合约的代码。
在这篇文章中我们将关注 L1 和 L2 的通讯,也就是 Inbox
和 Outbox
两个合约。
L1 和 L2 的通信由桥组件基于消息传递实现。消息分为两种:L1 消息,L2 消息。L1 上的智能合约可以直接读取 L1 消息。L2 消息给 L2 来读取。我们使用包含 L2 消息编码的 L1 消息来将信息从 L1 传递到 L2。目前一共有六种信息:
ETH_TRANSFER
: 以太坊转账L2_MSG
: L2 上的消息L1MessageType_L2FundedByL1
: 包含 L2 信息编码的 L1 信息,由 L1 支付手续费L1MessageType_submitRetryableTx
: L1 上的 Retryable TicketL2MessageType_unsignedEOATx
: L2 上未签名的用户交易L2MessageType_unsignedContractTx
: L2 上未签名的合约交易L2有两种方法可以将信息从 L1 发送到 L2。第一种是直接调用 Send 相关的函数。用这种方式发送信息延迟较低,并且使用起来比较简单。
第二种方式是创建 Retryable Ticket。接着用户在 L2 兑换这张 Retryable Ticket。这种方式方式的设计初衷是为了弥补第一种方式会因为 Gas 不够而失败。下图展示了三种具体发送信息的方法。
L1 发送到 L2 的消息会被放在 Inbox,例如将以太坊存入 L2。任何人都可以将消息放入 Inbox 中。但是当信息在 L2 被执行时,用户无法得知具体执行结果。