BOOSTRY Tech Blog

株式会社BOOSTRY の技術ブログです

Account Abstraction の提案史と要点まとめ

ethereum.org

こんにちは。BOOSTRY CTO の麻生です。

BOOSTRYでは、さまざまなタイプのウォレットアプリケーションを開発しています。

EVM型のブロックチェーンにおいては、ウォレット実装として、スマートコントラクトによるウォレット実装である「コントラクトウォレット」も選択肢となり得ます。 本記事ではコントラクトウォレットに関連する話題として、EIP-4337の提案を中心に、Account Abstraction(AA)の提案史と要点を整理したいと思います。

なお、本調査は B.O.O.S.T. Lab の活動の一環として実施しました。記載内容は2025/12時点の情報です。

1. Account Abstraction とは?

1-1. EOAとコントラクトアカウント

Ethereumには2種類のアカウントが存在します。

Externally Owned Account (EOA)

Contract Account

  • ETH残高を持つ。
  • コードを持つ。
  • 他アカウントからのトランザクションやメッセージ(call)でコードが実行される。状態更新がある場合は、アカウント専用の永続ストレージが更新される。

1-2. Account Abstraction

Account Abstractionに明確な定義はありませんが、EIP-2938では次のように表現されています。

Account abstraction (AA) allows a contract to be the top-level account that pays fees and starts transaction execution.

一般にAccount Abstractionは、コントラクトをEOAと同様のトップレベルアカウントとして扱えるようにすることを指します。 一見EOAと同等なら必要性が薄く見えますが、主にセキュリティ向上の観点でメリットがあるとされます。 トランザクション処理から署名検証、nonce管理、手数料支払いまでをコントラクトに委ねることで、柔軟な認可ロジックやリカバリーメカニズムを実装できるためです。

2. ウォレットのセキュリティに関する一考察

Vitalik Buterin氏は以下の記事でウォレットセキュリティの現状と課題について見解を述べています。ここではその概要を紹介します。

vitalik.eth.limo

Buterin氏は、ウォレットシステムが目指すべき状態を次のように定義しています。

  • 単一障害点がないこと
  • 精神的負担が小さいこと
  • トランザクション実行ができる限り簡素であること

これらの目標に照らして、各方式について次のように述べています。

ハードウェアウォレットだけでは不十分

  • サプライチェーン攻撃:ハードウェアウォレットを購入することは、設計企業、製造工場、出荷・流通の関係者など多くを信頼することを意味する。ハードウェアは基本的にオープンソースとして監査しにくい。
  • 単一障害点:PINを肩越しに盗み見られ、その後デバイスを盗まれれば資金を奪われうる。バックアップは別の問題を生む。

ニーモニック(復元フレーズ)では不十分

  • ニーモニックはウォレットのルート秘密鍵を人間によって可読な12〜24語で表現したもの。
  • 鍵の紛失には有効だが盗難には無力。ハードウェアのPINまたはニーモニックを盗まれれば資金を盗まれる。また、ニーモニックを誤って紛失しないよう常に気を配る必要があり、精神的負担が大きい。

マルチシグは「まあまあ良い」

  • マルチシグ型ウォレット(コントラクトウォレットを含む)は単一障害点がなく安全だが、万能ではない。例えばラップトップが盗まれれば電話も盗まれる可能性が高い。また、すべてのトランザクションで複数デバイスによる署名が必要になり、利便性が課題となる。

マルチシグ型コントラクトウォレット
https://vitalik.eth.limo/general/2021/01/11/recovery.html

ソーシャルリカバリーは「より良い」

  • ソーシャルリカバリーシステムの特徴
    • トランザクション承認に使う単一の署名鍵が存在する。
    • 複数人のguardians(保護者)を設定し、鍵の変更に多数決を必要とする。
  • guardiansの追加・削除にタイムロック(猶予期間)を設けられる。
  • guardiansの選定例

ソーシャルリカバリーの概念図
https://vitalik.eth.limo/general/2021/01/11/recovery.html

Buterin氏は、AA型のソーシャルリカバリー機能を備えたコントラクトウォレットが、現状の課題に対する最良の解の一つだと述べています。コントラクトウォレット自体のセキュリティなど、解決すべき課題は残りますが、十分に安全性が検証されたコントラクトウォレットを用いることで、EOAベースより高いセキュリティを実現できる可能性がある点は示唆的です。

3. EIP86

eips.ethereum.org

  • Author: Vitalik Buterin
  • Status: 🚧 Stagnant
  • Type: Standards Track
  • Category: Core
  • Created: 2017-02-10

3-1. 仕様

EIP-86は、新しいトランザクション形式とopcodeを導入し、プロトコルの代わりにコントラクトが署名・nonce検証や手数料徴収を担うことでAAを実現しようとしました。 この提案は最終的に採用されず、現在はStagnantです。

(1) 新しいトランザクション形式の導入

  • トランザクション署名が (CHAIN_ID, 0, 0)v = CHAIN_IDr = s = 0)のものを有効なトランザクションとして扱い、送信者アドレスを NULL_SENDER とする。
  • この形式のトランザクションでは gasPrice = 0nonce = 0value = 0 が設定されるものとする。
  • NULL_SENDERnonce はインクリメントしない。

この形式のトランザクションは、EOA署名なしで作成でき、プロトコル側の検証・手数料徴収を行わずコントラクトに委ねます。

(2) 新しいopcodeの導入:CREATE20xfb

  • (value, salt, memStart, memSize) を引数にコントラクトを生成する。
  • コントラクトアドレスは sha3(sender + salt + sha3(initCode)) % 2**160 とする。saltは任意の32バイト値である。

従来、コントラクトアドレスは、送信者とデプロイトランザクションnonce によって一意に決まります。 上述のトランザクション新形式では常に nonce = 0 のため、nonce非依存のアドレス算出が必要となり、このopcodeが併せて提案されました。

CREATE2については、EIP-1014として個別に提案され、すでに導入済みです。

参考:Deploying Smart Contracts Using CREATE2 - OpenZeppelin Docs

3-2. 歴史上の位置付けと問題点

EIP-86 は「EOA をやめて、すべてのアカウントをプログラマブルにする」最初の試みです。今日のAA関連提案、スマートウォレット技術は、すべてここから始まっています。

一方で、最終的にこの提案はEthereumでは導入されなかったわけですが、最大の課題はプロトコルレイヤーの改修が必要な点です。 ネットワーク参加者への影響が大きく、足並みを揃えることが難しかったと言えます。 また gasPrice = 0 を前提とすると、ネットワークのDoSリスクがありますが、当時有効な解決策がありませんでした。

4. EIP2938

eips.ethereum.org

4-1. 仕様

EIP-2938ではEIP-86の問題点を解消するため、以下が提案されました。

(1) 新しいトランザクション形式の導入:AA_TX_TYPE

  • EIP-2718「Typed Transaction」の一種としてAA特化のトランザクションタイプ AA_TX_TYPE を導入。
  • ペイロードRLP([nonce, target, data])
    • nonce: 対象コントラクトのnonce
    • target: 送付先(AA用コントラクトアカウント)アドレス
    • data: 呼び出す関数および引数
  • 従来の gasPricegasLimittovaluev/r/s は含めず、コントラクト内ロジックと後述opcodeで決定。
  • tx.nonce == target_contract.nonce をチェックし、一致すればインクリメント。
  • ガス関連はコントラクト内で PAYGAS により決定。

(2) 新しいグローバル変数の導入(トランザクション単位)

変数名 初期値
globals.transactionFeePaid bool false if type(tx) == AA_TX_TYPE else true
globals.gasPrice int 0 if type(tx) == AA_TX_TYPE else tx.gasPrice
globals.gasLimit int 0 if type(tx) == AA_TX_TYPE else tx.gasLimit

(3) 新しいopcodeの導入:NONCEPAYGAS

EIP-2938 で導入される主要な EVM 拡張が以下の2つです。 これらによって「コントラクトがトランザクションの有効性・ガス支払いを制御できる」ように設計されました。

  • NONCE (0x48):スタックに「現在のコントラクト (target) の nonce」を push する opcode
  • PAYGAS (0x49):「ガス支払いと実行開始の合図」をコントラクトにより明示させる opcode
    1. スタック/メモリから gasPricegasLimit を読み出す。
    2. コントラクトの残高 (ETH) が gasPrice * gasLimit をカバーできるかチェック。
    3. チェックが通れば、その分をコントラクト残高から差し引く → ガス支払いを確保。
    4. グローバル変数 transactionFeePaid を true にセットし、globals.gasPrice, globals.gasLimit を設定。
    5. その後の実行フェーズ (コントラクトのメインロジック) が開始され、実行中に revert が起きても、gas 支払いは戻らずマイナーに渡される。つまり一度 PAYGAS した時点で「有効性 + 手数料支払い保証」がブロックチェーン的に確保される。

これにより、コントラクトがトランザクションの有効性・ガス支払いを制御でき、独自の署名方式や認可ロジックを導入可能になります。

4-2. 歴史上の位置付けと問題点

EIP-2938は「プロトコルレベルでスマートコントラクトウォレットを標準化し、送信者・署名・ガス支払い方式を自由化する」提案と言えます。 EIP-86の後継として、より洗練されたプロトコルレベルのAAを目指しました。

しかしながらEIP-86同様、プロトコルレイヤー改修のハードルが高く、DoS耐性の工夫はあったものの採用に至りませんでした。

5. EIP4337

eips.ethereum.org

前2提案と異なり、CategoryがERCです。つまりプロトコルレイヤー(Core)に変更を加えない提案です。

5-1. 概要

  • UserOperation
    • エンドユーザーが署名し、Bundlerと呼ばれる特殊ノードに送る構造体。
    • AAアカウントに対するEVM上の状態変更要求に用いる。
    • 通常のトランザクションに専用フィールドを加えたもの(詳細は後述)。
  • User/Sender
    • UserOperationを送信するアカウントまたはコントラクトウォレット(スマートアカウント)。
  • Bundler
    • ERC-4337を実装した特殊なEVMクライアント(ノード)。
    • 受信したUserOperationをシミュレートし、問題なければEntryPointコントラクトを呼び出してセットを実行する。
  • EntryPointコントラクト
    • Bundlerから送られたUserOperationを、verification loop と execution loop に分けて実行するコントラクト。
    • verificationではアカウントの存在確認、ガス残高、UserOperationの有効性を確認。
    • executionでは callData に従って実行。解釈はコントラクトアカウント実装に依存。
  • (任意)Paymaster
    • 送信者の代わりに手数料を支払うコントラクト。
    • サービス提供者による手数料肩代わりや、ERC20等での支払いを可能にする。

EIP-4337は、コンセンサスレイヤのロジックを変えずに、トランザクションMempoolの機能を上位レイヤで模倣します。

EIP4337 Overview
https://medium.com/infinitism/erc-4337-account-abstraction-without-ethereum-protocol-changes-d75c9d94dc4a

処理の流れ:

  1. エンドユーザーはUserOperationを、EthereumのトランザクションMempoolとは別の専用Mempoolに送信する。
  2. BundlerはMempoolからUserOperationを抽出する。
  3. Bundlerは複数のUserOperationをまとめてbundle transactionを作り、EntryPointの handleOps を呼ぶ。この際、BundlerはETHでbundle transactionの手数料を支払う。既存Mempoolと同様に、手数料に基づく優先順位付けでUserOperationを選択する。
  4. EntryPointはbundle内の各UserOperationを順に処理する。
    • verification loop(必要に応じてPaymaster検証)
    • execution loop

このようにEIP-4337は、いわゆる「メタトランザクション」を標準化し、その実行を担う仕組みを整備して、コントラクトレイヤー起点のAAを実現します。

5-2. 詳細な規格

5-2-1. UserOperationの構造

UserOperationトランザクションに類似した役割を持ちます。:

struct PackedUserOperation {
    address sender; // Senderのアドレス
    uint256 nonce; // ノンス(リプレイ防止用の一意な値)
    bytes initCode; // コントラクトウォレットのデプロイ用コード(factoryアドレス+factoryDataの連結、または空)
    bytes callData; // Senderに渡す、メイン処理を担うデータ
    bytes32 accountGasLimits; // verificationGas(16バイト)とcallGas(16バイト)の連結
    uint256 preVerificationGas; // 署名検証前に必要なガス量
    bytes32 gasFees; // maxPriorityFee(16バイト)とmaxFeePerGas(16バイト)の連結
    bytes paymasterAndData; // Paymaster関連データ(または空)
    bytes signature; // 署名データ
}

ユーザーは実行したい処理をUserOperationにし、Bundlerの専用Mempoolへ送ります。 Bundlerは複数のUserOperationをまとめ、EntryPointの handleOps を呼び出します。

5-2-2. EntryPointコントラクト

EntryPointコントラクトは次のインターフェースを持ちます。

function handleOps(
    PackedUserOperation[] calldata ops,
    address payable beneficiary
) external { ... }
  • ops:処理対象のUserOperation配列
  • beneficiary:ガス代の受取先(通常はBundler)

5-2-3. コントラクトウォレット(Smart Account)

コントラクトウォレットは validateUserOp を実装する必要があります。

interface IAccount {
  function validateUserOp(
    PackedUserOperation calldata userOp,
    bytes32 userOpHash,
    uint256 missingAccountFunds
  ) external returns (uint256 validationData);
}
  • userOp: 実行対象のUserOperation
  • userOpHash: userOp(署名を除く)とEntryPointアドレス、chainIdを含むハッシュ
  • missingAccountFunds: EntryPointに預ける最低額

validateUserOp はEntryPointから呼ばれ、UserOperationの検証と必要なガス代の支払いを行います。

execution loopで実行される関数として、以下のような executeUserOp を用意するのが一般的です(仕様上は任意)。

interface IAccountExecute {
  function executeUserOp(PackedUserOperation calldata userOp, bytes32 userOpHash) external;
}

コントラクトウォレットは事前デプロイでなくても構いません。Factoryと CREATE2 を使い、UserOperationの initCode により決定論的にデプロイすることも可能です。

EntryPointとコントラクトウォレットの関係は次のとおりです。

Parymasterなし(ETH支払)の場合の処理フロー
https://medium.com/infinitism/erc-4337-account-abstraction-without-ethereum-protocol-changes-d75c9d94dc4a

  1. Bundlerがbundle transactionを作成し、handleOps を呼ぶ。(図の1)
  2. 検証・支払い(図の2、3)
    • UserOperationの検証
      • op.sender に対応するウォレットが存在しない場合、op.initCode で作成(※Paymaster未使用の場合は通常デプロイ済みを利用)。
      • ウォレットの validateUserOp を実行し、op.nonceop.signature を検証。
    • 検証が通れば、ウォレットが手数料を算出しEntryPointへ支払う。
  3. 実行・払い戻し(図の4、5)
    • op.callData に従いウォレットをコール(executeUserOp)。callDataの解釈はウォレット実装に依存。
    • 未使用ガスをウォレットへ払い戻す。

5-2-4. 機能拡張:Paymaster

EIP-4337はPaymasterを導入します。Paymasterにより、ユーザーはETH以外で手数料を支払ったり、サービス側が肩代わりできます。 Paymasterとなるコントラクトは、ETH等をEntryPointにステークして登録します。EntryPointは次のインターフェースを提供します。

function addStake() external payable
function unlockStake(address paymaster) external
function withdrawStake(address payable withdrawAddress) external

Paymaster側は以下を実装します。

function validatePaymasterUserOp
    (PackedUserOperation calldata userOp, bytes32 userOpHash, uint256 maxCost)
    external returns (bytes memory context, uint256 validationData);

function postOp
    (PostOpMode mode, bytes calldata context, uint256 actualGasCost, uint256 actualUserOpFeePerGas)
    external;

enum PostOpMode {
    opSucceeded,
    opReverted // UserOperationがrevertしてもPaymasterはガス代を支払う
}

Paymasterありの場合の処理フロー
https://medium.com/infinitism/erc-4337-account-abstraction-without-ethereum-protocol-changes-d75c9d94dc4a

Paymasterが存在する場合の基本的な流れ:

  1. Bundlerがbundle transactionを作成し、handleOps を呼ぶ。(図の1)
  2. 検証・支払い
    • UserOperationの検証(図の2)
      • op.sender が未作成なら op.initCode で作成。
      • ウォレットの validateUserOp を実行し、op.nonceop.signature を検証。
    • op.paymaster が十分なETHをEntryPointにステークしていることを確認(図の3)
    • op.paymastervalidatePaymasterUserOp をコールし、代払い可否を確認(図の4)
  3. 実行・精算
    • op.callData に従いウォレットをコール(図の5)
    • op.paymasterpostOp をコールし、代払いした手数料(ETH)をERC20等で回収(図の6)

6. おわりに

EIP-4337は、プロトコルレイヤーを変更せずにAAを実現する興味深い提案です。BundlerやEntryPoint、Paymasterなどの新しい概念を導入し、コントラクトウォレットの利用を促進します。 また、EIP-4337に至るまでの提案史を振り返ることで、同様の課題に対する様々なアプローチが存在することがわかります。 パブリックチェーンにおいては、プロトコルレイヤーの変更は大きなハードルとなりますが、それ以外のユースケースにおいてはEIP-2938や、極端な場合はEIP-86のようなアプローチも検討に値するでしょう。

また、本稿では触れませんでしたが、関連する提案としてEIP-7702が2025年5月のPectraアップグレードで導入されました。 EIP-7702 は、既存EOAに “スマートコントラクトの機能 (コード + 記憶領域)” を一時的に付与できるようにする提案で、これにより “EOA vs コントラクトウォレット” という従来の二分構造を曖昧にし、より柔軟で使いやすいアカウントモデルを実現することが期待されています。 Account Abstraction に関連する動向には今後も注目です。

最後に、本記事の内容は社内勉強会資料をもとに再整理したものです。BOOSTRYでは毎週、社内で技術勉強会を開催し、ブロックチェーンをはじめとする先端技術の知見をメンバー間で共有しています。この記事を通じて、BOOSTRYの技術への取り組みやブロックチェーン技術の可能性に少しでも興味を持っていただければ幸いです。今後も研究開発およびプロダクト開発を通じて、より効率的で機能性の高い、先進的な金融市場の実現に向けて取り組んでまいります。引き続きBOOSTRYの活動にご注目ください。

ご興味のある方は、ぜひ採用情報もご覧ください。私たちは、金融×ブロックチェーンという難しくもやりがいのある領域で、新しい市場を共に創る仲間をいつでも歓迎しています。

主な参考資料

〒101-0032 東京都千代田区岩本町3丁目9-2 PMO岩本町4F