Polygon zkEVMの全体アーキテクチャと取引実行プロセスの詳細解説
著者: 0xhhh(Twitter: @hhh69251498 ),Binary DAO
編集者: Red One
3月27日、Polygon zkEVMメインネットのテストバージョンが正式にオンラインになり、Vitalikが上で最初の取引を完了しました。
この記事はPolygon zkEVMシリーズの第一篇であり、Polygon zkEVMの全体的なアーキテクチャと取引実行プロセスを簡潔に説明し、Polygon zkEVMがどのように計算のスケーラビリティを実現し、同時にEthereumのセキュリティを継承しているかを分析します。
また、次の2篇の記事ではPolygon zkEVMのzkEVM BridgeとzkEVMの設計詳細、さらにPolygon zkEVMの去中心化Sequencerのロードマップについて詳しく紹介します。
一、RollupはEthereumに計算のスケーラビリティを実現するために
まず、Rollupの大まかな動作原理を明確にする必要があります。Rollupの登場はEthereumに計算のスケーラビリティを実現するためであり、具体的な実現方法は取引の実行をRollupにアウトソーシングし、取引と取引実行後の状態(State)をEthereumのコントラクト内に保存することです。技術的な路線の違いから、2種類のRollupが進化しました:
Optimistic Rollup
Ethereumに送信されたRollup取引(Rollup Transaction)と対応するRollup状態(Rollup State)が正しいと楽観的に考え、誰でも欺瞞証明(Fraud Proof)を提供することで、まだ挑戦期間中のRollup Stateに対して挑戦(Challenge)できます。
Zero-knowledge Rollup
ZKはEthereumに送信されたRollup取引と対応するRollup状態に対して有効性証明(Validity Proof)を提供します(Ethereum上のコントラクトによって検証され、Rollupの実行が対応する取引後の状態が正しいことを証明します)。
Ethereum公式の定義を参照:
https://ethereum.org/en/developers/docs/scaling/#rollups
Zero-knowledge RollupとOptimistic Rollupの最大の違いは、状態の有効性を検証する方法の違いによってFinalityに達する時間が異なることです;
Optimistic RollupはEthereumに提出された取引と状態が正しいと楽観的に考えるため、7日間の挑戦期間があります(Finalityに達する時間は7日です)。この期間中に、Ethereum上の取引に対応する状態が不正確であることを発見した誰でも、正しい状態を提出することで挑戦できます。
Zero-knowledge Rollup(zk-Rollup)がFinalityに達する時間は、取引に対応する有効性証明(Validity Proof)がEthereumに提出され、検証が通過するのにかかる時間に依存します。現在、Finalityはおおよそ1時間程度が一般的です(Gasコストの問題を考慮する必要があります)。
二、Polygon zkEVMの実行プロセス
次に、簡単な取引確認プロセスを通じてPolygon zkEVMがどのように機能するかを見て、全体的なプロトコルについて具体的な理解を得ます。その全プロセスは主に3つのステップに分けられます:
- Sequencerが複数のユーザー取引をバッチにまとめてL1のコントラクトに提出します;
- Proverが各取引の有効性証明(Validity Proof)を生成し、複数の取引の有効性証明を1つの有効性証明に集約します;
- Aggregatorが複数の取引の有効性証明(Validity Proof)をL1のコントラクトに提出します。
- Sequencerがユーザー取引をバッチにまとめてL1コントラクトに提出します
1) ユーザーは取引をSequencerに送信し、Sequencerは受信した取引の順序に従ってローカルで処理します(FRFS)。Sequencerがローカルで取引を成功裏に実行した場合、ユーザーがSequencerを誠実だと信じるなら、その時点で取引がFinalityに達したと考えることができます。ここで注意が必要なのは、現在ほとんどのSequencer内部のMempool(取引プール)はプライベートであるため、現在得られるMEVは比較的少ないということです。
2) Sequencerは複数の取引を1つのバッチにまとめます(現在は1つのバッチに1つの取引のみを含む)そして、複数のバッチを収集した後、L1上のPolygonZKEvm.solのSequenceBatch()関数を通じて複数のバッチを一緒にL1の取引Calldataに送信します。
(ここで複数のバッチを一度に提出するのは、L1のGas消費を可能な限り削減するためです)
3) PolygonZkEvm.solがSequencerから提供されたバッチを受け取ると、それぞれのバッチのハッシュを順に計算し、次のバッチに前のバッチのハッシュを記録します。これにより、以下の図のバッチ構造が得られます。
4) 各バッチ内の取引の順序も確定しているため、バッチの順序が確定した時点で、バッチに含まれるすべての取引がL1のPolygon zkEVMコントラクトに提出された順序が確定したと考えます。
以上の実際のプロセスは、L1がRollup DA層として完了すべき作業でもあります(この時点では、状態の検証や進行は行われていません)。
- Aggregatorが複数のバッチの取引に対してValidity Proofを生成します
1) AggregatorはL1のPolygonZKEVM.solコントラクトに新しいバッチが正常に提出されたことを監視し、それらのバッチを自分のノードに同期させ、zkProverにこれらの取引を送信します。
2) zkProverはこれらの取引を受け取った後、各取引に対してValidity Proofを生成し、複数のバッチに含まれる取引のValidity Proofを再度集約して1つの有効性証明(Validity Proof)を生成します。
3) zkProverは複数の取引のValidity ProofをAggregatorに送信します。
- Aggregatorが集約証明をL1のコントラクトに提出します
Aggregatorはこの有効性証明(Validity Proof)と対応するこれらのバッチの実行後の状態を一緒にL1のPolygon zkEvm.solコントラクトに提出します。以下の方法を呼び出すことによって:
コントラクト内では、状態変換が正しいかどうかを検証するために以下の操作が実行されます。
このステップがL1コントラクト内で正常に実行されると、この部分のバッチに含まれるすべての取引が本当にFinalityに達します(対応するOPの7日間の挑戦期間が終了します)。
三、EthereumがPolygon-zkEVMで果たす役割
上記でPolygon zkEVMの全体的なプロセスを理解したので、EthereumがRollupのためにどのような作業を行ったかを振り返ります:
第一歩として、SequencerがRollupの取引を収集してバッチにまとめた後、L1のコントラクトに提出します。L1はDA層の機能を提供するだけでなく、実際には取引の順序付けの一部の機能も完了しています;取引をSequencerに提出する際、取引は実際には順序付けされていません。なぜなら、Sequencerは取引の順序を自由に変更できる権限を持っているからです。しかし、取引がバッチに含まれてL1コントラクトに提出された後は、誰もその取引の順序を変更する権利を持ちません。
第二歩として、AggregatorはValidity ProofをL1コントラクトに持ち込み、新しい状態を達成します。AggregatorはProposerのような役割を果たし、コントラクトはValidatorのような役割を果たします;Aggregatorは新しい状態が正しいことを証明するValidity Proofを提供し、Validatorに対して自分が提供したValidity Proofがどの取引バッチに関連しているか、そしてそれらがL1のどの位置に存在しているかを伝えます。
次に、Validatorはコントラクトから対応するバッチを抽出し、Validity Proofと組み合わせることで状態変換の合法性を検証できます。検証が成功すると、実際にコントラクト内も対応するValidity Proofの新しい状態に更新されます。
四、モジュール化の観点からSmart Contract Rollupを構造化する
モジュール化の観点から見ると、Polygon zkEVMはSmart Contract Rollupタイプに属します。各モジュールを解体してみると、Delphiからの図からもわかるように、実際にはPolygon ZkEVMがSmart Contract RollupのConsensus Layer、DA Layer、Settlement LayerがすべてPolygonZkEVM.solコントラクト内に結合されており、明確に区別することができません。しかし、各モジュールを解体してみましょう:
データ可用性層(Data Availability Layer):Rollup取引が保存される場所であり、Polygon-zkEVMにとって、SequencerがSequenceBatch()メソッドを呼び出すとき、実際にはDA層に取引データを提出することを含みます。
決済層(Settlement Layer):具体的にはRollupとL1の間の資金の流動メカニズムを指し、具体的にはPolygon-zkEVMの公式ブリッジ(次の記事で詳しく紹介します)。
コンセンサス層(Consensus Layer):取引の順序付けと次の合法的な状態を決定する方法(フォーク選択)を含みます。SequencerがL1コントラクト内のSequenceBatch()を呼び出すと、取引の順序付けが完了し、AggregatorがL1コントラクト内のTustedVerifyBatches()を呼び出すと、次の合法的な状態の確認が完了します。
実行層(Execution Layer):取引を実行し、新しい世界の状態を得ること。ユーザーがSequencerに取引を提出し、Sequencerが実行を完了した後に新しい状態を得るプロセスです(したがって、Rollupは計算のスケーラビリティを実現するとよく言われます。なぜなら、L1は取引を実行して新しい状態を得るプロセスをRollupにアウトソーシングし、SequencerはAggregatorを通じてzkProverにValidity Proofの生成を委託するからです)。
五、なぜPolygon-zkEVMがL1のセキュリティを継承していると言えるのか
上記の全体的なプロセスから見ると、実際にSequencerはEthereumのProposerに似た作業を行い、一連の取引が有効な取引であることを提案し、この取引の実行後の新しい状態を示しました;L1コントラクトの検証ロジックは、すべてのL1のValidatorが自分のEthereumクライアントで一度実行することに相当します。実際には、すべてのEthereumの検証者がRollupの検証者として機能しているため、Polygon zkEVMがEthereumのセキュリティを継承していると考えられます。
別の観点から見ると、Rollupのすべての取引と状態がEthereum上に保存されているため、Polygon zkEVMのチームが逃げたとしても、誰でもEthereum上に保存されたデータを基にして、全体のRollupネットワークを復元する能力を持っています。
六、Polygon zkEVMのインセンティブメカニズム
Rollupのインセンティブメカニズムは、SequencerとAggregatorが利益を得る方法、つまり持続的に作業を維持するための方法を指します。
まず、ユーザーはRollup上の取引手数料を支払う必要があります。この手数料はETHで計算され、Bridged ETHで支払われます。
Sequencerは、これらのRollup取引を含むバッチをL1取引のCalldataにアップロードするコスト(SequenceBatch(batches()の呼び出しコスト)を支払う必要があり、同時にバッチをアップロードする際に一定のMaticをL1コントラクトに支払う必要があります。これは、後でAggregatorがこれらのバッチに対してValidity Proofを提供するコストを支払うためです。
Aggregatorは、trusted VerifyBatchesを呼び出してL1コントラクト内でまだFinalityに達していないバッチにValidity Proofを提供する際に、Sequencerが事前にコントラクト内に支払ったMATICトークンを引き出し、Validity Proofの報酬として受け取ることができます。
Sequencerの収入 = Rollupのすべての取引のGas費用 - バッチをL1にアップロードするためにかかるL1ネットワークのGas費用 - Aggregatorに支払う証明費用(MATICで計算)。
Aggregatorの収入 = Sequencerが支払ったMATIC報酬 - Validity ProofをL1に提出するためのGas費用 - Validity Proof生成にかかるハードウェア費用。
Aggregatorに支払う証明費用を調整し、Sequencerが利益を得られずにストライキするのを避けるために、以下のメカニズムを提供してSequencerがAggregatorに支払う証明費用を調整します。
コントラクト内には、バッチに証明を提供する費用を調整するためのメソッドが存在します:
function _updateBatchFee(uint64 newLastVerifiedBatch) internal
これにより、コントラクト内のBatchFeeという変数が変更され、この変数がSequencerが各バッチに支払うMATICトークンの数量を決定します。
変更メカニズムは次の通りです:
コントラクト内には、VeryBatchTimeTargetという変数が維持されており、これは各バッチがSequencerによってL1に提出された後、期待される検証時間を示します。
コントラクト内では、VeryBatchTimeTargetを超えてまだ検証されていないバッチのすべてを記録し、これらのバッチの総数をDiffBatchesとします。
したがって、バッチが遅れた場合、以下の式を使用してBatchFeeを調整します:
MultiplierBatchFeeは1000〜1024の範囲に制限された数であり、関数setMultiplierBatchFee()を通じてコントラクト管理者によって変更できます:
Function setMultiplierBatchFee (uint16newMultiplierBatchFee) public onlyAdmin
ここでMultiplierBatchFeeと10^3を使用するのは、3つの小数点以下の調整精度を実現するためです。
同様に、バッチが早く提出された場合も、相応のbatchFee調整メカニズムが発動します:DiffBatchesは早期に状態が検証されたバッチの数を示します。
まとめ
この記事では、Polygon zkEVMの核心メカニズムを整理し、Ethereumの計算スケーラビリティを実現する可能性を分析しました。全体的なアウトラインを得た後、次の記事ではプロトコル内部に深く入り込み、zkEVM Bridgeの設計詳細やSequencerの去中心化の道筋、zkProverの実装、そしてzkEVMの設計原理を順次解析していきます。