カスタム Paymaster
EntryPoint v0.7 互換 Paymaster をデプロイし、独自ポリシーを満たす UserOperation の Gas を支払えます。コントラクト、スポンサーサービス、資金、署名ポリシー、リスク管理、可用性は開発者が管理します。

参照実装:
1. IPaymaster API
interface IPaymaster {
enum PostOpMode { opSucceeded, opReverted, postOpReverted }
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;
}
1.1 validatePaymasterUserOp
| 引数 | 説明 |
|---|---|
userOp | スポンサー対象の完全な PackedUserOperation |
userOpHash | EntryPoint と chainId に結び付く hash |
maxCost | Gas 上限と価格から算出した最大コスト |
| 返り値 | 説明 |
|---|---|
context | postOp へ渡すコンテキスト。空なら postOp 不要 |
validationData | 署名の有効性と時間範囲 |
下位 160 bit:0 は有効、1 は署名失敗
次の 48 bit:validUntil(0 は期限なし)
上位 48 bit:validAfter
Paymaster はアグリゲーターアドレスを返せません。下位 160 bit が 0 または 1 以外なら検証失敗です。
このメソッドは次を満たす必要があります。
- 紐付く EntryPoint からの呼び出しのみ許可する。
paymasterData、sender、呼び出し先、上限、有効期限を検証する。- スポンサーポリシー違反時は revert または署名失敗を返す。
maxCost内で予算とクォータを確認する。- Bundler の ERC-7562 storage・状態変更規則を守る。
1.2 postOp
| 引数 | 説明 |
|---|---|
mode | UserOperation 実行の成功または revert |
context | 検証段階から渡されたコンテキスト |
actualGasCost | postOp 前までの実 Gas コスト |
actualUserOpFeePerGas | 実際に支払った Gas 単価 |
| 値 | 説明 |
|---|---|
opSucceeded | ビジネス呼び出し成功 |
opReverted | ビジネス呼び出し revert。Paymaster は Gas を支払う |
postOpReverted | EntryPoint 内部クリーンアップ状態。Paymaster への引数にはならない |
EntryPoint は context が空でない場合だけ postOp を呼びます。非空 context を返す Paymaster は信頼できる postOp を実装する必要があります。postOp が revert すると UserOperation は失敗しますが、消費済み Gas は支払われます。
2. BasePaymaster
BasePaymaster.sol は EntryPoint の紐付け、呼び出し元検証、deposit・stake 管理を提供します。
2.1 サブクラス拡張インターフェース
function _validatePaymasterUserOp(
PackedUserOperation calldata userOp,
bytes32 userOpHash,
uint256 maxCost
) internal virtual returns (bytes memory context, uint256 validationData);
function _postOp(
PostOpMode mode,
bytes calldata context,
uint256 actualGasCost,
uint256 actualUserOpFeePerGas
) internal virtual;
_validatePaymasterUserOp は必須です。非空 context を返す場合は _postOp を上書きします。BasePaymaster の既定 _postOp は revert します。
2.2 資金管理インターフェース
function entryPoint() external view returns (address);
function deposit() external payable;
function getDeposit() external view returns (uint256);
function withdrawTo(address payable withdrawAddress, uint256 amount) external;
function addStake(uint32 unstakeDelaySec) external payable;
function unlockStake() external;
function withdrawStake(address payable withdrawAddress) external;
deposit 以外の引き出し・stake 管理は Owner に制限されます。
3. RPC UserOperation フィールド
| フィールド | 型 | 説明 |
|---|---|---|
paymaster | address | Paymaster コントラクトアドレス |
paymasterVerificationGasLimit | QUANTITY | Paymaster 検証 Gas 上限 |
paymasterPostOpGasLimit | QUANTITY | postOp Gas 上限 |
paymasterData | DATA | 独自の認可、署名、ポリシーデータ |
最終送信オブジェクトには両方の Gas 上限が必要です。paymasterData 形式は実装とスポンサーサービスが定義します。Paymaster を使わない場合は 4 フィールドすべてを省略し、ゼロアドレスを指定しないでください。
4. paymasterAndData レイアウト
offset 0、20 bytes:paymaster
offset 20、16 bytes:paymasterVerificationGasLimit
offset 36、16 bytes:paymasterPostOpGasLimit
offset 52 以降:paymasterData
Paymaster 使用時は最低 52 bytes、未使用時は空 bytes です。
5. Deposit と stake
5.1 Deposit
Deposit は実際の UserOperation Gas を支払い、EntryPoint が検証時に必要 prefund を確認・予約します。
| インターフェース | 説明 |
|---|---|
depositTo(paymaster) | Gas deposit を追加 |
balanceOf(paymaster) | 利用可能 deposit を照会 |
withdrawTo | Paymaster 自身の deposit を引き出す |
不足時は AA31 paymaster deposit too low です。
5.2 Stake
Stake は Bundler のレピュテーションと DoS 対策用で、Gas を直接支払いません。
| インターフェース | 説明 |
|---|---|
addStake | stake とロック解除遅延を設定 |
unlockStake | 待機期間を開始 |
withdrawStake | 待機期間後に引き出す |
検証中に関連 storage へアクセスまたは特定状態を変更する Paymaster には、Bundler が最小 stake と unstake delay を要求する場合があります。しきい値は Bundler 設定によります。
6. よくあるエラー
| エラー | 意味 |
|---|---|
AA31 | Paymaster deposit 不足 |
AA32 | validationData の時間範囲が無効 |
AA33 | validatePaymasterUserOp が revert |
AA34 | validationData 下位 160 bit が 0 でない |
AA36 | 検証が Gas 上限超過 |
PostOpReverted | postOp が revert。PostOpRevertReason も確認 |
AA93 | paymasterAndData の長さ・レイアウトが無効 |