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

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) |
nonce | EntryPoint 管理的二维 nonce | key(192) ‖ sequence(64) |
initCode | 首次部署时的 Factory 地址和调用数据 | 未部署:factory(160) ‖ factoryData(N);已部署:0x |
callData | 发送给智能账户的执行数据 | selector(32) ‖ encodedArguments(N) |
accountGasLimits | 账户验证与执行阶段的 Gas 上限 | verificationGasLimit(128) ‖ callGasLimit(128) |
preVerificationGas | calldata 与 bundle 的链上验证外开销 | preVerificationGas(256) |
gasFees | EIP-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 包含:
| 字段 | 类型 | 说明 |
|---|---|---|
userOps | PackedUserOperation[] | 当前聚合器负责的操作 |
aggregator | IAggregator | 当前分组的聚合器;仅在 handleAggregatedOps 中,零地址分组表示该组无需聚合 |
signature | bytes | 当前分组的聚合签名 |
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. 核心事件
| 事件 | 关键字段 | 用途 |
|---|---|---|
UserOperationEvent | userOpHash、sender、paymaster、nonce、success、actualGasCost、actualGasUsed | 判断每个 UserOperation 的最终结果 |
AccountDeployed | userOpHash、sender、factory、paymaster | 记录反事实账户部署 |
UserOperationRevertReason | userOpHash、sender、nonce、revertReason | 记录账户业务调用回滚数据 |
PostOpRevertReason | userOpHash、sender、nonce、revertReason | 记录 Paymaster postOp 回滚 |
UserOperationPrefundTooLow | userOpHash、sender、nonce | 记录执行期间 prefund 不足 |
BeforeExecution | 无 | 区分验证阶段和执行阶段事件 |
Deposited / Withdrawn | account、amount | 记录 deposit 变化 |
StakeLocked / StakeUnlocked / StakeWithdrawn | account、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 的预期返回载体 |