跳到主要内容

EntryPoint

本文说明 BotChain 已部署 EntryPoint 的链上接口。直接执行 UserOperation 时,调用方需要自行承担 Bundler 职责。

EntryPoint 验证与执行流程

1. PackedUserOperation​

EntryPoint 接收以下链上结构:

struct PackedUserOperation {
address sender;
uint256 nonce;
bytes initCode;
bytes callData;
bytes32 accountGasLimits;
uint256 preVerificationGas;
bytes32 gasFees;
bytes paymasterAndData;
bytes signature;
}

1.1 字段说明与编码​

字段含义编码布局
sender智能账户地址smartAccount(160)
nonceEntryPoint 管理的二维 noncekey(192) ‖ sequence(64)
initCode首次部署时的 Factory 地址和调用数据未部署:factory(160) ‖ factoryData(N);已部署:0x
callData发送给智能账户的执行数据selector(32) ‖ encodedArguments(N)
accountGasLimits账户验证与执行阶段的 Gas 上限verificationGasLimit(128) ‖ callGasLimit(128)
preVerificationGascalldata 与 bundle 的链上验证外开销preVerificationGas(256)
gasFeesEIP-1559 优先费与最高总费用maxPriorityFeePerGas(128) ‖ maxFeePerGas(128)
paymasterAndData可选 Paymaster 地址、Gas 上限和自定义数据使用:paymaster(160) ‖ paymasterVerificationGasLimit(128) ‖ paymasterPostOpGasLimit(128) ‖ paymasterData(N);不使用:0x
signature由智能账户验证的授权数据accountSignature(N)

括号内数字的单位为 bit;N 表示可变长度。

2. 执行接口​

function handleOps(
PackedUserOperation[] calldata ops,
address payable beneficiary
) external;

function handleAggregatedOps(
UserOpsPerAggregator[] calldata opsPerAggregator,
address payable beneficiary
) external;

2.1 handleOps​

参数说明
ops不使用签名聚合器的 UserOperation 数组
beneficiary接收本批次实际 Gas 费用的地址

EntryPoint 先完成整批验证,再逐个执行账户 callData。任何验证阶段错误都

可能使整个批次回滚;业务执行回滚则通过事件记录,不一定使外层交易回滚。

2.2 handleAggregatedOps​

用于账户返回非零签名聚合器的场景。UserOperation 按聚合器分组,每组携带

聚合签名。没有签名聚合需求时使用 handleOps。

UserOpsPerAggregator 包含:

字段类型说明
userOpsPackedUserOperation[]当前聚合器负责的操作
aggregatorIAggregator当前分组的聚合器;仅在 handleAggregatedOps 中,零地址分组表示该组无需聚合
signaturebytes当前分组的聚合签名

3. Hash、nonce 与地址​

function getUserOpHash(
PackedUserOperation calldata userOp
) external view returns (bytes32);

function getNonce(
address sender,
uint192 key
) external view returns (uint256 nonce);

function incrementNonce(uint192 key) external;

function getSenderAddress(bytes memory initCode) external;

3.1 getUserOpHash​

返回账户需要验证的 UserOperation hash。该 hash 绑定:

  • UserOperation 内容,但不包含 signature

  • 当前 EntryPoint 地址

  • 当前 chainId

任何参与 hash 的字段在签名后发生变化,都会导致签名失效。

3.2 getNonce​

返回指定账户和 nonce key 的下一个完整 nonce:

nonce = uint192 key || uint64 sequence

SimpleAccount 默认使用 key 0。不要使用 Owner EOA 的交易 nonce,也不要

用智能账户的 eth_getTransactionCount 替代。

3.3 incrementNonce​

由调用者为自己的指定 key 提前递增 nonce sequence。普通账户通常直接使用

EntryPoint 在验证成功时进行的 nonce 更新。

3.4 getSenderAddress​

根据 initCode 计算反事实账户地址。该方法始终回滚,并通过

SenderAddressResult(address sender) 自定义错误返回结果。

4. Deposit 与 stake​

function getDepositInfo(
address account
) external view returns (DepositInfo memory info);

function balanceOf(address account)
external view returns (uint256);

function depositTo(address account) external payable;

function withdrawTo(
address payable withdrawAddress,
uint256 withdrawAmount
) external;

function addStake(uint32 unstakeDelaySec) external payable;

function unlockStake() external;

function withdrawStake(
address payable withdrawAddress
) external;

4.1 Deposit​

Deposit 是账户或 Paymaster 预存在 EntryPoint 中、用于支付 UserOperation

Gas 的余额。

方法说明
balanceOf查询指定实体的 deposit
getDepositInfo同时查询 deposit、stake 和解锁状态
depositTo任何地址都可以为指定实体充值
withdrawTo提取 msg.sender 自己的 deposit

4.2 Stake​

Stake 是 Factory、Paymaster 或聚合器为满足验证和声誉规则而锁定的资金,

不用于直接支付 UserOperation Gas。

方法说明
addStake增加 stake 并设置最短解锁延迟
unlockStake开始解锁等待期
withdrawStake等待期结束后提取 stake

Deposit 与 stake 相互独立。仅有 stake 不能支付 Gas,仅有 deposit 也不

一定满足 Bundler 对受限存储访问实体的 stake 要求。

5. 核心事件​

事件关键字段用途
UserOperationEventuserOpHash、sender、paymaster、nonce、success、actualGasCost、actualGasUsed判断每个 UserOperation 的最终结果
AccountDeployeduserOpHash、sender、factory、paymaster记录反事实账户部署
UserOperationRevertReasonuserOpHash、sender、nonce、revertReason记录账户业务调用回滚数据
PostOpRevertReasonuserOpHash、sender、nonce、revertReason记录 Paymaster postOp 回滚
UserOperationPrefundTooLowuserOpHash、sender、nonce记录执行期间 prefund 不足
BeforeExecution无区分验证阶段和执行阶段事件
Deposited / Withdrawnaccount、amount记录 deposit 变化
StakeLocked / StakeUnlocked / StakeWithdrawnaccount、stake、时间记录 stake 生命周期

外层 handleOps 交易成功不代表每个 UserOperation 都成功。结果应以

UserOperationEvent.success 为准。

6. 核心错误​

错误说明
FailedOp(opIndex, reason)指定 UserOperation 在验证或预付款阶段失败
FailedOpWithRevert(opIndex, reason, inner)失败并携带账户、Factory 或 Paymaster 的内部回滚数据
PostOpReverted(returnData)Paymaster postOp 回滚
SignatureValidationFailed(aggregator)聚合签名验证失败
SenderAddressResult(sender)getSenderAddress 的预期返回载体