イーサリアムのL2ソリューションArbitrumの紹介
こんにちは。次世代システム研究室のL.W.です。
今回はイーサリアムのL2ソリューションArbitrumを調査し、触ってみましたので、ここで共有します。
1.The Merge後のL2ソリューションについて
日本時間9月15日15:43頃、イーサリアムの大型アップグレードThe Mergeが実施されましたが、ブロックチェーンのコンセンサスアルゴリズムがPoWからPoSへ無事に移行しました。
出典:https://members.delphidigital.io/reports/the-complete-guide-to-rollups
マージにより、イーサリアムのエネルギー消費が最大99.95%削減されました。
一方、気になるgas fee(ガス代、手数料)、tps (トランザクションスループット)、transaction finality(トランザクションの最終性、一度承認されたトランザクションは覆らない)がどうなりますか。
結論ですが、gas fee、tps にはThe Merge前と比べると、ほぼ変わらないです。
ガス代は、イーサリアムネットワークの容量に対するイーサリアムネットワーク需要の産物であります。
イーサリアムのブロックあたりのgas limit はThe Merge前と同じガス制限の30,000,000 と変わらないことで、 ブロック生成時間は12 秒に固定されていたが、The Merge前の平均の13 秒を 7% 改善するだけです。
したがって、gas feeが下がる余地、tpsが上がる余地はないかと判断されています。
The Mergeの後、transaction finalityはむしろ前より長くなってしまいます。イーサリアムのPoSコンセンサスにより、ビーコンチェーンブロックが確定するまでに 64 ~ 95 スロット (約 15 分) かかることとなります。
レイヤ2ソリューションがイーサリアムのスケーリングの鍵となっています。
社会的な実用には、皆さんにかなり期待されています。
2.Arbitrumの概要
Arbitrum(アービトラム)は、Offchain Labs によって、スケーラビリティ問題でガス代などが高騰しがちなイーサリアムのトランザクションを非常に高速かつ安価にするために設計されたレイヤー2(L2)ソリューションの一つであり、Optimistic Rollup技術でイーサリアム のセキュリティ性を便乗させます。
Arbitrumのメインネットは「Arbitrum One」と名付けされて、まだベータ版(beta)ではありながら、既に多くのDeFi(分散型金融)、NFT(非代替性トークン)、Web3プロジェクトがArbitrum Oneにローンチされています。
そして、TVL(ロックアップされた資産総額)からすると、ArbitrumはイーサリアムのL2ソリューションでダントツトップOneとなっています。
最新の技術スタックNitroを採用した大型アップグレードはが8月31日に実施されたことにより、tpsがもっと向上し、gas feeがもっと安くとなるし、Arbitrum と Ethereum 間のクロスチェーン通信がもっと簡素化されます。
では、一体、gas fee、tps 、transaction finalityにおいて、Arbitrumはどのように改善に取り組んでいますか。3.Optimistic Rollup
3.1 Rollupとは
Rollupの定義は何ですか。ここでの定義を引用させてください。「Rollups are blockchains that post their blocks to another blockchain, and inherit the consensus and data availability of that blockchain (referred to as a “consensus and data availability layer”).」
「Rollupとは、ブロックを別のブロックチェーン(「コンセンサスとデータ可用性レイヤー」と呼ばれます)に配置し、そのブロックチェーンのコンセンサスとデータの可用性を承継するブロックチェーンである 。」
Rollupのモデルを簡約的に纏めると、オンチェーンのスマートコントラクト + オフチェーンのアグリゲーターです。
・ オンチェーンのスマートコントラクト
イーサリアムを始めのRoot Chainのセキュリティ性を活用します。
・ オフチェーンのアグリゲーター
トランザクションをオフチェーンで実行および集約し、大規模なトランザクションを圧縮し、最終的にバッチとしてイーサリアムなどのRoot Chainに配置して、より高速で安価な目的を達成することを目指します。
Rollup Chainで順序付けのトランザクションを束ねるのはバッチです。
大方のRollupソリューションですが、トランザクションの計算、検証、保存はRollup Chainで行い、データの可用性のため、定期的にトランザクション自体とこれらのトランザクションで作成したステートのMerkle Tree RootもRoot Chainに保持させます(ここでのステートというのは、口座残高、コントラクトのコードとデータということであります。)誰でもこれらのトランザクションでRollchainでのフルステートを再現できます。
これで、Rollup ChainのセキュリティーはRoot Chainにより裏付けられます。
Root Chainでの計算、検証、保存コストはRollup Chainより高いことで、大部分をRollup Chainに移転することで、手数料を軽減させますね。
Root ChainではステートのMerkle Tree Rootを維持するスマートコントラクトがあります。
出典:https://vitalik.ca/general/2021/01/05/rollup.html
誰でも、高度に圧縮された形式のトランザクションのコレクション、そして、以前のステートのMerkle Tree Rootと新しいステートのMerkle Tree Root (トランザクション処理後のマークルルート) のバッチを発行し、Root Chainに登録させます。
Root Chainでのコントラクトは、バッチ内の以前のステートルートが現在のステートルートと一致するかどうかを検証します。 一致する場合は、ステートルートを新しいステートルートに切り替えます。
出典:https://vitalik.ca/general/2021/01/05/rollup.html
では、ここで問題が潜んでいますね。バッチの中で不正なトランザクションを混ざっている場合、どのようにこの不正を見抜きますか。見逃したら、この不正なトランザクションにより、Rollup chainに滞在するどなたが損失を被るリスクがありますね。
この問題を解決する方法の一つは、zk-Rollupです。zk-SNARKsを活用したRollupです。ここで展開しません。
もう一つはOptimistic Rollup(ORU)が挙げられています。
出典:https://medium.com/@foresightventures-zh
3.2 Optimistic Rollup (ORU)
fraud proofsを使用する楽観的Rollupです。 Rollupコントラクトは、ステートルートの全履歴と各バッチのハッシュを追跡します。 あるバッチの事後ステートのルートが正しくないことを誰かが発見した場合、そのバッチが正しく計算されなかったことのプルーフをRoot チェーンに公開し、不正に挑戦します。 Root チェーンでのコントラクトはこのプルーフを確かに不正か検証し、そのバッチとそれ以降のすべてのバッチを元に戻せます。アービトラムはoptimisticです。つまり、アービトラムは、任意の当事者 (例えば、フルノードのバリデーター) に、その当事者が正しいと主張するロールアップ ブロックをレイヤー 1 に出張させ、他のすべての人にその主張に異議を唱える機会を与えることによって、チェーンの正しい状態を進めます。
異議申し立て期間 (dispute期間、約 1 週間) が経過し、主張されたロールアップ ブロックに誰も異議を申し立てなかった場合、Arbitrum はロールアップ ブロックが正しいことを確認します。 誰かが異議申し立て期間中に申し立てに異議を申し立てた場合、Arbitrum は効率的な紛争解決プロトコルを使用して、どちらの当事者が嘘をついているのかを特定します。 嘘つきは手付金を没収され、誠実者はその手付金の一部を彼らの努力に対する報酬として受け取ります (手付金の一部は燃やされ、共謀があったとしても嘘つきが罰せられることが保証されます)。
不正行為をしようとする当事者は手付金を失うため、不正行為を試みることは非常にまれであり、通常のケースでは、1 つの当事者が正しいロールアップ ブロックを投稿し、誰もそれに異議を唱えません。
異議を申し立てることにはトランザクションの再実行(re-executing transactions)とインタラクティブな証明(Interactive proving)の二つの方法があります。
インタラクティブな証明では、トランザクションごとに、計算されたマシンステートハッシュをロールアップ ブロックに含めることです。 異議が発生した場合、Root chainでのコントラクトは審判員として、トランザクション全体の実行をエミュレートして、結果が出張者の主張と一致するかどうかを判定します。
Arbitrum は、インタラクティブな証明という方法を採用しています。より効率的、柔軟的と言われています。
4.Arbitrumの技術スタック
4.1 Full Node
名前が示すように、Arbitrum のフルノードは、イーサリアムのフルノードと同じ役割を果たします。チェーンのステートを認識し、他のユーザーがチェーンと対話するために使用できるAPIを提供します。Arbitrumでは、sequencerとvalidatorの二つ種類のフルノードがあります。
4.2 Sequencer
出典:https://github.com/OffchainLabs/nitro/blob/master/docs/Nitro-whitepaper.pdf
sequencer(シーケンサー)は特別に指定された Arbitrum フルノードであり、ユーザーのトランザクションを定期的(数分間)に イーサリアムに送信する役割があります。つまり、Arbitrumブロックの作成者、またはバッチの実行者であります。
原則として、チェーンのシーケンサーはさまざまな形式を取ることができます。 Arbitrum One の現状では、Sequencer は単一の中央集権型エンティティ(Offchain Labs側運営)です。
Sequencerは中央主権で、gas feeを安価にさせ、トランザクションのフィナリテは速くさせます。
一方、Sequencerは攻撃でサービス停止、またはトランザクションの順序を変更したり、トランザクションのブロックへの組み込みを一時的に遅らせたりする可能性がありますが、これを防げるためには、Validator(バリデーター)というArbitrum フルノードはArbitrumプロトコルへ加えられます。
4.3 Validator
バリデーターは、Arbitrumチェーンの安全性を担当するものです。 つまり、プロトコルの進行状況を監視し、チェーンの状態について不正を主張したり、互いに論争したりするなどです。バリデーターが積極的(active)、防御的(defensive)、または監視塔(watchtower)のモード(または戦略、strategy)が設けられています。
Offchain Labs は、これらのいずれかの戦略に従うことを期待しています。 ただし、これはプロトコルによって強制されません。
「アクティブなバリデーター」は、新しいブロックを提案することにより、チェーンを前進させるために継続的に取り組んでいます。 Arbitrumチェーンに 1 つの誠実でアクティブなバリデータのみが必要です。 アクティブなバリデーターの数を増やしても、チェーンの効率は向上しません。現状Offchain Labsが一つのアクティブなバリデーターを運営しています。
「防衛的なバリデーター」はRollupプロトコルを監視し、不正行為を監視した場合にのみ行動し、その時点で正しいブロックを提案するか、または正しいブロックが既に提案されている場合は、そのブロックに賭けます。
「監視塔のバリデーター」は防御型バリデーターと同じようにRollupプロトコルを監視しますが、不正行為を発見した場合、正しいブロックを自分で提案したり賭けたりすることはなく、他のバリデーターやユーザに不正があることを警告するだけです。
誰もが Arbitrum プロトコルに参加するために、パーミションレスでバリデーターを立ち上げます。 Arbitrumチェーンの歴史やステートについては何も秘密にならないです。
4.4 フルノードのソフトウェアストラクチャ
フルノードのメインなデザインアイデアは、「geth at the core」であります。 ここで「geth」とは、イーサリアムの最も一般的なノード ソフトウェアである go-ethereum を指します。 その名前が示すように、go-ethereum は Go 言語で書かれており、Arbitrumも同様にGoで実装されています。Arbitrumフルノードを構成するソフトウェアは、主に 3 つのレイヤーで構築されています。
最上層と最下層は geth のコードに大きく依存しているため、この構造は「geth サンドイッチ」と呼ばれています。
出典:https://github.com/OffchainLabs/nitro/blob/master/docs/Nitro-whitepaper.pdf
4.4.1 Geth core
ベースレイヤーであり、EVM コントラクトの実行をエミュレートし、イーサリアムのステートを構成するデータ構造を維持する部分です。Arbitrum NitroはこのGethのコードをライブラリとしてコンパイルし、必要なフックを追加するためにいくつかのマイナーな修正を行っただけです。
4.4.2 ArbOS
ArbOS と呼ばれるミドルレイヤーは、 Arbitrumチェーンの管理に必要かつ便利な機能を実装するソフトウェア レイヤーです。 これには、トランザクションの収集とシーケンシング、クロスチェーン通信、および Arbitrum 固有の料金の追跡と徴収が含まれます。State Transition Function (STF)はここで実現されています。
トランザクションがシーケンス処理された後、チェーンのSTF を使用して Nitro チェーンによって処理されます。 STF は、ステートと、通常は単一のトランザクションである受信メッセージを入力として受け取ります。 STF の出力は更新されたステートであり、新しい Ethereum 互換のブロック ヘッダーが Nitro チェーンに追加されます。
STF は完全に決定論的であるため、トランザクションで STF を実行した結果は、トランザクションのデータとトランザクション前のステートのみに依存します。このため、トランザクション T の結果は、Nitro チェーンの生成ステート、T に先行する一連のトランザクション、および T 自体にのみ依存します。
この決定論のおかげで、誠実な当事者は、トランザクション シーケンスだけが与えられれば、チェーンの完全なステートと履歴を決定できます。正しいステートと履歴に同意するために、ノードは通信する必要がなく、それらの間でコンセンサスも必要ありません。これは、すべての人に見えるトランザクションシーケンスにのみ依存するためです。
4.4.3 Node functionality
トップレイヤーであり、主に geth から引き継いだノード ソフトウェアで構成されます。 Arbitrumクライアントからの接続と RPC リクエストを処理し、イーサリアムと互換性のあるブロックチェーンノードを操作するために必要なその他のトップレベルの機能を提供します。EthereumのJSONーRPC APIはArbitrumにも適用できます。
eth_getTransactionReceiptを例にします。
{ "success": 1, "transactionReceipt": { "transactionHash": "0xd143bd3b5c71cfea8c8acae29cb66eb4f559ff9ce944fd23c34ef9f874583c5c", "blockHash": "0xf72032e7a78bc4a4696733be28fa57e8f532726909cce8b97d921e269eb28e50", "blockNumber": 29343538, "logs": [ { "transactionHash": "0xd143bd3b5c71cfea8c8acae29cb66eb4f559ff9ce944fd23c34ef9f874583c5c", "address": "0x6C2C06790b3E3E3c38e12Ee22F8183b37a13EE55", "blockHash": "0xf72032e7a78bc4a4696733be28fa57e8f532726909cce8b97d921e269eb28e50", "blockNumber": 29343538, "data": "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", "logIndex": 0, "removed": false, "topics": [ "0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925", "0x00000000000000000000000066856a4211af5dcab6a1e2b6204111cd9bddf6fe", "0x0000000000000000000000001b02da8cb0d097eb8d57a175b88c7d8b47997506" ], "transactionIndex": 1, "id": "log_0x2f22c2b7356abccad18934e8cc815ea3fec5c1bce4c054a06ff95586b0f32280" } ], "contractAddress": null, "effectiveGasPrice": "0x5f5e100", "cumulativeGasUsed": 484406, "from": "0x66856a4211af5dcab6a1e2b6204111cd9bddf6fe", "gasUsed": 484406, "logsBloom": "0x00000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000200000000000020000000000000000000000000800000000000000000000002000000000000000000000000100000000000000000000000000000000000000000000000000020000000000000000000400000000000000000000000000000000000000020000000000000000000000000000000000000000000010000000000000000000000000000040000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000", "status": true, "to": "0x6c2c06790b3e3e3c38e12ee22f8183b37a13ee55", "transactionIndex": 1, "type": "0x2", "l1BlockNumber": "0xefc900", "gasUsedForL1": "0x686f0" } }
4.5 Cross-Chain Messaging
上で説明のように、ArbOS の役割の 1 つは、Arbitrum とレイヤー 1のイーサリアム間の両方向で安全なクロスチェーン コールをサポートすることです。 1 つの層のアカウントはトランザクションを他のチェーンに送信でき、そのトランザクションは非同期で実行されます。Ethereum から Arbitrum Nitro チェーンへの呼び出し(L1 to L2 messaging)をサポートするためには、 イーサリアムでInbox コントラクトと ArbitrumのRetryable Tickets が導入されています。
Arbitrum Nitro チェーンから Ethereum への呼び出し(L2 to L1 messaging)をサポートするためには、 Outbox コントラクトが導入されています。
Inboxは一連のレイヤ 1 イーサリアム コントラクトによって管理されて、Arbitrumチェーンに送信されたメッセージ (通常はトランザクション) を記録する役割を果たします。
うちにはDelayed Inboxコントラクトを含めます。 Delayed Inboxはレイヤ 1 で送信されたメッセージを受信し、メインの Inbox は Sequencer によって送信されたメッセージと Delayed Inbox からのメッセージのマージを受信します。
トランザクションは、 ArbitrumチェーンのInboxコントラクトでメソッドを呼び出すことにより、Delayed Inbox に追加されます。 コントラクトでは、タイムスタンプ付きのトランザクションのキューを保持します。 Sequencer は、Delayed Inboxキューの最初のメッセージをシーケンスに含めることができます。
誠実なシーケンサーは、Delayed Inboxへのそのメッセージの到着が L1 チェーンの再編成(Reorg)によって一掃されないことを保証するのに十分な長さの短い遅延の後にこれを行います。(通常は 10 分の遅延です)。
つまり、L1からL2までの移転は少なくとも10分を待つしかないですね。
Outbox コントラクトによって、L2 から L1 への任意のコントラクト コールが可能です。 つまり、L2 で開始され、最終的に L1 で実行されるメッセージです。 Optimistic Rollupに固有のセキュリティ プロパティを考えると、送信メッセージの L1 実行は、メッセージの論争期間(1週間)が経過し、そのロールアップ ブロックが確認された後にのみ行うことができます。
Optimistic Rollupプロトコールにより、L2からL1までの移転は少なくとも1週間を待つしかないです。
4.5.1 L1-to-L2 Messaging
Retryable Tickets(再試行可能なチケット)は、L1 から L2 へのメッセージ (L2 で実行されるメッセージを開始する L1 トランザクション) を作成するための Arbitrum の正規の方法です。再試行可能なものは、L1 で支払われる固定料金 (calldata サイズのみに依存) で送信できます。 L1 での送信は、L2 での実行と分離可能/非同期です。 Retryables はクロス チェーン操作間の原子性を提供します。 送信を要求する L1 トランザクションが成功した場合 (つまり、元に戻らない場合)、L2 での Retryable の実行も最終的に成功することが強く保証されます。
Retryableは、Inbox の createRetryableTicket メソッドを介して送信されます。 一般的なケースでは、再試行可能な送信の後に、トランザクションの実行が試行されます (つまり、「auto-redeem」)。
Retryableを実行するために使用されるガスは、呼び出しの当事者が提供します。 Retryable の実行が成功すると、Retryable は削除されます。 実行に失敗した場合、再試行可能なオブジェクトは引き続き存在し、さらにredeemの実行を試みることができます。このサイト通してredeemを再実行できます。
redeemが成功しないまま一定期間 (現在は 1 週間) が経過した場合、Retryableは失効し、自動的に破棄されます。 Retryable は、有効期限が切れる前に毎回更新される限り、無期限に存続できます。
例:
以下のはEthereumでのコントラクト
contract GreeterL1 is Greeter { address public l2Target; IInbox public inbox; ... ... function setGreetingInL2( string memory _greeting, uint256 maxSubmissionCost, uint256 maxGas, uint256 gasPriceBid ) public payable returns (uint256) { bytes memory data = abi.encodeWithSelector(Greeter.setGreeting.selector, _greeting); uint256 ticketID = inbox.createRetryableTicket{ value: msg.value }( l2Target, 0, maxSubmissionCost, msg.sender, msg.sender, maxGas, gasPriceBid, data ); emit RetryableTicketCreated(ticketID); return ticketID; } }以下のはArbitrumでのコントラクト
contract GreeterL2 is Greeter { ArbSys constant arbsys = ArbSys(100); address public l1Target; ... ... /// @notice only l1Target can update greeting function setGreeting(string memory _greeting) public override { // To check that message came from L1, we check that the sender is the L1 contract's L2 alias. require( msg.sender == AddressAliasHelper.applyL1ToL2Alias(l1Target), "Greeting only updateable by L1" ); Greeter.setGreeting(_greeting); } }
4.5.2 L2-to-L1 Messaging
L2 から開始されたメッセージは、最終的に L1 での実行で解決されます。 L2-to-L1 メッセージ (outgoingメッセージ) には、Arbitrum の L1-to-L2 メッセージ (再試行可能) と多くの共通点がありますが、いくつかの違いがあります。Optimistic Rollupの観点から見ると、アサートされた RBlock が確認されると (通常、アサートされてから 1 週間後)、このマークルルートが Outbox コントラクトの L1 にポストされます。 Outbox コントラクトは、ユーザーがメッセージを実行できるようにします。Merkle の包含証明(proofs of inclusion)を検証し、どの L2 から L1 メッセージが既に使用されたかを追跡します。
クライアントの観点から見ると、L2 から L1 へのメッセージは、L2 ArbSys プリコンパイル コントラクトの sendTxToL1 メソッドの呼び出しで始まります。 メッセージがアサーションに含まれ (通常は 1 時間以内)、アサーションが確認されると (通常は約 1 週間)、どのクライアントでもメッセージを実行できます。 これを行うために、クライアントは最初に Arbitrum チェーンのプリコンパイルNodeInterface コントラクトの constructOutboxProof メソッドへの呼び出しを介してプルーフデータを取得します。 返されたデータは、Outbox の executeTransaction メソッドで使用されて、L1で実行できます。
例:
以下のはArbitrumでのコントラクト
contract GreeterL2 is Greeter { ArbSys constant arbsys = ArbSys(100); address public l1Target; ... ... function setGreetingInL1(string memory _greeting) public returns (uint256) { bytes memory data = abi.encodeWithSelector(Greeter.setGreeting.selector, _greeting); uint256 withdrawalId = arbsys.sendTxToL1(l1Target, data); emit L2ToL1TxCreated(withdrawalId); return withdrawalId; } }以下のはEthereumでのコントラクト
contract GreeterL1 is Greeter { address public l2Target; IInbox public inbox; ... ... /// @notice only l2Target can update greeting function setGreeting(string memory _greeting) public override { IBridge bridge = inbox.bridge(); // this prevents reentrancies on L2 to L1 txs require(msg.sender == address(bridge), "NOT_BRIDGE"); IOutbox outbox = IOutbox(bridge.activeOutbox()); address l2Sender = outbox.l2ToL1Sender(); require(l2Sender == l2Target, "Greeting only updateable by L2"); Greeter.setGreeting(_greeting); } }ここが実際にexecuteTransactionを呼び出せた例です。
4.6 GasとFee
説明上、Ethereum のレイヤー 1のガスと区別するためには、Arbitrumチェーンのレイヤー 2 ガスをNitroGas という用語を使用します。 各 EVM 命令は、両方のチェーンで同じ数のガス ユニットのコストがかかります。 たとえば、MULMOD 命令は Arbitrumでは 8 NitroGas、Ethereumでは 8 Gas のコストがかかります。NitroGas の価格(Gas Price)は、Arbitrumのアルゴリズムによって変化する basefee で表示します。
Ethereum と同様に、Arbitrum は NitroGas の使用状況を追跡し、使用状況に基づいてbasefeeを動的に調整するため、需要がチェーンの持続可能な容量を超えると、需要と容量のバランスが戻るまでbasefeeが増加します。
このアプローチは、イーサリアムのユーザー エクスペリエンスを維持し、開発者とユーザーが標準のツールとウォレットを使用できるようにします。
Arbiscanでのとあるトランザクションで説明してみます。
ちなみに、JSONーRPCのeth_gasPriceでbasefeeを取得することができます。
ユーザーが Arbitrumでtx を送信するときに、支払う手数料には L1のcalldataのリソースの費用と
L2 リソースのネットワーク料金の二つ部分を含めます。
optimistic rollupにより、L2でのトランザクションは定期的に、Brotliアルゴリズムで圧縮された形で
L1のcalldata領域に登録します。
将来EIP-4488が採用されれば、calldataのコストがもっと安くなります。大変期待されていますね。
L2 リソースのネットワーク料金には、L2 ノードが tx にサービスを提供するために負担しなければならない計算、ストレージ、およびその他の負荷が含まれます。
eth_getTransactionReceiptで、とあるトランザクションのガス利用明細を取得できます。
{ "success": 1, "transactionReceipt": { "transactionHash": "0xa1cf2eb9c7ad45ffc3db9cd10a84e53cd622d786229e3e5bb8d16e0355e07729", "blockHash": "0xf30f3a5006c33ba11e58103465bb834f7447241f9b980e76cd5c0ec8a2c3d882", "blockNumber": 22887274, "logs": [], "contractAddress": null, "effectiveGasPrice": "0x5f5e100", "cumulativeGasUsed": 82031, "from": "0x80c67432656d59144ceff962e8faf8926599bcf8", "gasUsed": 82031, "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "status": true, "to": "0xf5bae3e8f61468762ba115802570831f2b294c3a", "transactionIndex": 1, "type": "0x0", "l1BlockNumber": "0xec225e", "gasUsedForL1": "0xee67" } }
4.7 ETH Bridge
L1 と L2 の間でメッセージを渡す機能 (Cross-Chain Messaging) を活用して、資産を Ethereum から Arbitrum チェーンに、またその逆にトラストレスに移動できます。 Ether、ERC20 トークン、ERC-721 トークンなど、原則としてあらゆる資産をブリッジできます。Arbitrumチェーンではネイティブトークンが発行されていませんが、EthereumからブリッジされたEtherがガス代に当てます。
Ethereum から Arbitrum チェーンに Ether をブリッジするには、Inbox.depositEth を介して入金トランザクションを実行します。 これにより、資金が L1 のBridge コントラクトに転送され、同じ資金が Arbitrum チェーン内の指定されたアドレスに入金されます。
Etherなどの資産のブリッジにはArbitrumの公式ブリッジサイトで完成できます。
このブリッジはOffchain Labs が実装した「Canonical Bridge」であり、ほとんどのユーザーとアプリケーションが使用する主要なブリッジです。 Ethereum と Arbitrum の両方でコントラクトを持つ DApp であり、Arbitrum のCross-Chain Messagingを活用して基本的な望ましいトークンブリッジ機能を実現します。
4.8 Token Bridge
イーサリアムのトークン コントラクトは、Arbitrumでのトークン コントラクトに関連付けられます(mapping、マッピング)。 トークンをデポジットするには、L1 ブリッジ コントラクトでトークンの一部をエスクロー(escrow)し、L2 のペアのトークン コントラクトで同じ金額を発行する必要があります。 L2 では、ペアのコントラクトは通常の ERC20 トークン コントラクトと同じように動作します。引き戻し(withdraw)には、L2 コントラクトでトークンの一部をバーンする必要があり、後で L1 ブリッジ コントラクトから請求できます。
トークンブリッジのアーキテクチャは、次の 3 種類のコントラクトで構成されています。
■ Asset contracts: これらはトークン コントラクト自体です。つまり、L1 の ERC20 と Arbitrumで の対応物です。
■ Gateways: 特定のタイプのクロス チェーン アセット ブリッジングを実装するコントラクトのペアです。 (L1 に 1 つ、L2 に 1 つ)。
GatewayはL1 ERC20 Gateway、L1 Arb-Custom Gatewayと専用Gateway(現状はL1 Livepeer Gateway、L1 Weth GatewayとL1 Dai Gatewayしかない)区別されています。
Arbitrumでマッピングするトークンがないまま、EthereumでのERC20トークンをブリッジする場合、デフォルトにArbitrumで対応するスタンダードERC20トークンがデプロイされて、Ethereumでのとマッピングされます。EthreumからArbitrumにブリッジする場合、トークンはL1 ERC20 Gatewayにエスクローされます。
ArbitrumでカスタマイズのERC20トークンをデプロイし、EthereumでのERC20トークンとマッピングし、EthreumからArbitrumにブリッジする場合、トークンはL1 Arb-Custom Gatewayにエスクローされます。
■ Routers: 正確に 2 つのコントラクト (L1 に 1 つ、L2 に 1 つ) で、各アセットを指定されたGateway(ゲートウェイ)にルーティングします。
4.8.1 deposit(L1からL2へ)
出典:https://developer.offchainlabs.com/asset-bridging
ユーザはEthereumでのSomeERC20TokenをArbitrumにブリッジしようとします。SomeERC20Tokenは既にはArbitrumでのarbSomeERC20Tokenとマッピングされたこととします。
① ユーザーが Router.outBoundTransfer を呼び出します (引数として SomeERC20Token の L1 アドレスを使用)。
② Router は SomeERC20Token のGateway(ゲートウェイ)を検索する。
③ Router は 検索されたGatewayのoutBoundTransfer を呼び出し、適切なパラメータを転送します。
④ L1でのGateway はトークンをエスクローし、再試行可能なチケット(retryable ticket)を作成して、L2 で のGateway の finalizeInboundTransfer メソッドをトリガーします。
⑤ finalizeInboundTransfer は、L2 の arbSomeERC20Token コントラクトでbridgeMint方法通して、適切な量のトークンを作成します。
※ 以上の①、②、③の一つ例はここで参照できます。④、⑤の一つ例はここで参照できます。
4.8.2 withdraw(L2からL1へ)
出典:https://developer.offchainlabs.com/asset-bridging
① Arbitrum では、ユーザーが L2GatewayRouter.outBoundTransfer を呼び出し、これが arbSomeERC20Token のゲートウェイ (つまり、L2ERC20Gateway) で outBoundTransfer を呼び出します。
② arbSomeERC20Token トークンのbridgeBurnに通してトークンをバーンし、L1でのGateway.finalizeInboundTransfer へのエンコードされたメッセージで ArbSys を呼び出します。これは最終的に L1 で実行されます。
③ 紛争ウィンドウが期限(1週間)切れになり、ユーザーのトランザクションでのアサーションが確認された後、ユーザーは Outbox.executeTransaction を呼び出すことができます。これにより、エンコードされた L1でのGateway.finalizeInboundTransfer メッセージが呼び出され、ユーザーのトークンが L1のGateway コントラクトのエスクローから解放されます。
※ 以上の①、②の一つ例はここで参照できます。③の一つ例はここで参照できます。
4.9 Arbitrumのトランザクションのファイナリティー
L1からL2への移転は10分がかかります。L2からL1への移転は1週間がかかります。この二つのケースは特別です。Arbitrumチェーンでのファイナリティーについて、二つのモデルがあります。
① Soft Confirmation(ソフト確認)モデル(sequencerに信頼するモード)
シーケンサーはArbitrumのトランザクションを受信すると、オフチェーンのInboxで順序づけし、
Arbitrum のVM を使用してローカルで実行します (L1 および L2 料金の収集/割り当てなどを含む)。
クライアントにトランザクションのレシートを即座に提供します (追加のオンチェーン確認を必要とせず、通常は 1 秒または 2 秒以上かかるべきではないという)。
② Ethereum-Equivalent Finalityモデル
シーケンサーは通常の状態では、Sequencer は数分ごとに、クライアントのトランザクションを含む L2 トランザクションのバッチをcalldata としてイーサリアムに登録します。
シーケンサーのソフト確認の信頼モデルに不快感を感じるクライアントは、シーケンサーがトランザクションをバッチでポストするまで待つことができます。
L1でのバッチトランザクションはここで確認できます。
クライアントが少なくとも 1 つの誠実に動作するアクティブな Arbitrum バリデーターがあると信じていると仮定すると (Arbitrum ロールアップでは、検証はパーミッションレスであることを思い出してください)、クライアントはトランザクションのファイナリティを通常の Ethereum トランザクションと同等に扱うことができます。
つまり、L2 トランザクションは、それをバッチで記録した L1 トランザクションと同じファイナリティを持っています。クライアントが通常の Ethereum トランザクション (つまり、L1の何回のconfirmations数を待つ) に使用するファイナリティを、L1バッチポスティング トランザクションに適用します。
L2トランザクションのブロックを生成するシーケンサーバッチのL1トランザクションのconfirmations数を取得ためには、getL1Confirmationsを利用できます。
4.10 ArbitrumのOptimistic Rollup プロトコール
紛争(dispute)が発生した場合、Arbitrum は、インタラクティブな証明という方法を採用しています。より効率的、柔軟的と言われています。出典:https://medium.com/@foresightventures-zh
詳しくの解説は、今回はここで展開しませんが、知りたい方はこれに参照して頂ければと思います。
4.11 Arbitrum Nova
分散型SNS、ゲーム向けに設計されたArbitrum Novaチェーンは8月に本番稼働となり、Nitro技術のArbitrum Oneと並行的に運行されています。手数料はArbitrum Oneよりかなり安くて、大手掲示板サイトRedditがこれを採用していたと報道されています。Arbitrum NovaはAnyTrust技術で作られています。AnyTrustはNitroのバリアントであり、Nitro コード ベースに含まれており、AnyTrust 機能は構成スイッチによって有効または無効にされます。
Arbitrum Nitroプロトコルの正確さには、すべての Arbitrum ノードが Arbitrum チェーンのインボックス内のすべての L2 トランザクションのデータにアクセスできる必要があります。L1 Ethereum に calldata としてデータを (バッチ化された、圧縮された形式で) ポストすることにより、データアクセスを提供します。 これを支払うための Ethereum ガスは、Nitro のコストの最大の要素です。
AnyTrust は代わりに、外部のデータ利用可能性委員会 (Data Availability Committee、DAC) に依存して、オンデマンドでデータを提供します。DACはオンチェーンデータへのアクセスを提供し、トランザクションを検証して、スケーラブルで安全なブロックチェーンイノベーションをサポートすることです。
出典:https://github.com/OffchainLabs/nitro/blob/master/docs/Nitro-whitepaper.pdf
DACはWeb2 および Web3 の主要なプレーヤーで構成されます。現状はInfura、Offchain Labs、Reddit、Google Cloud、FTX、P2P、および QuickNode が加えられています。
5.まとめ
Arbitrumは依然としてBeta版(完全な分散型ではない)であり、シングルのSequencer、限られたvalidators(validator whitelisting)で構成されています。これで多少リスクが潜んでいますね。
Sequencerがサービスダウンとなってしまったことがありますね。キャンペーンで、Arbitrumでのトランザクションの殺到により、gas priceはL1のイーサリアムを超えたこともありました。そして、Ethereumでのコントラクト群はアップグレード(upgradeability)型であり、管理ロールのキーが流出されたら、または攻撃されたら、ロックされている資産の流失に繋がります。
Beta版以降のArbitrumはどのように改善していくか、楽しみに見守っていきたいです。
今回は理論的なことばかり並べてみましたが、早くArbitrumを動かしたいならば、当研究室のメンバーによる過去記事を参照ください。
https://recruit.gmo.jp/engineer/jisedai/blog/arbitrum/
6.最後に
次世代システム研究室では、グループ全体のインテグレーションを支援してくれるアーキテクトを募集しています。アプリケーション開発者の方、次世代システム研究室にご興味を持って頂ける方がいらっしゃいましたら、ぜひ募集職種一覧からご応募をお願いします。皆さんのご応募をお待ちしています。