# Arbitrum Architecture: Inbox

By [Inevitable](https://paragraph.com/@inevitable) · 2024-09-08

tech

---

在 Arbitrum 推出 Nitro 之际，我们回顾一下 Arbitrum 的架构。Arbitrum 作为乐观证明的先行者，其架构部分有很多值得学习的地方。

Arbitrum 是一个 EVM 兼容的乐观证明 L2。虽然 EVM 兼容，但是在一些变量上会有所区别。例如我们在 L2 获取 `block.number` 时，我们得到的是 Arbitrum 上的区块高度，而不是以太坊上的区块高度。

下图是 Arbitrum 的框架图。基本分为 L2 和一系列部署在 L1 上的智能合约。

![](https://storage.googleapis.com/papyrus_images/9bb8bfe51c8aca3603c375cb0950283b.png)

Arbitrum 部署在 L1 上的桥组件负责 L1 和 L2 的沟通。这个组件包含 4 个智能合约：Inbox，Outbox，Rollup 和 Dispute。在[这里](https://github.com/OffchainLabs/arbitrum/tree/afa60b9ab2f8645fb292251d74f2adb42ecde047)可以找到这些合约的代码。

在这篇文章中我们将关注 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 Ticket
    
*   `L2MessageType_unsignedEOATx`: L2 上未签名的用户交易
    
*   `L2MessageType_unsignedContractTx` : L2 上未签名的合约交易L2
    

Inbox
-----

有两种方法可以将信息从 L1 发送到 L2。第一种是直接调用 Send 相关的函数。用这种方式发送信息延迟较低，并且使用起来比较简单。

第二种方式是创建 Retryable Ticket。接着用户在 L2 兑换这张 Retryable Ticket。这种方式方式的设计初衷是为了弥补第一种方式会因为 Gas 不够而失败。下图展示了三种具体发送信息的方法。

![](https://storage.googleapis.com/papyrus_images/35a892cd58cfd7b326e41072e2cdd10b.png)

![](https://storage.googleapis.com/papyrus_images/6cb62c1171b3e8493a3eef35442f54fc.png)

![](https://storage.googleapis.com/papyrus_images/d08f5914ba52b5167e39329625f294a2.png)

L1 发送到 L2 的消息会被放在 Inbox，例如将以太坊存入 L2。任何人都可以将消息放入 Inbox 中。但是当信息在 L2 被执行时，用户无法得知具体执行结果。

下图展示了信息如何流动的。 用户将消息发送给桥组件。在未来24小时，只有 Sequencer 可以执行这些消息。24 小时后，任何人都可以执行这些消息，并放到 Main Seqeuncer Inbox。这个机制有效防止 Sequencer 作恶和审查。

如果消息是直接由 Sequencer 提交的，Sequencer 可以立即将消息提交至 Sequencer Inbox。

![](https://storage.googleapis.com/papyrus_images/2ddc1f7c3c9ca7508ac0c044c54c8aec.png)

可以在这找到 [Arbitrum Inbox](https://github.com/OffchainLabs/arbitrum/blob/afa60b9ab2f8645fb292251d74f2adb42ecde047/packages/arb-bridge-eth/contracts/bridge/Inbox.sol) 的源代码。代理合约部署在了 [0x4dbd4fc535ac27206064b68ffcf827b0a60bab3f](https://etherscan.io/address/0x4dbd4fc535ac27206064b68ffcf827b0a60bab3f)。Inbox 合约部署在了[0xc23e3f20340f8ef09c8861a724c29db43ba3eed4](https://etherscan.io/address/0xc23e3f20340f8ef09c8861a724c29db43ba3eed4#code)。

Inbox 拥有以下 [Interfaces](https://developer.offchainlabs.com/docs/sol_contract_docs/md_docs/arb-bridge-eth/bridge/inbox)：

*   `sendL2MessageFromOrigin()`
    
*   `sendL2Message()`
    
*   `sendL1FundedUnsignedTransaction()`
    
*   `sendUnsignedTransaction()`
    
*   `sendContractTransaction()`
    
*   `depositEth()`
    
*   `createRetryableTicket()`
    

目前使用最多的函数是 `depositETH()` 。[这个交易](https://www.notion.so/Arbitrum-Inbox-01941677d9e5488c8e4a9a5f74bd9236?pvs=21)就调用了 `depositETH()` 。这笔交易发送了信息 `L1MessageType_submitRetryableTx`，并且释放了两个事件：

*   `MessageDelivered`
    
*   `InboxMessageDelivered`
    

让我们放大这张图，仔细看看用户的信息是如何被提交到 Bridge 合约的。

![](https://storage.googleapis.com/papyrus_images/a8c958bc0f78e685a1c1b8ec7e480d15.png)

消息相关的数据从 `Inbox.sol` 流到 `Bridge.sol`。数据最后被存在了 Delayed Inbox Accumulator 的末尾。

在这个生命周期，所有事件中，有两个事件包含了消息状态的转变。一个标志消息被放到 Inbox，另一个标志信息被加入队列。

---

*Originally published on [Inevitable](https://paragraph.com/@inevitable/arbitrum-architecture-inbox)*
