ERC-4337 Gas估算阶段如何区分Paymaster验证的估算与实际阶段?
在Paymaster合约的_validatePaymasterUserOp中区分Gas估算与实际验证阶段的方法
有两种可靠的方式适配EIP-4337规范要求,实现阶段区分:
1. 检查UserOp的signature是否为虚拟占位符
EIP-4337规范推荐Gas估算阶段使用固定虚拟签名(如0xdeadbeef系列占位值),你可以在合约中预先定义该值,在验证逻辑中优先判断:
- 若签名匹配虚拟值,判定为Gas估算阶段,直接跳过真实签名验证,返回合法验证结果即可。
- 若不匹配,则进入实际验证阶段,执行ECDSA签名恢复与地址对比。
示例代码:
// 定义规范推荐的虚拟签名常量 bytes public constant DUMMY_SIGNATURE = hex"deadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef"; function _validatePaymasterUserOp( UserOperation calldata op, bytes32 userOpHash, uint256 requiredPreFund ) internal override returns (bytes memory context, uint256 validationData) { // 识别Gas估算阶段 if (keccak256(op.signature) == keccak256(DUMMY_SIGNATURE)) { // 跳过签名验证,返回允许执行的验证数据(0表示无错误) return ("", 0); } // 实际验证阶段:执行签名恢复与校验 address signer = ECDSA.recover(ECDSA.toEthSignedMessageHash(userOpHash), op.signature); require(signer == yourStoredAddress, "Paymaster: Invalid signer"); // 其他自定义验证逻辑... return ("", 0); }
2. 利用EntryPoint的模拟验证上下文判断
当EntryPoint执行Gas估算时,会调用simulateValidation方法触发Paymaster的_validatePaymasterUserOp,此时可通过以下方式识别:
- 检查当前调用是否来自EntryPoint的
simulateValidation(可通过函数签名或调用栈判断,但实现复杂度较高)。 - 估算阶段的UserOp Gas参数为临时值,对应的
userOpHash并非最终值,强行执行签名验证必然失败,可捕获该失败判定为估算阶段,但这种方式不如占位符判断可靠。
关键注意事项
- 估算阶段的
userOpHash基于未最终确定的Gas参数计算,无法得到正确的签名恢复结果,必须跳过该阶段的签名验证。 - 估算阶段仅需完成基础检查(如用户白名单、操作类型合法性),避免不必要的Gas消耗。
内容的提问来源于stack exchange,提问作者Thomas Kelly
相关产品推荐
相关产品推荐

