paint-brush
Arbitrum Architecture: Inboxby@glaze
1,343 reads
1,343 reads

Arbitrum Architecture: Inbox

by GlazeSeptember 6th, 2022
Read on Terminal Reader
Read this story w/o Javascript
tldt arrow

Too Long; Didn't Read

As Nitro is released, let’s look back at the Arbitrum architecture. Arbitrum is one of the pioneers of Optimistic Rollup. It has a huge influence on successor rollups. In this research piece, we will dive deep into the essential parts of rollups and hopefully find anything similar to new rollups by ourselves. Arbitrum is an EVM-compatible optimistic rollup. Although it is EVM compatible, there are some differences in variables, like block.number. When getting block.number on Arbitrum, you will get the block number on the Arbitrum network, but not Ethereum.
featured image - Arbitrum Architecture: Inbox
Glaze HackerNoon profile picture

As Nitro is released, let’s look back at the Arbitrum architecture. Arbitrum is one of the pioneers of Optimistic Rollup. It has a huge influence on successor rollups. In this research piece, we will dive deep into the essential parts of rollups and hopefully find anything similar to new rollups by ourselves.


Arbitrum is an EVM-compatible optimistic rollup. Although it is EVM compatible, there are some differences in variables, like block.number. When getting block.number on Arbitrum, you will get the block number on the Arbitrum network, but not Ethereum.

Arbitrum deployed ETH Bridge component on L1 to communicate with Layer2. In this component, there are four main smart contracts: Inbox, Outbox, Rollup contracts and Dispute contracts. Smart contracts code are stored at arbitrum/packages/arb-bridge-eth/contracts. We will focus on the communication between L1 and L2 in this research piece, which are Inbox and Outbox.


L1 and L2 communications happen on the ETH bridge component with messages-based implementation. Messages are separated as L1 messages and L2 messages. To deliver messages from L1 to L2, we use an L1 message containing an L2 message as encoded data. There are 6 types of messages:


  • ETH_TRANSFER : Transfer ETH
  • L2_MSG : Generic L2 message to the L2 chain
  • L1MessageType_L2FundedByL1 : L1 message containing an L2 message as encoded data, funded by L1
  • L1MessageType_submitRetryableTx: Retryable ticket on L1
  • L2MessageType_unsignedEOATx: Unsinged user transaction on L2
  • L2MessageType_unsignedContractTx : L2 message which is an unsigned contract transaction

Inbox

There are two ways to send messages from L1 to L2. The first is directly sending messages by calling send-related functions. This one is simple and has relatively low latency than the second way.


The second way is to create a retryable ticket. Then users redeem this ticket on L2. Arbitrum team designs the second way because the first way may fail due to out of gas.

The following diagram shows 3 specific way to deliver message to L2.

Messages from L1 to L2 will be put in Inbox, like deposits. Anyone can submit tx to L2 through Inbox. However, when the message gets executed on L2, the caller does’’t know the execution result.


The following diagram shows a high-level overview of the message flow. Users submit the message to the inbox in the bridge component and only sequencers can release the message within 24 hours. After 24 hours, anyone can release this message to the main sequencer inbox. This mechanism can prevent sequencers from misbehaving.


If the message directly comes from the sequencer, the sequencer can immediately add the message to the sequencer inbox.

You can find Arbitrum Inbox source code on arbitrum/packages/arb-bridge-eth/contracts/bridge/Inbox.sol. The proxy contract is deployed at 0x4dbd4fc535ac27206064b68ffcf827b0a60bab3f and Inbox is deployed at 0xc23e3f20340f8ef09c8861a724c29db43ba3eed4.

Inbox has the following interfaces:

  • sendL2MessageFromOrigin()
  • sendL2Message()
  • sendL1FundedUnsignedTransaction()
  • sendUnsignedTransaction()
  • sendContractTransaction()
  • depositEth()
  • createRetryableTicket()

Currently, the most-used function is depositETH(). Here is an example transaction. This function call sends a message with type L1MessageType_submitRetryableTx and emits two events:


  • MessageDelivered
  • InboxMessageDelivered


Let’s zoom into how users submit messages to the bridge. The entry function is depositETH(). The following chart illustrates the function call graph.

Message-related data flows from Inbox.sol to Bridge.sol. The data is stored in the delayed inbox accumulator at the end.


During the lifecycle, two events are emitted showing that the message was sent to the inbox, and the inbox added the message to the queue.


This article was first published here.