メインコンテンツまでスキップ

スマートアカウント

SimpleAccount は最小構成の単一 Owner ECDSA 参照実装です。独自の ERC-4337 スマートアカウントも実装できます。

SimpleAccount implementation は全アカウントプロキシが共有する実装アドレスであり、ユーザーのアカウントアドレスではありません。各インスタンスは Owner と salt で決まります。

1. SimpleAccountFactory API​

interface ISimpleAccountFactory {
function accountImplementation() external view returns (address);
function getAddress(address owner, uint256 salt) external view returns (address);
function createAccount(address owner, uint256 salt) external returns (address);
}
メソッド説明
accountImplementation共有 SimpleAccount 実装を返す
getAddressOwner と salt から反実仮想プロキシアドレスを計算(デプロイなし)
createAccountコードがなければ作成し、デプロイ済みなら既存アカウントを返す

初回 UserOperation の Factory データは、Factory アドレスと ABI エンコードした createAccount(owner, salt) です。EntryPoint は Factory の返り値が UserOperation の sender と一致し、デプロイ後に sender にコードが存在することを要求します。

2. SimpleAccount API​

interface ISimpleAccount {
function owner() external view returns (address);
function entryPoint() external view returns (address);
function getNonce() external view returns (uint256);
function initialize(address owner) external;
function execute(address dest, uint256 value, bytes calldata func) external;
function executeBatch(address[] calldata dest, uint256[] calldata value, bytes[] calldata func) external;
function getDeposit() external view returns (uint256);
function addDeposit() external payable;
function withdrawDepositTo(address payable withdrawAddress, uint256 amount) external;
}

2.1 アカウント状態​

メソッド説明
owner現在の単一 ECDSA Owner
entryPointアカウントに紐付く EntryPoint
getNonceEntryPoint における key 0 の次の nonce
initializeプロキシ Owner を一度だけ初期化

Factory は作成時にプロキシを初期化します。未初期化プロキシを外部へ公開しないでください。

2.2 ビジネス実行​

メソッド呼び出し権限動作
executeOwner または紐付く EntryPoint単一の呼び出しを実行し revert データを転送
executeBatchOwner または紐付く EntryPoint複数の呼び出しをアトミックに実行

executeBatch の宛先配列と calldata 配列は同じ長さが必要です。value 配列は空(全呼び出しで BOT を送らない)または宛先配列と同じ長さにします。

Owner が直接呼ぶ場合は通常のオンチェーントランザクションで Gas を支払います。EntryPoint から呼ぶ場合は UserOperation を使用し、アカウントまたは Paymaster の deposit から決済します。

2.3 EntryPoint deposit​

メソッド説明
getDepositEntryPoint 内の Gas deposit を照会
addDepositアカウントの deposit に入金
withdrawDepositToOwner が deposit を引き出す

ネイティブ BOT 残高は送金・ビジネス呼び出しに、EntryPoint deposit は UserOperation Gas に使われ、互いに独立しています。

2.4 トークンの受け取り​

SimpleAccount はネイティブ BOT、ERC-721、ERC-1155 を受け取り、対応する receiver インターフェース検出を実装します。

3. SimpleAccount の検証動作​

SimpleAccount は BaseAccount.validateUserOp を継承します。

function validateUserOp(PackedUserOperation calldata userOp, bytes32 userOpHash, uint256 missingAccountFunds) external returns (uint256 validationData);
手順動作
呼び出し元紐付く EntryPoint のみ許可
署名 hashuserOpHash に EIP-191 を適用
署名検証ECDSA recover の結果が Owner と一致
署名失敗SIG_VALIDATION_FAILED(1)を返す
nonceEntryPoint が一意性を管理。既定 key は 0
prefundmissingAccountFunds を EntryPoint へ支払う

SimpleAccount は multisig、ソーシャルリカバリー、Session Key、Passkey、ERC-7579 モジュールを標準提供しません。必要なら独自アカウントを実装し、未公開インターフェースがあると仮定しないでください。

4. 独自スマートアカウント​

IAccount を一から実装するか、BaseAccount を継承します。EntryPoint v0.7 と Bundler の検証規則への互換性が必要です。

4.1 必須インターフェース​

interface IAccount {
function validateUserOp(PackedUserOperation calldata userOp, bytes32 userOpHash, uint256 missingAccountFunds) external returns (uint256 validationData);
}
引数説明
userOp検証・実行対象の PackedUserOperation
userOpHashEntryPoint と chainId に結び付く hash
missingAccountFundsdeposit と必要 prefund の差額
下位 160 bit:0 は署名有効、1 は失敗、その他はアグリゲーターアドレス
次の 48 bit:validUntil(0 は期限なし)
上位 48 bit:validAfter

4.2 必須動作​

  • msg.sender が信頼する EntryPoint か検証する。
  • signature、認可ポリシー、必要な状態を検証する。
  • 署名不一致は 1 を返し、形式・ポリシー違反は revert できる。
  • アカウントの nonce ポリシーを適用し、一意性更新は EntryPoint に任せる。
  • Paymaster なしで deposit が不足する場合は missingAccountFunds を支払う。
  • ERC-7562 の opcode、storage アクセス、外部呼び出し制限を守る。
  • 推定時に決定論的でシミュレーション可能な検証を提供する。

BaseAccount のサブクラスは最低限 entryPoint() と _validateSignature(...) を提供します。必要に応じて _validateNonce(...) と _payPrefund(...) を上書きします。

4.3 実行インターフェース設計​

単一実行、一括実行、モジュール実行、権限階層など独自の callData を定義できます。既定では EntryPoint が userOp.callData を直接アカウントへ送ります。

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

executeUserOp selector を使う場合、EntryPoint が完全な UserOperation と hash を渡します。このインターフェースは任意です。

4.4 Factory とデプロイ​

  • 決定論的パラメータから安定したアドレスを導出する。
  • 作成メソッドが実際のデプロイ先を返す。
  • 初回 initCode の先頭 20 bytes に Factory アドレス、残りに calldata を置く。
  • デプロイ結果を UserOperation の sender と一致させる。
  • デプロイ後は Factory フィールドを省略する。

Bundler は Factory とアカウントの検証をシミュレーションし、規則違反があれば mempool へ入る前に拒否します。