跳至内容
0%

什么是 UserOperation?

发布于 2023年6月26日3 分钟阅读

User operations 是包含交易详情的对象,代表发送者的智能合约账户执行。User operations 是一种伪交易对象,使得账户抽象无需对 Ethereum 及支持 ERC-4337 的 layer 2 区块链进行共识层改动即可运作。

无论是开发智能合约钱包(SCWs),还是让去中心化应用兼容 SCWs,理解定义 user operation 的各个参数、user op 字段在构建过程中如何填充、user ops 如何被 bundler 打包、以及如何被 paymaster 验证和执行,都会很有帮助。

使用我们的 Embedded Accounts 和账户抽象基础设施,让新用户可以创建内嵌邮箱和 passkey 钱包!

观看:在 Solidity 中构建和执行 user operations

user operation 中包含哪些字段?

User operations(UOs)包含的字段与常规交易类似(例如 sender、to、calldata、maxFeePerGas、maxPriorityFee、signature 和 nonce),但也有一些 user operation 结构体特有的新字段,包括 callGasLimit、verificationGasLimit、preVerificationGas 和 paymasterAndData。

UO 字段的定义可以在 ERC-4337 官方规范 中找到。以下是简要总结:

  • callGasLimit - 主执行调用所使用的 gas
  • verificationGasLimit - 完成验证步骤所使用的 gas
  • preVerificationGas - 支付给 bundler,以覆盖验证前执行和 calldata 成本的 gas
  • paymasterAndData - 赞助方 paymaster 的地址,以及要发送给 paymaster 的数据

David Philipson(Alchemy AA 基础设施团队的工程师)撰写的 "You Could Invented Account Abstraction" 系列第一部分,对 user operations 的设计与架构 做了说明。

接下来,我们来了解正确填充 user operation 中各字段的标准工作流程。

发送 user operation 的流程是怎样的?

将 user operation(user op)发送给 bundler 的典型流程包含多个步骤:

  1. 构建一个部分填充的 user op,填入 sender、nonce、initCode 和 callData
  2. 通过 eth_estimateUserOperationGas 向 bundler RPC 为该部分 user op 估算 gas
  3. 填充 preVerificationGas、verificationGasLimit、callGasLimit
  4. 如果使用的是不依赖 user op 内容的 paymaster(例如 ERC20 paymaster),此时可以填充 paymasterAndData。
  5. 估算该操作所需的 gas 费用,并填充 maxFeePerGas 和 maxPriorityFeePerGas
  6. (可选)将 user op 发送给赞助方 paymaster 进行签名,并填充 paymasterAndData
  7. 这一步必须在此时完成,因为 paymaster 的签名需要上述所有字段都已填充。
  8. 对 user op 进行签名,填充 signature,并通过 eth_sendUserOperation 将 user op 发送给 bundler

虽然开发者可以使用原生的 ethers.js 来获取每个 user operation 字段的值,但也有一些 web3 开发者工具可以让 UO 的构建更加简单。

开发者可以使用什么工具来构建 user operations?

像 Alchemy 的开源 AA SDK 这类 user operation 构建工具,比使用原生 ethers.js 构建 user ops 更加简便。

Alchemy 的 AA SDK

Alchemy 的 AA SDK 基于 viem 构建,为开发者提供一个轻量级的库。GitHub 上的 aa-sdk 也通过 aa-ethers 库支持 ethers.js 的 signers 和 providers。

使用 aa-sdk 构建 user operations 的主要优势之一是它提供了两个实用方法:

  1. sendUserOperation - 处理 gas 估算、请求 paymasterAndData、签名等操作
  2. sendTransaction - 将交易对象数据(from、to、data 和 value)转换为 user operation

构建 user operation 的操作顺序较为复杂,而 Alchemy 的 AA-SDK 通过运行一系列操作简化了 UO 的构建:先用 getDummyPaymasterData,再用 estimateGas 估算 gas,接着是 getFeeData,最后是 getPaymasterAndData。

在获得 user op 各字段的值之后,它会取用 target、callData 以及一个可选的 value 来构建并签署 user operation。然后它将 user op 发送给 bundler,并接收该 user op 的哈希值。

如果你想使用 Alchemy 的 paymaster、其他 paymaster,或者计划为你自己的 SmartAccounts 添加支持,请阅读 Alchemy AA SDK 文档,了解如何轻松创建 UOs 的完整说明。

user operations 是如何被添加到 user op mempool 中的?

在 user op 被添加到 mempool 之前,它必须通过一系列检查,以确保其遵循 ERC-4337 规范中所述的预期行为。该 user op 还必须通过验证模拟检查,以确保其有效并能够支付其 gas 费用(无论是通过发送者的钱包,还是通过 paymaster 的赞助策略)。

1. 检查 user ops 的有效性

初始的一系列检查在 ERC-4337 规范的 "Client behavior upon receiving a UserOperation" 一节中有说明,以下是简要总结:

  • sender 是一个已存在的合约,或者用于创建合约的 initCode 非空(但不能两者同时成立)
  • 如果 initCode 非空(即该 user op 用于创建账户),需判断该 factory 是否已质押
  • verificationGasLimit 足够低(小于或等于 MAX_VERIFICATION_GAS)
  • preVerificationGas 足够高,可以支付 calldata gas 以及额外开销费用
  • paymasterAndData 要么为空,要么以 paymaster 地址开头
  • 如果存在 paymaster,其在链上必须有非空的代码、有足够资金支付该 user op 的费用,且未被封禁
  • callgas 至少要达到一次带非零值的 CALL 的成本
  • maxFeePerGas 和 maxPriorityFeePerGas 都高于客户端可接受的最低值
  • sender 在池中没有另一个 user op(或者该 user op 是构造用来替换已有条目的)

有许多规则会影响这些检查,规范中对此有完整说明。

在这篇 user operations 入门介绍中,我们只是想传达用来判定 user op 有效性所进行的高层次检查。

2. user operation 会被模拟

一旦 user op 通过这些基础检查,客户端就需要对该 user operation 进行模拟,以验证其能够支付其执行费用——无论是使用自身资金,还是借助 paymaster。

为了模拟一个 user op,bundler 会调用 simulateValidation() 方法,该方法接着会调用 sender 账户上的 validateUserOp 函数,如果将使用 paymaster 来赞助该 user op 的执行 gas 费用,则会调用 paymaster 合约账户上的 validatePaymasterUserOp。

调用 simulateValidation() 方法后,它会以 ValidationResult 响应发生 revert。函数发生 revert 是预期行为,这被视为成功的结果。

如果 ValidationResult 以其他错误发生 revert,则说明该 user op 未通过验证模拟,不会被添加到 mempool 中。如果 user ops 返回 sigFail,它们会被排除在 mempool 之外;如果 validUntil 响应已过期,UOs 同样可能被排除在 mempool 之外。

注意: 如果 user op 中存在 initCode,账户将由一个 account factory 创建,随后模拟过程将使用新创建的账户继续进行。

既然 user operation 已经过构建、检查、模拟并被添加到 mempool 中,它就可以被发送到 entry point 合约进行验证和执行了!

user operations 是如何被验证和执行的?

要让 user operation 中的交易详情发布到链上,entry point 合约需要验证该 user operation,如果该 UO 通过验证,entry point 合约就会执行该交易,然后向 bundler 偿还其所支付的 gas 费用。

user op 验证和执行的基本步骤如下:

  1. bundler 通过 handleOps() 方法将 user ops 发送给单一的 entry point 合约
  2. 对每个 op,entry point 会在该 op 的 sender 钱包上调用 validateOp*
  3. 如果有任何 op 未通过验证步骤,则会被丢弃
  4. 接下来,对每个 op,在其 sender 钱包上调用 executeOp,并追踪所使用的 gas 量
  5. 从 sender 的钱包或 paymaster 向 bundler 转账 ETH,以支付执行每个 op 所用的 gas

*所有的验证都会先运行,然后才会运行所有通过验证的 user ops 的执行。

下图展示了 entry point 合约是如何代表发送者的智能合约钱包对 user operations 进行验证和执行的:

用户操作如何验证与执行

User operations 是一种伪交易对象,使得智能合约钱包能够作为用户在 Ethereum 及其等效 L2 上的主要钱包。智能合约钱包带来了 web3 UX 方面的好处,让区块链更易于使用,而这一切得以实现,正是依赖于 Ethereum 和 L2 上的 AA 基础设施提供商。

如果你的 web3 产品支持智能合约钱包,欢迎了解 Alchemy 的 AA 基础设施,包括面向 Ethereum、Polygon、Arbitrum、Optimism 以及 Sepolia 等常用测试网的 Gas Manager API 和 Bundler API!

Background gradient

构建区块链应用

Alchemy 将最强大的 Web3 开发者产品和工具与资源、社区及专业支持结合在一起。