0 シンプルな概要
アクセスリストを含むトランザクションタイプを追加します。
アクセスリストとは、トランザクションがアクセスする予定のアドレスとストレージキーのリストのことです。
リスト外へのアクセスも可能ですが、その分費用が高くなります。
1 抽象的な説明
新たなEIP-2718トランザクションタイプを導入します。
そのフォーマットは0x01 || rlp([chainId, nonce, gasPrice, gasLimit, to, value, data, accessList, signatureYParity, signatureR, signatureS])となります。
アクセスリストはアドレスとストレージキーのリストを指定します。
これらのアドレスとストレージキーは、accessed_addressesとaccessed_storage_keysというグローバルなセット(EIP-2929で導入)に追加されます。
ガスコストが発生しますが、リスト外へのアクセスに比べて割引が適用されます。
2 モチベーション
このEIPは二つの機能を果たします。
EIP-2929によって導入されたコントラクト破壊のリスクを緩和します。
トランザクションは、アクセスする予定のアカウントとストレージスロットを事前に指定し、その分の料金を前払いできます。
その結果、実際の実行時には、SLOADとEXT*オペコードのコストは100ガスだけになります。
これは、EIP-2929による破壊を防ぐだけでなく、EIP 1884のために停止してしまったコントラクトを解除するのに十分低いコストです。
アクセスリストの形式とその形式を扱うロジックを導入します。
このロジックは、ブロック全体の証人、ReGenesisでの使用、時間をかけて静的な状態アクセスに移行するなど、他の多くの目的に再利用することができます。
3 仕様
1 定義
1)TransactionType 1
EIP-2718を参照してください。
2)ChainId
このchainIDを持つネットワークでのみ有効なトランザクションです。
3)YParity
secp256k1署名のy値のパリティ(偶数の場合は0、奇数の場合は1)
2 パラメータ
FORK_BLOCK_NUMBERから、TransactionType 1の新たなEIP-2718トランザクションが導入されます。
このトランザクションのEIP-2718 TransactionPayloadはrlp([chainId, nonce, gasPrice, gasLimit, to, value, data, accessList, signatureYParity, signatureR, signatureS])となります。
このトランザクションのsignatureYParity、signatureR、signatureS要素は、keccak256(0x01 || rlp([chainId, nonce, gasPrice, gasLimit, to, value, data, accessList]))に対するsecp256k1署名を表します。
このトランザクションのEIP-2718 ReceiptPayloadはrlp([status, cumulativeGasUsed, logsBloom, logs])です。
トランザクションが有効であるためには、accessListは[[{20バイト}, [{32バイト}...]]...]型である必要があります。
ここで、...は「左のものをゼロ回以上」という意味です。例えば、以下は有効なアクセスリストです(全ての16進数文字列は実際にはバイト表現であります)
実行の開始時(つまり、EIP-2028のルールに従って21000 + 4 * ゼロ + 16 * 非ゼロのスタートガスが課される時点)、
0xabcdef0000
そして、アクセスリストのための追加ガスを課します。
1アドレスあたり
ACCESS_LIST_ADDRESS_COSTガス、
1ストレージキーあたり
ACCESS_LIST_STORAGE_KEY_COSTガス
例えば、上記の例ではACCESS_LIST_ADDRESS_COST * 2 + ACCESS_LIST_STORAGE_KEY_COST * 2ガスが課されます。
なお、非ユニークなアドレスとストレージキーは禁止されていないことに注意してください。
ただし、それらは複数回課金され、高いガスコスト以外に実行フローや結果には何の違いもありません。
そして、値の複数回の包含によるガスコストの増加を除けば、推奨される単一の包含に対して実行フローや結果に他の違いはありません。
アドレスとストレージキーは即座にaccessed_addressesとaccessed_storage_keysのグローバルセットに読み込まれます。
これは次のロジックを使って行うことができます。
これはRLPデコードされたアクセスリストの検証の仕様をコード化したものとして二重の役割を果たします。
access_listの分だけ繰り返しています。
assert文を使って検証を行なっています。
accessed_addresses, accessed_storage_keysに加えて、gas_costも増加させていることがわかります。
アクセスリストは、トランザクションデータのようにバイトごとに料金が課されるわけではありません。
上記で述べたアイテムごとのコストは、アクセスリストデータの帯域幅コストだけでなく、トランザクションの評価時にこれらのアカウントとストレージキーにアクセスするコストもカバーするためのものです。
4 根本原理
1 アクセスリスト内のアクセスに対して少ない料金を課す
これは、トランザクションができるだけアクセスリストを使用することを奨励し、ストレージの読み込みが予測可能であるときにトランザクションの処理が容易になるためです。
クライアントはデータベースからデータを事前に読み込んだり、トランザクションが受信された時点で証人を求めたり、少なくともデータを並列に読み込むことができます。
2 重複を許す
このアプローチは最大限にシンプルさを追求するために採用されています。
これにより、どの要素に対して重複を防ぐべきかという問題が回避されます。
具体的には、アクセスリスト内の二つのアドレス/キー間で防ぐべきなのか、アクセスリストとトランザクションの送信者/受信者/新規に作成されたコントラクトとの間で防ぐべきなのか、また他に制限すべき箇所があるのか、といった疑問を避けることができます。
ガスはアイテムごとに課金されるため、同じ値をアクセスリストに二度含めることには利点がなく、コストだけが増えます。
したがって、実際にはこれがブロックチェーンの過剰な膨張を引き起こすことはないと考えられています。
3 署名はトランザクションタイプとトランザクションデータの両方に対して行われる
これは、トランザクションが異なるタイプのトランザクションとして「再解釈」されることを防ぐために行われます。
5 後方互換性
このEIPは、「予期せぬ」SLOADとアカウントアクセスを行うためのガスコストを高くします。
ガスは前払いであり、したがって固定ガスのローカル呼び出しに影響を与えないため、これは以前のガスコストの増加がリスクをもたらすような方法でコントラクトを破ることはありません。
しかし、ストレージへのアクセスを大量に依存するアプリケーションは、経済的にはずっと実行しにくくなります。
6 セキュリティの考慮事項
1 アクセスリストの生成
アクセスリストは多くの状況でリアルタイムで構築するのが難しく、これはトランザクションの生成と署名の間に高いタイムラグがある環境や、トランザクションジェネレータの単純さが非常に重視される環境(例えば、ハードウェアウォレットなど)でさらに悪化します。
しかし、このEIPはアクセスリストに対して初期の10%割引を提案しているだけなので、アクセスリストの生成に手間をかけずにシンプルなトランザクションを作成するだけでほとんどコストがかからないはずです。
アクセスリスト外の状態にアクセスするコストは、ツールが開発され、アクセスリストの生成がより成熟するにつれて、将来のハードフォークで時間とともに増加すると予想されます。
2 トランザクションサイズの膨張
アクセスリストが使用される結果として、平均ブロックサイズが増加します。
しかし、アクセスリストのバイトあたりのコストは、ストレージキーに対して1900 / 32 = 59.375、アドレスに対して2400 / 20 = 120となり、calldataよりもはるかに高価であるため、最悪の場合のブロックサイズは増加しません。
さらに、平均ブロックサイズの増加は、トランザクションの受信時にストレージを事前にフェッチしたり、ブロックを受信したときにストレージを並列にロードしたりする能力によって部分的に補償されます。
7 著作権
著作権および関連する権利はCC0を通じて放棄されます。
8 引用
このドキュメントを引用する際は以下のようにしてください。
Vitalik Buterin (@vbuterin), Martin Swende (@holiman), "EIP-2930: Optional access lists," Ethereum Improvement Proposals, no. 2930, August 2020. [Online serial].