EIP2938
概要
2020.09.04 に Vitalik らが提案したが、採用には至っていない
目指すところは EIP86 とほぼ同様だが、当時は存在しなかった EIP2718 などが考慮されたより具体的な提案となっている Transaction validity, as of Muir Glacier, is defined rigidly by the protocol: ECDSA signature, a simple nonce, and account balance. Account abstraction extends the validity conditions of transactions with the execution of arbitrary EVM bytecode (with some limits on what state may be accessed.) To signal validity, we propose a new EVM opcode PAYGAS, which also sets the gas price and gas limit the contract is willing to pay.
新しいトランザクションタイプとともに PAYGAS という新しい opcode を導入し、PAYGAS の実行を境に EVM 処理のルールを切り分ける
PAYGAS 前:verification phase
例外が投げられた場合、トランザクションは不正とみなされる
現行プロトコルでトランザクションの電子署名が不正だった場合と同様の扱い
m0t0k1ch1.icon ここをコントラクトごとに定義できるようにすることで、トランザクション検証処理を抽象化する
m0t0k1ch1.icon いくつかの制約(ex. 実行可能な opcode が限られている)がある
例えば、外部アカウントのステートを参照を可能にしてしまうと以下のようなことができてしまう
if FOO.get_number() != 5: throw() のような検証処理を有したアカウントを target として大量の AA トランザクションがブロードキャストされた(この時点では FOO.number は 5 だったとする)後に、別のトランザクションで FOO.number を別の値に更新し、上記 AA トランザクションを全て無効化する
PAYGAS 後:execution phase
例外が投げられた場合でも、トランザクション手数料が発生する
マイナーはそのような場合でもブロックに含めることができる
m0t0k1ch1.icon PAYGAS で設定された gas_price と gas_limit を基準として従来と同様の処理が行われる
AA を single-tenant AA と multi-tenant AA に切り分けて考える
ユーザー数の少ないウォレットなどは signle-tenant AA の範囲、ユーザー数の多い tornado.cash や Uniswap のようなアプリケーションは multi-tenant AA の範囲
We split account abstraction into two tiers: single-tenant AA, which is intended to support wallets or other use cases with few participants, and multi-tenant AA, which is intended to support applications with many participants (eg. tornado.cash, Uniswap).
m0t0k1ch1.icon 複数ユーザーによって同一アカウントのステートが更新されるようなケースの AA(multi-tenant AA)は扱いが難しいため、上記のように切り分けて、まずは単一ユーザーによるステート更新のみを考えればよいようなケースの AA(single-tenant AA)から始めましょう、というスタンスぽい
m0t0k1ch1.icon single-tenant AA は AA_PREFIX などを用いて AA トランザクションのみをサポートすればよいが、multi-tenant AA は従来形式のトランザクションもサポートする必要がある
モチベーション
既存の制約によって、以下のようなイノベーションが妨げられている
ECDSA 以外(ex. シュノア、BLS、ポスト量子暗号)の署名検証が可能なコントラクトウォレット
資金の紛失・盗難といったリスクを軽減するような機能(ex. マルチシグ、ソーシャルリカバリー)を有したコントラクトウォレット
tornado.cash のようなプライバシー保護システム
高次な条件(ex. マッチング可能な注文が存在する)を満たさないトランザクションがチェーンに含まれないようにすることによる、DeFi プロトコルのガス効率改善
ETH 以外のトークンによるトランザクション手数料支払い
トランザクション処理の中でリアルタイムにトークンを ETH に変換することで実現するなど
仲介システムに支払われる余分な 21,000 gas は技術的に非効率
仲介システムは、上記 gas を考慮した上で利益をあげる必要があるため、経済的に非効率
m0t0k1ch1.icon 実際にユーザーが支払う gas は 21,000 よりも多くなってしまう
詳細
EIP2718 に準拠した AA_TX_TYPE(2)という新しいトランザクションタイプの導入 このタイプのトランザクションを AA トランザクションと呼ぶこととする
AA トランザクションのペイロードは rlp([nonce, target, data]) という形式で表現される
AA トランザクションの基本 gas コストは AA_BASE_GAS_COST(15,000)とする
電子署名やその検証処理が必須ではないため、21,000 より少ない
AA トランザクションの nonce は既存のトランザクションと同様に処理される
m0t0k1ch1.icon EIP86 では nonce の検証まで抽象化し切ろうとしていたが、まずは single-tenant AA の実現に焦点を当てて方針を変えたぽい AA トランザクションは gas_limit を有さない
gas_limit は、単純にブロック内の残 gas(既にブロックに含められたトランザクションが消費した gas を block.gas_limit から差し引いたもの)に設定される
以下で説明する PAYGAS opcode によって gas_limit を引き下げることは可能
新しい(トランザクション単位での)グローバル変数の導入
globals.transaction_fee_paid
type:bool
false if type(tx) == AA_TX_TYPE else true
globals.gas_price
type:int
0 if type(tx) == AA_TX_TYPE else tx.gas_price
globals.gas_limit
type:int
0 if type(tx) == AA_TX_TYPE else tx.gas_limit
NONCE(0x48)という新しい opcode の導入
nonce をスタックにプッシュする
m0t0k1ch1.icon verification phase で nonce を検証できるようにするため
PAYGAS(0x49)という新しい opcode の導入
スタックのトップから 2 つの引数(version_number と memory_start)をとる
memory_start で指定されたメモリ領域から gas_price と gas_limit を読み出す
m0t0k1ch1.icon トランザクション自体に設定しなくなった代わりに
以下の条件が全て満たされているかを確認する
アカウントの残高が gas_price * gas_limit 以上である
globals.transaction_fee_paid == false
最上位 AA 処理フレームの中にいる
現在実行している EVM 処理が exit や revert した場合、トランザクションの EVM 処理全体が終了する
上記の条件が全て満たされている場合に以下の処理を行う
アカウントの残高から gas_price * gas_limit を差し引く
globals.transaction_fee_paid に true を設定する
globals.gas_price に gas_price を設定する
globals.gas_limit に gas_limit を設定する
現コンテキストの remaining_gas を更新する
gas_limit から既に消費した分の gas を差し引いた値を設定する
参照
---.icon
m0t0k1ch1.icon まだ現実的な提案とは言い難いが、single-tenant AA と multi-tenant AA に切り分けて整理が進んだのは重要と思う
m0t0k1ch1.icon 要件も難易度もかなり異なるので、multi-tenant AA は single-tenant AA の延長線上で考えない方がよいような気がする
m0t0k1ch1.icon single-tenant AA の実現に特化していいなら着地しそう