はじめに

初めまして。 CryptoGamesというブロックチェーンゲーム企業でエンジニアをしている cardene(かるでね) です! スマートコントラクトを書いたり、フロントエンド・バックエンド・インフラと幅広く触れています。

代表的なゲームはクリプトスペルズというブロックチェーンゲームです。

今回は、二つの新しいEVM命令AUTHとAUTHCALLを導入し、スマートコントラクトにEOAの制御を委任できるようにする仕組みを提案しているEIP3074についてまとめていきます!

以下にまとめられているものを翻訳・要約・補足しながらまとめていきます。

他にも様々なEIPについてまとめています。

概要

EIP(Ethereum Improvement Proposal、イーサリアム改善提案)におけるこの提案は、EVM(Ethereum Virtual Machine、イーサリアム仮想マシン)に新たな命令セット「AUTH」と「AUTHCALL」を導入することを提案しています。 ここでの目的は、外部所有アカウント(EOA)の制御をスマートコントラクトに委譲する機能を追加することです。

  • AUTH
    • この命令は、ECDSA(Elliptic Curve Digital Signature Algorithm、楕円曲線デジタル署名アルゴリズム)署名に基づいて「authorized」というコンテキスト変数を設定します。
    • 署名が検証されると、その結果に基づいてauthorized変数が設定されます。
    • これにより、署名者が認証されたことがEVMに知らされます。

楕円曲線デジタル署名アルゴリズム(ECDSA)は、デジタル署名を生成するための一般的な方法の一つで、特に暗号通貨やセキュリティが要求される通信でよく使用されます。 ECDSAは、楕円曲線暗号を基にしたアルゴリズムであり、公開鍵暗号方式の一種です。

楕円曲線とは

楕円曲線とは、特定の代数的方程式で定義される曲線です。 ECDSAで使用される楕円曲線は、以下のような形の方程式で表されます。

y2=x3+ax+by^2 = x^3 + ax + b

ここで、aa と bb は定数で、この曲線上の点が演算の基盤となります。

ECDSAの主要なステップ

  1. 鍵の生成

    • 秘密鍵
      • ランダムに選ばれる数値。
    • 公開鍵
      • 楕円曲線上の点で、秘密鍵から算出される。
  2. 署名の生成

    • メッセージからハッシュ値を計算します。
    • 秘密鍵とハッシュ値を用いて、署名(通常は2つの数値のペア)を生成します。
    • この署名過程では、楕円曲線上での点の加算と乗算が用いられます。
  3. 署名の検証

    • 送信者の公開鍵とメッセージのハッシュ値、および受信した署名を使用して、署名が有効であるかを検証します。
    • 正しい公開鍵と署名が与えられれば、計算は元のハッシュ値を再生し、これによりメッセージの真正性が保証されます。

ECDSAの利点

  • セキュリティ
    • 比較的小さい鍵長でも高いセキュリティを提供します。
  • 効率
    • 他の暗号方式に比べて計算効率が良い場合があります。

使用例

ビットコインやイーサリアムなどの多くの暗号通貨で、トランザクションの認証や秘密保持のためにECDSAが使用されています。

ECDSAはそのセキュリティと効率から、現代のデジタルセキュリティ環境において重要な役割を担っています。

  • AUTHCALL
    • この命令は、認証されたアカウントとして別のアドレスにコール(関数呼び出しやトランザクション実行など)を行うことができます。
    • 実質的に、AUTHCALLはAUTHで設定された認証情報を使用して、認証されたアカウントの代わりに操作を行うことができるようにします。

この機能により、スマートコントラクトはユーザーの許可を得てそのユーザーのアカウントで特定のアクションを実行することが可能になります。 これは、ユーザーが直接トランザクションに署名する代わりに、信頼できるスマートコントラクトがユーザーの代理として機能する新たなパラダイムを開くことを意味します。

このような機能は、DeFiや金融サービスでの利便性とセキュリティの向上に寄与する可能性がありますが、認証メカニズムやスマートコントラクトのセキュリティ設計には細心の注意が必要です。

動機

このEIP(イーサリアム改善提案)は、外部所有アカウント(EOA)の機能を拡張するという長年の要求に対する新しいアプローチを提案しています。 これまでの要求には、トランザクションのバッチ処理、ガススポンサーシップ、有効期限の設定、スクリプトの実装などが含まれており、これらの追加はプロトコルの複雑さが増し、新しい要件や変更に対応することが困難になります。 また、攻撃対象領域の増加も意味している場合があります。

この提案は、これらの機能をトランザクションの有効性要件としてプロトコルに固定するのではなく、ユーザーが自身のEOAの制御をスマートコントラクトに委譲できるようにすることで、開発者にEOAのための新しいトランザクションスキームを開発するための柔軟なフレームワークを提供します。 このEIPの魅力的なユースケースの一つは、EOAがスマートコントラクトウォレットのように振る舞えるようになることであり、これにより新たなコントラクトを展開する必要がなくなります。

さらに、このEIPの主要な動機の一つは「スポンサードトランザクション」です。 これは、トランザクションのガス代をトランザクションを実行するアカウントとは異なるアカウントが支払う場合を指します。

スポンサードトランザクションについては以下の記事を参考にしてください。

イーサリアムのブロックチェーン上でトークンを使用する場合、通常はトランザクション(送金やスマートコントラクトの実行など)を行うためにガス料金が必要です。 このガス料金はETHで支払われます。 しかし、多くのユーザーはETHを持っていない状況で、ETH以外の価値あるトークン(例えばERC20トークン)を持っている場合があります。

ERC20については以下の記事を参考にしてください。

問題点

ユーザーがETHを持っていない場合、彼らが持っている他のトークンをETHに変換してガス料金を支払う必要があります。 しかし、この変換自体もトランザクションを必要とするため、ETHがないとトークンをETHに変換すること自体ができません。 これが循環依存の問題です。

スポンサードトランザクションの解決策

スポンサードトランザクションは、この問題を解消するために提案されました。 これは、ユーザーがトランザクションを実行する時に、自分でガス料金を支払う代わりに、別のアカウント(スポンサー)がガス料金を支払う仕組みです。 スポンサーがガス料金を支払うことで、ユーザーは自分の持っているトークンをETHに変換することなく、トランザクションを実行できます。

利点

  • アクセシビリティの向上
    • ETHを持っていないユーザーも、トランザクションを行うことができるようになります。
  • 柔軟性
    • 異なる種類のトークンを持っているユーザーが、ETHの保有なしにイーサリアムのプラットフォームを利用できるようになります。

このようにスポンサードトランザクションは、ユーザーがイーサリアム上での活動をより自由に行えるよう支援し、イーサリアムエコシステムの利用者基盤を拡大する手助けとなります。

このEIPにより、ユーザーはスポンサーになることで、自分のトランザクションに必要なガス料金を支払わなくても、別のアカウントがその料金を負担することができるようになります。 これにより、資金が限られているユーザーや新規ユーザーもイーサリアムプラットフォームをより簡単に利用できるようになります。

仕様

規則(Conventions)

  • top - N
    • EVMスタック上で、最も最近にプッシュされた値からN番目の値を指します。
    • ここで、top - 0は最も最近の値です。
  • ||
    • バイトの連結演算子です。
  • invalid execution
    • 実行が無効であり、現在の実行フレームを直ちに終了し、残りのガスをすべて消費します(スタックアンダーフローや無効なジャンプと同じ方法で)。

定数(Constants)

Constant Value
MAGIC 0x04
  • MAGIC
    • EIP3074署名で使用される定数で、他の署名形式との署名衝突を防ぐために用います。

コンテキスト変数(Context Variables)

Variable Type Initial Value
authorized address unset
  • authorized
    • 現在の実行フレームでのAUTHCALL命令のためのアクティブなアカウントを示します。
    • 設定されている場合、authorizedにはそのコントラクトに代わって行動する許可を与えたアカウントのみが含まれます。
    • 未設定の場合、まだアクティブなアカウントが設定されておらず、AUTHCALL命令には使用できません。

コンテキスト変数のスコープ

  • authorizedはプログラムカウンタと同じスコープを持ち、一つの実行フレーム内で持続しますが、任意のコール(DELEGATECALLを含む)を通じて渡されません。
  • 同じコントラクトが異なる実行フレームで実行される場合(例えば、自己へのCALL)、各フレームは独立したauthorizedの値を持ちます。
  • 実行フレームが開始される時、authorizedは常に未設定の状態からスタートします。
    • これは、以前の実行フレームで値が設定されていたとしても変わりません。

このEIPの導入により、スマートコントラクトはより柔軟にEOAの代わりに動作することが可能になり、ユーザーに代わって特定の操作を許可する新しい方法を提供します。

AUTH (0xf6)

新しいオペコード AUTH (0xf6) についての説明です。 この命令はEVM(イーサリアム仮想マシン)のスタックから3つの要素を入力として受け取り、1つの要素を出力として返します。 この命令の目的は、特定の署名が正当であるかを検証し、検証が成功した場合には authorized というコンテキスト変数を設定することです。

入力

AUTH 命令は以下のスタック要素を入力として受け取ります。

Stack Value
top - 0 authority
top - 1 offset
top - 2 length

また、メモリの特定範囲を指定します。 その範囲は以下のフォーマットでデータを含みます。

  • yParity
    • memory[offset : offset+1]
  • r
    • memory[offset+1 : offset+33]
  • s
    • memory[offset+33 : offset+65]
  • commit
    • memory[offset+65 : offset+97]

この命令はECDSA(Elliptic Curve Digital Signature Algorithm)署名を検証するために、メモリから特定のデータを読み込みます。

メモリレイアウト

yParity
  • アドレス
    • memory[offset : offset+1]

署名の yParity 値を含みます。 これはECDSA署名における公開鍵のY座標が奇数か偶数かを示す値(0または1)です。 これは公開鍵の回復に使われます。

r
  • アドレス
    • memory[offset+1 : offset+33]

署名の r 成分を含みます。 これは署名生成過程において得られる値で、署名の有効性検証に使用されます。

s
  • アドレス
    • memory[offset+33 : offset+65]

署名の s 成分を含みます。 これも署名の一部で、r と合わせて署名の正当性を確認するのに必要です。

commit
  • アドレス
    • memory[offset+65 : offset+97]

追加のデータを含む32バイトの値で、特定の条件やコンテキストにおける署名の妥当性を確認するために使用されます。 この値は、契約が事前に定義された特定の条件に従って操作を行っていることを「証明」するのに役立ちます。

使用目的

この命令は、トランザクションやコントラクト間の相互作用において、特定のアカウントが行動を許可したことを確認するために使用されます。 たとえば、ユーザーがスマートコントラクトに特定の操作を代行させたい場合に、この署名を使ってその許可が正当であることを証明できます。署名が正しく、指定されたパラメータが予期された値であることが確認できれば、authorized 変数が設定され、スマートコントラクトはそのアカウントの代わりに行動することが許可されます。

出力

出力はスタックに戻され、以下のようになります。

Stack Value
top - 0 success

メモリはこの命令によって変更されません。

振る舞い

署名の内容と検証

AUTH 命令は以下の情報を使用してECDSA署名を検証します。

  • yParity, r, s
    • secp256k1 曲線上でのECDSA署名の要素です。

署名対象のメッセージは keccak256(MAGIC || chainId || nonce || invokerAddress || commit) です。

  • MAGIC
    • 署名の一意性を保証するための定数(0x04)。
  • chainId
    • 現在のチェーンの一意の識別子で、32バイトにパディングされます。
  • nonce
    • 署名者の現在のnonceで、32バイトに左詰めでパディングされます。
  • invokerAddress
    • AUTH 命令を実行しているコントラクトのアドレスで、32バイトまで0でパディングされます。
  • commit
    • 呼び出し側のロジックにおける特定の追加の有効性条件にコミットするための32バイト値。
署名の検証結果に基づく振る舞い

署名が有効で署名者のアドレスが authority アドレスと一致する場合、authorized 変数は authority アドレスに設定されます。 署名が無効または署名者のアドレスが authority と一致しない場合、authorized は未設定(リセット)されます。 AUTH は、authorized が設定されていれば1を返し、そうでなければ0を返します。

ガスコスト

AUTH のガスコストは以下の要素から構成されます。

  • 固定料金
    • 3100(ecrecover プリコンパイルのコストとほぼ同等で、さらに keccak256 ハッシュと追加ロジックのコストが含まれます)。
  • メモリ拡張ガスコスト (auth_memory_expansion_fee)
    • 指定されたメモリ範囲が現在の割り当て外にある場合、メモリが拡張されたときのコストです。
  • authority がメモリに既に読み込まれている(warm)場合は100、そうでなければ(cold)2600(EIP2929に基づく)。

EIP2929については以下の記事を参考にしてください。

このオペコードは、スマートコントラクトが特定のアカウントの代わりに行動する許可を確認するために非常に重要であり、Ethereumのセキュリティと柔軟性を向上させる目的があります。

AUTHCALL (0xf7)

新しいオペコード AUTHCALL (0xf7) は、Ethereum Virtual Machine (EVM) における既存の CALL (0xF1) 命令と似た振る舞いをする命令ですが、いくつかの点で異なります。この命令は、スタックから7つの要素を入力として取り、1つの要素を出力として返します。AUTHCALL は、既に AUTH 命令によって設定された authorized アカウントとして動作することが特徴です。

入力

AUTHCALL 命令は以下のスタック要素を入力として受け取ります。

Stack Value
top - 0 gas
top - 1 addr
top - 2 value
top - 3 argsOffset
top - 4 argsLength
top - 5 retOffset
top - 6 retLength

説明

  • gas
    • 呼び出しに割り当てられるガス量。
  • addr
    • 呼び出すコントラクトのアドレス。
  • value
    • 送信するETHの量。
  • argsOffset
    • メモリ内の引数の開始位置。
  • argsLength
    • 引数の長さ。
  • retOffset
    • メモリ内の戻り値の開始位置。
  • retLength
    • 戻り値の長さ。

出力

出力はスタックに戻され、以下のようになります。

Stack Value
top - 0 success

振る舞い

AUTHCALL は、既存の CALL 命令に似ていますが、いくつかの違いがあります。 この命令は、特定のアカウントが authorized として設定されている場合に、そのアカウントの権限で別のコントラクトを呼び出すことができます。

主な違いと動作の詳細
  1. authorizedの確認

    • authorized が設定されていない場合、実行は無効です。
    • これは、AUTHCALL が有効に機能するためには、authorized が事前に AUTH 命令などによって設定されている必要があるためです。
  2. 呼び出しアドレスの設定

    • 呼び出し元のアドレスは、authorized に設定されたアドレスになります。
    • これにより、authorized アカウントが他のコントラクトに対して直接行動を起こすかのように操作が行われます。
  3. ガスコストとガス供給

    • ガスの計算は CALL 命令と同様ですが、ガスオペランドが0の場合は、EIP150に従い利用可能なガス全てが送られます。
    • 利用可能なガスがオペランドで指定されたガスより少ない場合は、実行は無効です。

EIP155については以下の記事を参考にしてください。

  1. 送金とバランスの確認

    • value は authorized アカウントのバランスから差し引かれます。もし value が authorized のバランスを超えている場合、実行は無効です。
    • ガス手当(stipend)は提供されません。
    • これは、非ゼロの値が送金される場合でも適用されます。
  2. コール深度の増加

    • AUTHCALL はコール深度を1だけ増加させます。
    • authorized アカウントを経由してターゲットにコールするのではなく、直接ターゲットにコールするため、コール深度が2増加することはありません。

コール深度(call depth)は、Ethereum Virtual Machine (EVM) におけるトランザクション実行時のコンテキストスタックの深さを表します。 これは、スマートコントラクトが他のコントラクトを呼び出す際に重要となる概念です。

コール深度とは何か?

EVMにおいて、トランザクションがスマートコントラクトを実行すると、最初の実行レベルが開始されます。 この時点でのコール深度は0です。 スマートコントラクトが他のコントラクトを呼び出すたびに、新しい実行フレームがスタックにプッシュされ、コール深度が1増加します。 つまり、あるコントラクトが別のコントラクトを呼び出すと、コール深度は1になり、その呼び出されたコントラクトがさらに別のコントラクトを呼び出すと、コール深度は2になる、という具合です。

コール深度の上限

EVMでは、コール深度の上限が1024に設定されています。 この限界を超えると、その呼び出しは単に失敗し、実行されないことになります。 この規則は、スタックオーバーフロー攻撃などのセキュリティリスクを防ぐために設けられています。

コール深度の影響

コール深度は、特にガスの消費やトランザクションの複雑性に影響を与えます。 深いコールチェーンは、それぞれのレベルでガスを消費し、トランザクションのコストを増大させます。 また、深いコールチェーンを持つトランザクションは、エラーの発生やデバッグの難しさを増す可能性があります。

コール深度の管理

スマートコントラクトを設計する時には、コール深度を適切に管理することが重要です。 特に、複数のコントラクト間で相互に呼び出しを行うような設計の場合、予期せぬ深さまでコールが続くことがあり、それによりトランザクションが失敗するリスクが高まります。 したがって、可能な限りフラットな構造を保持し、不要な外部呼び出しを避けることが望ましいです。

  1. 戻りデータの取り扱い

    • RETURNDATASIZE と RETURNDATACOPY によってアクセスされる戻りデータエリアは、CALL 命令と同じ方法で設定されます。
  2. authorizedのリセット

    • 重要な点として、AUTHCALL の実行後に authorized はリセットされず、変更されないまま残ります。

これらの特徴により、AUTHCALL はスマートコントラクトが他のアカウントの権限を借りて操作を行うことを可能にし、複雑な交渉や条件付きの取引を実行するための柔軟性を提供します。

ガスコスト

AUTHCALL のガスコストは、いくつかのコンポーネントの合計で構成されます。 これには静的なガスコスト、メモリ拡張に関連するガスコスト、動的なガスコスト、およびサブコール実行に使用可能なガスが含まれます。

ガスコストの計算
  • 静的ガスコスト (warm_storage_read)

    • これは、既にアクセスされたアドレスやデータを読み取るために必要な基本的なガスコストです。
  • メモリ拡張ガスコスト (memory_expansion_fee)

    • CALL 命令と同じ方法で計算され、メモリの使用量が増加する場合に追加のガスコストが発生します。
  • 動的ガスコスト (dynamic_gas)

    • 初期値は0ですが、以下の条件によって増加します。
      • 対象のアドレス addr が以前にアクセスされていない場合(cold_account_access)、動的ガスコストに2500が加算されます。
      • 送金額 value が0より大きい場合、6700が加算されます。
      • さらに、対象のアドレスが空(コントラクトがデプロイされていない)である場合は、25000が加算されます。
  • サブコールで実行可能なガス (subcall_gas)

    • 利用可能なガスから動的ガスコストを差し引いた残り (remaining_gas) から、その1/64を除いた量 (all_but_one_64th) を計算します。
    • もし gas オペランドが0であれば、subcall_gas は all_but_one_64th 全量に設定されます。
    • これはEIP150に基づき、サブコールに可能な限り多くのガスを割り当てるためです。
    • gas オペランドが0ではなく、all_but_one_64th が gas より少ない場合、実行は無効となりエラーが発生します(例外が投げられます)。
    • それ以外の場合、subcall_gas は gas に設定されます。

Ethereum Virtual Machine(EVM)におけるgasオペランドは、スマートコントラクトの実行時に非常に重要な役割を果たします。 gasはEthereumネットワークにおける計算資源の消費を制御し、スマートコントラクトの実行に必要な計算やストレージ操作に対する料金をユーザーが支払う方式です。 各トランザクションや関数呼び出しにおいて、実行に必要なgasの量を指定することで、その操作がどれだけの計算リソースを消費するかを制御します。

gas オペランドの概要

gasオペランドは、スマートコントラクトの各命令が実行される際に消費されるgasの量を指定します。 これにより、トランザクションの実行コストと時間を管理し、ネットワークの過負荷を防ぎます。 gasの料金は、gasの価格(gas price)と消費されたgasの量に基づいて計算されます。 トランザクションを送信する時、ユーザーはgas priceを指定することができ、これによりトランザクションの優先度が決定されます。

gas オペランドの使用方法

トランザクションのgas

トランザクションを送信する時、gas limit(トランザクションによって消費される最大のgas量)とgas price(単位gasあたりの料金)を設定します。 gas limitはそのトランザクションが消費可能なgasの上限を示し、これを超えるとトランザクションは「Out of Gas」エラーになります。

関数呼び出しのgas

関数を呼び出す時にも、どれだけのgasを割り当てるかを指定できます。 特に重要なのは、他のコントラクトを呼び出す際や複雑な計算を行う場合です。

gas オペランドの重要性

  • セキュリティ
    • gasシステムにより、悪意のあるユーザーやバグを持つコントラクトによる無限ループや過度の計算が防がれ、ネットワークの安全性が保たれます。
  • 効率
    • gasを使用することで、ブロックチェーンの各ノードがどれだけの計算を行うべきかを予測でき、システムの全体的な効率が向上します。
  • エコノミクス
    • gasはEthereumネットワークの経済システムの一部であり、マイナーにとっての報酬となり、ネットワークの維持・運営を動機付けます。

gas オペランドの理解と適切な管理は、Ethereum上で効果的かつ経済的にスマートコントラクトを運用するために不可欠です。

ガスコストの請求

CALL 命令と同様に、AUTHCALL でもガスコストはコールが実際に実行されるかどうかにかかわらず、直ちに全額が請求されます。 これは、EVMがサブコールを行う前に必要なガスを保証するためです。

これらのルールにより、AUTHCALL はガスの使用とコールの管理を厳密に行いながら、authorized アカウントの権限の下で他のコントラクトを呼び出すことが可能になります。 これによって、スマートコントラクトが他のアカウントの資源を効果的に利用し、複雑なインタラクションを行う能力が強化されます。

補足

署名形式とメモリの利用

署名形式の柔軟性

AUTH 命令が動的なメモリ範囲を受け入れるのは、将来的にコントラクトアカウント(非ECDSA署名を使用する可能性がある)にも対応可能にするためです。 現在は外部所有アカウント(EOA)のみがサポートされていますが、これにより将来的に異なる署名スキームに対応できるようになります。

署名アドレスの扱い

authority引数の含意

authority(署名アドレス)を AUTH 命令の引数として含めることで、将来のアップグレード時にコントラクトアカウントとEOAの両方に対応できるように設計されています。 複数の署名スキームが許可される場合、署名だけから承認アカウントのアドレスを計算することは不可能になります。このため、authority は署名者のアドレスを指定するために必要です。

利用可能なガスの割当て

利用可能なガスの予約

AUTHCALL はEIP150に従って、利用可能なガスの63/64以上をサブコールに渡すことはありません。 これは、ガスの消費を制御し、呼び出しの深さによる問題を避けるためです。

authorized 未設定時の処理

未設定の authorized に対するエラー処理

コントラクトが AUTHCALL を実行する前に authorized が正しく設定されているべきです。 authorized が設定されていない状態で AUTHCALL を実行しようとすると、現在の実行フレームを直ちに終了させるのが最も安全な振る舞いです。 この振る舞いは、トランザクションのスポンサー/中継に関連して特に重要であり、スポンサーと受け手(sponsee)の間で責任を明確に区別する必要があります。 誤ったサブコールや AUTH の失敗など、スポンサーに起因する問題が受け手に不公平な料金を課すことを防ぐためです。

新しいトランザクションタイプの導入

このアプローチでは、新しいトランザクションタイプを導入して、手数料の支払いを行うアカウントと実際のアクションを起こすアカウントを分離します。 この方法はクライアントの大規模な変更を必要とし、アップグレードが他のソリューションよりも困難です。 アカウント抽象化(Account Abstraction, AA)との互換性がすぐには得られないという問題もあります。 AAコントラクトはプライベートキーを持たないため、スポンサーのアカウントからの署名済みトランザクションを発行することができません。 新しいトランザクションタイプの主な利点は、有効性要件がプロトコルによって強制されるため、無効なトランザクションがブロックスペースを汚染しないことです。

ERC4337については以下の記事を参考にしてください。

EVM内での新メカニズムの導入

このアプローチでは、EVMに新しいメカニズムを導入して、他のアカウントとして動作する機能(masquerade)を提供します。 AUTHとAUTHCALLは、外部所有アカウント(EOA)としてコールを行う機能を実現します。 これは、コントラクトアカウントがより直接的にETHを送受信できるようにするなど、将来の展開に対する即時の利点があります。 この方法は、新しいトランザクションタイプを導入するよりも侵襲性が低く、既存のウォレットやその他のツールに対する変更が少なくて済みます。 AUTHCALLのCALLからの唯一の逸脱は、CALLERを設定することであり、スポンサードトランザクションのための送信者抽象化を実現する最小限の機能を実装します。

署名と信頼性

初期の提案とその問題点

最初の提案では、ノンス(トランザクションごとに一意に増加する数値で、トランザクションの一意性を保証する)を追跡するために、プリコンパイルされた(つまり、ブロックチェーンに予め組み込まれた)ストレージを持つスマートコントラクトの使用が検討されました。 しかし、この方法はEthereumにとって前例のないものであり、技術的な複雑さやセキュリティリスクが懸念されました。

変更されたアプローチ

これらの問題を解決するため、リプレイ保護の機能は個々の契約者(invoker)に委ねることになりました。 これにより、ノンスの管理は各invokerコントラクトが行うことになり、システム全体としての複雑さを軽減します。

ユーザーとinvokerの信頼関係

署名とinvokerの結びつき

ユーザーがトランザクションに署名する時には、その署名が特定のinvokerにのみ関連付けられるようになっています。 これは、署名が特定のコントラクトのコンテキスト内でのみ有効であることを意味し、他のinvokerがその署名を不正利用することを防ぎます。

ユーザーの安心感

ユーザーは、自分が信頼するinvokerを選択することができ、そのinvokerがトランザクションを適切に管理し、自分の意図した通りにトランザクションが実行されることを信頼できます。 これにより、ユーザーは自分のトランザクションが正確に処理されることを確信できます。

このように、スポンサードトランザクションにおいてリプレイ保護(既に実行されたトランザクションが再び悪意を持って実行されることを防ぐためのメカニズム)の管理は、よりシンプルでセキュリティが確保された方法へと進化しています。 ユーザーは特定のinvokerとの関係を通じて、自分のトランザクションの安全を確保することができるようになりました。

Commit 機能の理解

コミットの役割

ユーザーは特定のトランザクション(またはコール)のプロパティ(例えば、送金額やガス量など)に対して「コミット」します。 これは、トランザクションの特定の詳細に対するハッシュ値を計算することによって行われます。 このハッシュ値(コミット値)は、トランザクションが実行される前にその値が検証され、承認されることをユーザーが保証するために使用されます。 これにより、リプレイ攻撃などに対する保護が可能になります。

拡張可能性

コミット機能を使用することで、インボーカー(呼び出しを管理するコントラクト)は任意の制約を実装することができます。 例えば、複数のノンスを並行して管理することや、単一の署名で複数のコールにコミットすることが可能です。 これにより、複数のトランザクションフローを単一のトランザクションにまとめることができ、例えばERC20のapproveとtransferを一つの署名で実行できるようになります。

Invoker Contracts

インボーカーコントラクトの役割

インボーカーコントラクトは、スポンサーとスポンシー(手数料の支払いを受ける側)の間の信頼できる中間者として機能します。 スポンシーは、信頼できる特定のコントラクトだけが自分のトランザクションを処理するように要求するために、インボーカーに署名します。 これにより、スポンシーはスポンサーを信頼する必要なく、安全にトランザクションを実行することができます。

セキュリティ上の配慮

インボーカーコントラクトは、アップグレード可能であってはならず、一度デプロイされたコードは変更されるべきではありません。 アップグレード可能なインボーカーは、悪意のあるコードに置き換えられるリスクがあり、セキュリティ上の脆弱性を引き起こす可能性があります。

コール深度とガスの管理

EVMはネストされたコールの最大数を制限しており、スポンサーがコール深度を操作してインボーカーに到達する前に深度を増加させることは、スポンシーに対する妨害攻撃となり得ます。 しかし、63/64のガスルールとAUTHCALLのコストを考慮すると、実際のコールスタックはガスパラメータによってかなり制限されます。 したがって、インボーカーは最小限のガス量を保証するだけで十分であり、合理的なガス量ではハードマキシマムのコール深度に到達することはありません。

途中でのEOAからの値の控除

トランザクションプールの不変性

以前は、トランザクション実行中に外部所有アカウント(EOA)から値を控除することが問題視されていました。 これは、トランザクションプールがトランザクションの有効性を静的に決定できるという不変性に基づいています。

不変性の破壊

さらなる調査により、この不変性を破っても安全であることが判明しました。 特に、攻撃者が多数のトランザクションをキューに入れ、それらを一度に無効にする攻撃が理論的には可能ですが、ネットワーク全体に対する実質的な影響は小さいため、問題視されていません。

tx.origin を署名者として許可

tx.origin を署名者として許可する利点

トランザクションバッチ処理の簡素化

tx.originをauthorizedと等しく設定することで、外部トランザクションの送信者が署名アカウントとなります。 これにより、例えばERC20トークンの承認(approve)とその後の転送(transfer)を別々のトランザクションで行う必要がなくなり、一つのトランザクションで完了できるようになります。

tx.origin 使用に関するセキュリティ上の懸念

スマートコントラクトへの影響

EIP3074により、AUTHおよびAUTHCALLを通じてmsg.sender == tx.originが複数の実行層で成立する可能性があります。 これは通常、トランザクションの最上位層でのみ発生する状況で、require(msg.sender == tx.origin) チェックを含むスマートコントラクトに影響を与えます。

セキュリティチェックの使用例
  • EOA確認
    • msg.senderがEOAであることを確認するために使用されます。
    • このチェックは、実行層の深さに依存しないため、この提案によって影響を受けません。
  • アトミックサンドイッチ攻撃防止
    • このような攻撃は、ターゲットコントラクトの実行前後に状態を変更することに依存します。
    • このEIPによりこの保護が破られる可能性がありますが、tx.originをこのように依存することは一般的に悪い実践と見なされています。
    • リエントランシー防止
      • この提案は、特にこの形式のリエントランシー保護に影響を与える可能性がありますが、この形式の保護を使用している例は見つかっていません。

解決策と軽減策

他のアプローチ

tx.originを定数のENTRY_POINTアドレスやinvokerアドレスに設定する。 tx.originを送信者、invoker、または署名者のアドレスから導出された特別なアドレスに設定する。 authorized == tx.originを禁止する(ただし、将来的にはこの制限を緩和する可能性がある)。

これらのポイントは、tx.originを使用することの潜在的な利点とリスクを総合的に評価するために重要です。

セキュリティリスクと対策

atomicサンドイッチ攻撃

tx.origin の使用は、atomicサンドイッチ攻撃(特定のコントラクトの前後で状態を変更する攻撃)に対する保護を弱める可能性がありますが、これは一般的に悪い実践と見なされています。

「アトミックサンドイッチ攻撃」は、ブロックチェーンおよびスマートコントラクトのセキュリティに関連する特定のタイプの攻撃手法です。 この攻撃は、特にEthereumのようなプラットフォームで見られる問題で、攻撃者が特定のトランザクションの前後で自分のトランザクションを挿入することによって、ターゲットとなるトランザクションの結果を操作します。

アトミックサンドイッチ攻撃の仕組み

  1. トランザクションの観察

    • 攻撃者は、ブロックチェーンネットワーク上で特定のトランザクションを観察します。
    • これは通常、大きな資産の移動や重要なコントラクト関数の実行を伴うトランザクションです。
  2. アトミックな挿入

    • 攻撃者は、対象となるトランザクションの直前に自分のトランザクションを配置し、対象トランザクションの直後にもう一つのトランザクションを配置します。
    • これにより、攻撃者は対象トランザクションの実行環境を事前に操作し、実行後の状態も利用できるようになります。
  3. 状態の操作

    • 最初のトランザクションで、攻撃者はターゲットトランザクションが依存する状態を変更することができます(例えば、市場価格や流動性プールの残高など)。
    • 対象トランザクションが実行された後、攻撃者は再び状態を操作して、元のトランザクションから利益を得るためのアクションを実行します。

アトミックサンドイッチ攻撃の例

価格操作

分散型金融(DeFi)プラットフォームにおいて、攻撃者はスリッページ(価格の滑り)を利用して、ある資産の価格を意図的に上げたり下げたりします。 これにより、その価格変動を利用して不正な利益を得ることが可能になります。

フラッシュローン攻撃

攻撃者はフラッシュローン(短期間に大量の資金を借りることができる仕組み)を利用して大量の資産を借り、市場に影響を与えるトランザクションを挟みます。 その後、資産を返却する前に、市場の操作から利益を得ることができます。

防御策

トランザクション順序のランダム化

マイナーやブロック生成者によるトランザクションの順序をランダムにすることで、このタイプの攻撃の効果を軽減することができます。

スリッページ保護

ユーザーがトランザクションを発行する際に、許容するスリッページの量を設定することで、価格操作の影響を受けにくくすることができます。

アトミックサンドイッチ攻撃は、特にDeFi領域で懸念される問題であり、ユーザーとプラットフォームはこのタイプのリスクを理解し、適切な防御策を講じることが重要です。

再帰性の防止

msg.sender == tx.origin のチェックは再帰的な呼び出しを防ぐために使用されることがありますが、この提案ではその有効性が低下する可能性があります。 しかし、再帰性を防ぐ他の方法が存在します(例えば、ストレージ変数の使用)。

その他の提案された解決策

tx.origin の設定変更

tx.origin を固定のエントリーポイントアドレスやインボーカーアドレスに設定することで、不変性を維持しつつ制限を緩和することが提案されています。

AUTHCALL と CALL の比較

コストの違い

CALL命令で非ゼロの値を送信する場合、そのコストは追加で9,000ガス増加します。 このうち6,700はバランス転送のオーバーヘッドをカバーするため、残りの2,300はサブコールのガスカウンターを種付けするための手当(stipend)として使用されます。 AUTHCALL はサブコールに対して手当を提供しないため、基本的な6,700のみが使用されます。

インプロトコルリボケーション(In-Protocol Revocation)

リボケーションの必要性

AUTHメッセージのリボケーションがない場合、このEIPは開発者にとって非常に強力で柔軟なプリミティブを提供しますが、安全でないまたは悪意のあるインボーカーを使用するユーザーにとってはリスクが伴います。 ユーザーが単一のトランザクションで多くの操作をバッチ処理できる新しい能力により、アカウントから資金が抜かれるリスクが高まります。 このリスクは、プロトコルレベルおよびアプリケーションレベルでのサポートが試みられることにより、このEIPの採用に関わらず増加し続けるでしょう。

リプレイ保護とセキュリティリスク

インボーカーがリプレイ保護を実装している場合、それによってリスクの影響範囲が大幅に制限されるはずです。 しかし、バグが敵にリプレイ保護メカニズムを迂回することを許す場合、それは敵に脆弱なインボーカーと相互作用した任意のEOAへの完全なアクセスを与えるかもしれません。

ノンスとリボケーション

プロトコル内でのリボケーションがないため、ユーザーは自分のアカウントを脆弱なインボーカーから削除する方法がありません。 このため、AUTHはメッセージ内のノンスが署名者の現在のノンスと一致することを要求します。 これにより、EOAからの単一のトランザクションがノンスを増加させ、すべての未処理の承認を無効にします。

互換性

背景

現在のEthereumアカウントモデルには、外部所有アカウント(EOA)とスマートコントラクトアカウントの2種類があります。 EOAはプライベートキーによるECDSA署名で識別され、トランザクションを認証します。

懸念点

将来的なアカウントモデルの変更

このEIPは、ECDSA署名に依存していますが、将来的にはEOAの概念を完全に取り除き、同じ振る舞いをエミュレートするスマートコントラクトウォレットに置き換えることが望ましいかもしれません。 この変更が実施されると、ユーザーはさらに進んで、例えばマルチシグ(複数の署名による認証)など、他の認証方法に「アップグレード」する選択肢を持つことになります。

旧来の認証方法の持続的使用

現在のEIPの実装では、スマートコントラクトウォレットが他の認証メソッドにアップグレードされた場合でも、AUTHは古いプライベートキーによるアクションを許可し続ける可能性があります。 これは、新しいロジックがAUTHによって尊重されないため、セキュリティ上の問題を引き起こす可能性があります。

提案された解決策

AUTHのロジックの修正

EOAsが削除される時に、AUTHのロジックを修正して、アカウントに対して標準的なメッセージを呼び出し、そのアカウントが署名または証人が有効であるかを判断させるようにする提案があります。 これにより、AUTHはアカウントの新しい認証ロジックを尊重することができ、より柔軟で将来に対応した方法で動作する可能性があります。

今後の研究の必要性

この変更がどのようにインボーカーに影響を与えるか、そしてインボーカーを将来にわたってどのように設計するのが最善かについてさらに研究を行う必要があります。 これは、Ethereumのアカウントおよび認証システムの将来の進化に適応するために重要です。

セキュリティ

セキュアなインボーカー

インボーカーはスマートコントラクトを介してユーザーの命令を実行するエンティティですが、セキュリティが確保されていないと大きなリスクを招く可能性があります。

リプレイ保護

インボーカーはリプレイ攻撃を防ぐためにノンスを実装し、コミットに含める必要があります。 これにより、悪意あるアクターが同じ署名を再利用して同じアクションを繰り返すことを防ぎます。

値のコミット:

トランザクションで転送される値(value)はコミットに含めるべきです。 これにより、スポンサーが意図しない効果を引き起こすことを防ぎます。

ガスのコミット

ガス量もコミットに含めることが重要です。 これにより、スポンサーが意図的にガスを使い果たさせてトランザクションを失敗させることを防ぎます。

アドレスとコールデータ

トランザクションの宛先アドレス(addr)とコールデータ(calldata)もコミットに含めるべきです。 これにより、悪意あるアクターが任意の関数を任意のコントラクトで呼び出すことを防ぎます。

tx.origin としての署名者の許可

tx.originをauthorizedと同じに設定することは、以下のリスクを含みます。

atomicサンドイッチ攻撃の防御の破壊

tx.originが署名者として使用されると、atomicサンドイッチ攻撃を防ぐための保護が破壊される可能性があります。 これは、トランザクションの前後で状態を変更する攻撃に対する防御が弱まるためです。

リエントランシー防御の破壊

require(tx.origin == msg.sender)スタイルのリエントランシー防御が破壊される可能性があります。 この提案では、リエントランシー防御に依存しているコントラクトが影響を受ける可能性があります。

スポンサードトランザクションリレイヤー

スポンサードトランザクションリレイヤーは、トランザクションの手数料を代行して支払いますが、以下のリスクがあります。

認証の無効化

承認されたアカウントが自身のノンスを増加させることで認証を無効にし、リレイヤーがガスを無駄に消費させる可能性があります。

資産の払い出し

承認されたアカウントが関連する資産を払い出すことにより、リレイヤーがガスを無駄に使う可能性があります。

これらのリスクを緩和するために、リレイヤーは担保の預入れや評判システムの導入など、潜在的な損失を考慮に入れた設計を検討する必要があります。

最後に

今回は「二つの新しいEVM命令AUTHとAUTHCALLを導入し、スマートコントラクトにEOAの制御を委任できるようにする仕組みを提案しているEIP3074」についてまとめてきました! いかがだったでしょうか?

質問などがある方は以下のTwitterのDMなどからお気軽に質問してください!

他の媒体でも情報発信しているのでぜひ他も見ていってください!