这篇文章介绍了用户操作(User Operations)在以太坊和支持ERC-4337的区块链中的作用,详细探讨了用户操作的字段、构造流程以及如何将其添加到用户操作内存池(mempool)、验证和执行的步骤。
用户操作是包含交易细节的对象,用于代表发送者的智能合约账户执行。用户操作是一个伪交易对象,使得账户抽象能够在不需要对以太坊和支持 ERC-4337 的第二层区块链进行共识层更改的情况下正常工作。
要开发智能合约钱包 (SCW) 或使去中心化应用程序兼容 SCW,了解定义用户操作的参数、用户操作字段在用户操作构造过程中的填充方式、用户操作如何被打包以及如何由支付者进行验证和执行是非常有益的。
使新用户能够利用我们的嵌入式账户和账户抽象基础设施 创建嵌入式电子邮件和密码钱包!
在 Solidity 中构建和执行用户操作 | 从零开始的账户抽象课程 | 第1部分 - - YouTube
用户操作(UOs)包含与常规交易类似的字段(如发送者、接收者、调用数据、最大每单位Gas费用、最大优先费用、签名和随机数),但它们还具有特定于用户操作结构的新字段,包括调用Gas限制、验证Gas限制、预验证Gas和支付者与数据。
UO 字段的定义可以在 官方ERC-4337规范中找到。它们在这里总结如下:
callGasLimit - 主执行调用使用的Gas
verificationGasLimit - 用于完成验证步骤的Gas
preVerificationGas - 用于支付打包者以覆盖预验证执行和调用数据成本的Gas
paymasterAndData - 支持方支付者的地址加上发送给支付者的数据
有关 用户操作的设计和架构 的解释可以在 David Philipson 撰写的《你可以发明账户抽象》系列的第一部分中阅读,他是 Alchemy AA 基础设施团队的工程师。
接下来,让我们学习正确填充用户操作内部字段的标准工作流程。
将用户操作(用户操作)发送到 打包者 的典型流程包含多个步骤:
构造一个填充了发送者、随机数、初始化代码和调用数据的部分用户操作
通过 eth_estimateUserOperationGas 向打包者 RPC 估算部分用户操作的Gas
填充预验证Gas、验证Gas限制、调用Gas限制
如果使用的支付者不依赖于用户操作的内容,例如 ERC20 支付者,这里可以填充支付者与数据。
估算操作所需的Gas费用并填充最大每单位Gas费用和最大优先费用
(可选)将用户操作发送到赞助支付者进行签名,并填充支付者与数据
这一操作必须在此步骤完成,因为支付者的签名需要所有上述字段都已填充。
签名用户操作,填充签名,并通过 eth_sendUserOperation 将用户操作发送到打包者
虽然开发者可以使用原生 ethers.js 来获取每个用户操作字段的值,但有一些 web3 开发工具使 UO 的构造变得更加简单。
用户操作构建工具,如 Alchemy 的开源 AA SDK,使构建用户操作比使用原生 ethers.js 更容易。
Alchemy 的 AA SDK 是使用 viem 构建的,为开发者提供轻量级的包。GitHub 上的 aa-sdk 还通过 aa-ethers 库支持 ethers.js 签名者和提供者。
使用 aa-sdk 构建用户操作的主要好处之一是两个实用方法:
sendUserOperation - 处理Gas估算、请求支付者与数据、签名等
sendTransaction - 将交易对象数据(发送者、接收者、数据和价值)转换为用户操作
构建用户操作的操作顺序很复杂,Alchemy 的 AA-SDK 通过运行一系列操作来简化 UO 的构造,以 getDummyPaymasterData 估算Gas estimateGas,然后 getFeeData,最后 getPaymasterAndData。
在获取用户操作字段的值后,它需要目标、调用数据和可选值来构建和签名用户操作。然后将用户操作发送到打包者,并接收用户操作的哈希。
如果你想使用 Alchemy 的支付者、另一个支付者,或者计划添加对你自己的智能账户的支持,请阅读 Alchemy AA SDK 文档,以详细说明如何轻松创建 UOs。
学习如何使用 AA-SDK | 账户抽象 | Solidity | Viem - YouTube
在用户操作可以加入内存池之前,它必须通过一系列检查以确保其符合 ERC-4337 规范中概述的预期行为。用户操作还必须通过验证仿真检查,以确保其有效并能够支付其Gas费用(由发送者的钱包支付或通过支付者赞助政策)。
初始的系列检查在 ERC-4337 规范的“客户端收到 UserOperation 时的行为”部分中进行了说明,以下是这些检查的摘要:
发送者是一个已存在的合约,或初始化代码(用于创建合约)不为空(但不能两者都成立)
如果 initCode 不为空(因为用户操作创建了一个账户),则需要确定工厂是否被质押
verificationGasLimit 需要足够低(小于或等于 MAX_VERIFICATION_GAS)
preVerificationGas 足够高,用于支付数据调用Gas和额外的Gas费用
paymasterAndData 为空或者以支付者地址开头
如果存在支付者,则支付者必须在链上具有非空代码、有资金支付用户操作,并且没有被禁用
callgas 至少是一个带有非零值的 CALL 的费用
maxFeePerGas 和 maxPriorityFeePerGas 超过客户端接受的最低值
发送者在池中没有其他用户操作(或用户操作构造为替换现有条目)
有许多规则可能影响这些检查,它们在规范中进行了详细说明。
对于用户操作的介绍,我们的目标是传达其中为 qualifying 的用户操作所做的高层次检查。
一旦用户操作通过这些基本检查,客户端需要模拟用户操作以验证用户操作是否可以支付其执行费用,无论是通过使用其自身资金还是通过支付者。
为了模拟用户操作,打包者调用 simulateValidation() 方法,然后如果将使用支付者来赞助用户操作的Gas费用,则调用发送者账户上的 validateUserOp 函数或支付者合约账户上的 validatePaymasterUserOp 函数。
在调用 simulateValidation() 方法后,它将通过 ValidationResult 响应进行回滚。回滚的函数是预期的行为,这被视为成功的结果。
如果 ValidationResult 以不同错误回滚,则用户操作未通过验证模拟,并且不会加入到内存池。如果返回 sigFail,用户操作会被排除在内存池之外,如果 validUntil 响应过期,UOs 也可能被排除在内存池之外。
注意: 如果用户操作中存在 initCode,将通过账户工厂创建账户,然后使用新创建的账户继续进行模拟过程。
现在用户操作已构建、检查、模拟并添加到内存池,可以将其发送到入口点合约进行验证和执行!
要使用户操作中的交易详情在链上发布,入口点合约需要验证用户操作,如果用户操作验证通过,那么入口点合约将执行交易,然后向打包者偿还Gas费用。
用户操作验证和执行的基本步骤是:
打包者通过 handleOps() 方法将用户操作发送到单例入口点合约
对于每个操作,入口点在操作的发送者钱包上调用 validateOp
如果任何操作未通过验证步骤,则将其丢弃
接下来,在操作的发送者钱包上为每个操作调用 executeOp,跟踪使用了多少Gas
从发送者的钱包或支付者向打包者转移 ETH,以支付执行每个操作所用的Gas
所有验证都是在此运行,仅在验证通过后,才会运行所有经过验证的用户操作的执行。
下面是一个图示,显示用户操作是如何由入口点合约代表发送者的智能合约钱包进行验证和执行的:
用户操作是伪交易对象,允许智能合约钱包在以太坊和相应的第二层网络上充当用户的主要钱包。智能合约钱包引入了 web3 用户体验优势,使区块链变得更加易于使用,这得益于 以太坊和第二层网络的 AA 基础设施提供商。
如果你的 web3 产品支持智能合约钱包,请探索 Alchemy 的 AA 基础设施,包括我们的 Gas管理 API 和 打包者 API,适用于以太坊、Polygon、Arbitrum、Optimism,以及 Sepolia 等流行测试网!
- 原文链接: alchemy.com/overviews/us...
- 登链社区 AI 助手,为大家转译优秀英文文章,如有翻译不通的地方,还请包涵~
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!