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

カスタム Paymaster

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

Paymaster の検証・実行フロー

参照実装:

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
userOpHashEntryPoint と chainId に結び付く hash
maxCostGas 上限と価格から算出した最大コスト
返り値説明
contextpostOp へ渡すコンテキスト。空なら 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​

引数説明
modeUserOperation 実行の成功または revert
context検証段階から渡されたコンテキスト
actualGasCostpostOp 前までの実 Gas コスト
actualUserOpFeePerGas実際に支払った Gas 単価
値説明
opSucceededビジネス呼び出し成功
opRevertedビジネス呼び出し revert。Paymaster は Gas を支払う
postOpRevertedEntryPoint 内部クリーンアップ状態。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 フィールド​

フィールド型説明
paymasteraddressPaymaster コントラクトアドレス
paymasterVerificationGasLimitQUANTITYPaymaster 検証 Gas 上限
paymasterPostOpGasLimitQUANTITYpostOp Gas 上限
paymasterDataDATA独自の認可、署名、ポリシーデータ

最終送信オブジェクトには両方の 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 を照会
withdrawToPaymaster 自身の deposit を引き出す

不足時は AA31 paymaster deposit too low です。

5.2 Stake​

Stake は Bundler のレピュテーションと DoS 対策用で、Gas を直接支払いません。

インターフェース説明
addStakestake とロック解除遅延を設定
unlockStake待機期間を開始
withdrawStake待機期間後に引き出す

検証中に関連 storage へアクセスまたは特定状態を変更する Paymaster には、Bundler が最小 stake と unstake delay を要求する場合があります。しきい値は Bundler 設定によります。

6. よくあるエラー​

エラー意味
AA31Paymaster deposit 不足
AA32validationData の時間範囲が無効
AA33validatePaymasterUserOp が revert
AA34validationData 下位 160 bit が 0 でない
AA36検証が Gas 上限超過
PostOpRevertedpostOp が revert。PostOpRevertReason も確認
AA93paymasterAndData の長さ・レイアウトが無効