账户抽象 - OpenZeppelin 文档

本文介绍了账户抽象的概念,特别是通过 ERC-4337 标准实现账户抽象的方法。

账户抽象

与外部拥有账户 (EOA) 不同,智能合约可以包含基于以太坊原生 ECDSA 之外的认证机制的任意验证逻辑,并具有执行优势,例如批量处理或 gas 赞助。为了利用智能合约的这些属性,社区已广泛采用 ERC-4337,这是一种通过替代内存池处理用户操作的标准。

该库提供了多个遵循此标准的账户抽象合约,因为它能够实现更灵活和用户友好的应用程序交互。账户抽象用例包括新型环境中的钱包(例如,嵌入式钱包)、更细粒度的账户配置和恢复机制。

ERC-4337 概述

ERC-4337 是一个详细的规范,说明如何在不更改协议级别(即区块链本身的规则)的情况下实现处理操作所需的逻辑。 此规范定义了以下组件:

UserOperation

UserOperation 是一个高层的伪交易对象,代表账户的意图。这与常规 EVM 交易有一些相似之处,例如 gasFeescallData 的概念,但包含启用新功能的字段。

struct PackedUserOperation {
    address sender;
    uint256 nonce;
    bytes initCode; // concatenation of factory address and factoryData (or empty)
    bytes callData;
    bytes32 accountGasLimits; // concatenation of verificationGas (16 bytes) and callGas (16 bytes)
    uint256 preVerificationGas;
    bytes32 gasFees; // concatenation of maxPriorityFee (16 bytes) and maxFeePerGas (16 bytes)
    bytes paymasterAndData; // concatenation of paymaster fields (or empty)
    bytes signature;
}

捆绑用户操作的这个过程涉及捆绑者必须承担的多个成本,包括基本交易费用、calldata 序列化、入口点执行和付费方上下文成本。为了补偿这些费用,捆绑者使用 preVerificationGasgasFees 字段来适当地向用户收费。

估算 preVerificationGas 没有标准化,因为它会根据网络条件(如 gas 价格和操作捆绑包的大小)而变化。
使用 ERC4337Utils 来操作 UserOperation 结构和其他 ERC-4337 相关值。

Entrypoint

每个 UserOperation 都是通过一个名为 EntryPoint 的合约执行的。 此合约是一个单例,以相同的地址部署在多个网络中,尽管也可以使用其他自定义实现。

入口点合约被认为是账户信任的实体。

Bundlers

Bundler 是一块 链下 基础设施,负责处理用户操作的替代内存池。 Bundler 本身使用 UserOperations 数组调用 Entrypoint 合约的 handleOps 函数,这些 UserOperations 会被执行并包含在一个区块中。

在此过程中,捆绑者支付执行交易的 gas 费用,并在 Entrypoint 合约的执行阶段获得退款。

/// @dev Process `userOps` and `beneficiary` receives all
/// the gas fees collected during the bundle execution.
// @dev 处理 `userOps` ,`beneficiary` 获得在捆绑包执行期间收集的所有 gas 费用。
function handleOps(
    PackedUserOperation[] calldata ops,
    address payable beneficiary
) external { ... }

Account Contract

账户合约是一种智能合约,它实现了在 ERC-4337 上下文中验证 UserOperation 所需的逻辑。任何智能合约账户都应符合 IAccount 接口才能验证操作。

interface IAccount {
    function validateUserOp(PackedUserOperation calldata, bytes32, uint256) external returns (uint256 validationData);
}

同样,账户应该有一种方法来执行这些操作,方法是在其 fallback 上处理任意 calldata 或实现 IAccountExecute 接口:

interface IAccountExecute {
    function executeUserOp(PackedUserOperation calldata userOp, bytes32 userOpHash) external;
}
IAccountExecute 接口是可选的。 开发人员可能希望使用 ERC7821 来获得最小的批量执行接口,或者依赖于 ERC-7579、ERC-6909 或任何其他执行逻辑。

要构建你自己的账户,请参阅 accounts

Factory Contract

智能合约账户由账户开发者定义的 Factory 合约创建。 此工厂接收任意字节作为 initData,并返回部署账户逻辑的 address

要构建你自己的工厂,请参阅 account factories

Paymaster Contract

Paymaster 是一个可选实体,可以赞助账户的 gas 费用,或者允许他们以 ERC-20 代币而不是原生货币支付这些费用。 这以与云服务器的计算成本从最终用户处抽象出来的方式相同的方式抽象了用户体验中的 gas。

要构建你自己的 paymaster,请参阅 paymasters

更多说明

ERC-7562 验证规则

为了处理 UserOperations 的捆绑包,捆绑者在每个操作发送者上调用 validateUserOp 以检查是否可以执行该操作。 但是,捆绑者无法保证区块链的状态在验证阶段之后保持不变。 为了克服这个问题,ERC-7562 提出了一组对 EVM 代码的限制,以便捆绑者(或节点运营商)免受意外的状态更改。

这些规则概述了由规范内存池处理的操作的要求。

账户可以在验证阶段访问自己的存储,他们可能会以非直接的方式轻松违反 ERC-7562 存储访问规则。 例如,大多数账户在验证签名时从存储中访问其公钥,从而限制了拥有为其他账户验证操作的账户的能力(例如,通过 ERC-1271)

尽管任何违反此类规则的账户仍可能由私有捆绑者处理,但开发人员应牢记依赖私有基础设施而不是 无需许可的 执行的中心化权衡。

← 概述

账户 →

  • 原文链接: docs.openzeppelin.com/co...
  • 登链社区 AI 助手,为大家转译优秀英文文章,如有翻译不通的地方,还请包涵~
点赞 0
收藏 0
分享
本文参与登链社区写作激励计划 ,好文好收益,欢迎正在阅读的你也加入。

0 条评论

请先 登录 后评论
OpenZeppelin
OpenZeppelin
江湖只有他的大名,没有他的介绍。