Layer2 开发教程 # 3 账户抽象

  • skysys.eth
  • 更新于 2024-05-22 19:37
  • 阅读 384

记录一下个人学习笔记,参考网上资料,本文主要是我个人学习笔记,内容出处均在文末注明。部分内容源自ChatGPT,如文中有错误还请不吝赐教。【文本】标识的内容文本为作者个人观点,仅供参考。上一篇文章提到了zkSync原生支持账户抽象,本文对账户抽象进行详细说明。传统的以太坊网络中,主要存

记录一下个人学习笔记,参考网上资料,本文主要是我个人学习笔记,内容出处均在文末注明。部分内容源自 ChatGPT,如文中有错误还请不吝赐教。【文本】标识的内容文本为作者个人观点,仅供参考。

上一篇文章提到了 zkSync 原生支持账户抽象,本文对账户抽象进行详细说明。

传统的以太坊网络中,主要存在两类账户:

  • 外部拥有账户(EOA):由私钥控制,可以直接发起交易。
  • 合约账户:由部署在区块链上的智能合约代码控制,能够执行更复杂的操作。

尽管这两类账户都能持有和转移资产,它们的功能和限制各不相同: EOA:1)免费创建。2)能够直接发起交易。3)主要进行 ETH 和代币转移。4)由一对密钥控制。

合约账户:1)部署需消耗 gas。2)仅在接收到交易时能发起交易。【意思就是合约交互也需要EOA触发】3)可以执行多样化的逻辑,如多签钱包,社交恢复,代付 gas 费用等。4)无私钥,完全由代码逻辑控制。

账户抽象(AA)将 EOA 和合约账户的特性统一,允许账户既能自主发起交易,又能承载复杂的逻辑。这极大地扩展了区块链账户的应用范围,使得例如智能合约钱包等应用成为可能,同时简化了用户的操作流程和为用户的资金安全提供了更安全的保障。

zkSync 中的账户抽象

zkSync 上的帐户抽象协议与 EIP4337 非常相似,而 zkSync 期望在其链中有着更高的效率和用户体验,zkSync 实现了原生的账户抽象,在关键部分做了不一样的处理:【关于ERC4337协议的内容后续我会在其他文章详细阐述】

  • 实现层面:zkSync Era 的账户抽象在协议层面进行集成,EIP4337 则避免了在协议层面的实现。【EIP4337协议不用修改共识协议】
  • 账户类型及 Paymasters 支持:zkSync Era 中智能合约账户和付款人都是一等公民,提供一个统一的账户模型来实现账户抽象化,所有账户(包括 EOA)都支持 Paymasters。
  • 交易处理
    • 在 EIP4337 的工作流程中,用户发起交易,将交易提交至专用内存池 (UserOperation mempool) 中并由打包者 (Bundlers) 转化为基础交易,然后交由 EntryPoint 负责合约验证和 Paymaster 合约负责为用户操作支付交易费用,最终完成交易操作。
    • 相比之下,在 zkSync Era 上,有一个统一的内存池 (mempool),用于来自外部拥有账户 (EOA) 和智能合约账户的交易。在 zkSync Era,Operator 承担了捆绑交易的角色,无论账户类型如何,并将它们发送到 Bootloader(类似于 EntryPoint 合约),从而产生单个内存池 (mempool) 和交易流。

【也就是说 zkSync 协议层面支持,不用维护专门的 mempool 和 打包者,以太坊之后可能也会采用这种方案,在未来的分叉中支持】

IAccount

每个智能合约账户按照官方建议遵从 IAccount 接口实现【这个和ERC4337差不多捏】,包含以下 5 个关键方法:

  • validateTransaction(必须):确认交易逻辑是否满足账户规则,如果错误应回滚,若是成功则继续执行交易流程

  • executeTransaction(必须):收取手续费后调用,执行交易内容

  • payForTransaction(可选):不使用 Paymaster 将会直接采用正常手续费扣除方案(tx.gasprice * tx.gasLimit)

  • prepareForPaymaster(可选):设置支付的方案,如:ERC-20 代币替代 Gas 支付(参考 官方案例

  • executeTransactionFromOutside(可选):该函数处理是否从外部发起交易,不是强制实现的,但官方鼓励这样做,因为在优先模式的情况下(例如,如果 Operator 没有响应),则可以考虑从 EOA 帐户开始交易。

// SPDX-License-Identifier: MIT
pragma solidity 0.8.20;

import "../libraries/TransactionHelper.sol";

bytes4 constant ACCOUNT_VALIDATION_SUCCESS_MAGIC = IAccount.validateTransaction.selector;

interface IAccount {
    function validateTransaction(
        bytes32 _txHash,
        bytes32 _suggestedSignedHash,
        Transaction calldata _transaction
    ) external payable returns (bytes4 magic);

    function executeTransaction(
        bytes32 _txHash,
        bytes32 _suggestedSignedHash,
        Transaction calldata _transaction
    ) external payable;

    function executeTransactionFromOutside(Transaction calldata _transaction) external payable;

    function payForTransaction(
        bytes32 _txHash,
        bytes32 _suggestedSignedHash,
        Transaction calldata _transaction
    ) external payable;

    function prepareForPaymaster(
        bytes32 _txHash,
        bytes32 _possibleSignedHash,
        Transaction calldata _transaction
    ) external payable;
}

IPaymaster

Paymaster:zkSync 中的支付中继 在 zkSync 的账户抽象化框架内,Paymaster 作为中心角色,使得交易发起者可以通过第三方支付交易费用,或使用非原生代币(如 ERC-20 代币)支付费用。

  • 用户发起交易时,可以指定一个 Paymaster 合约来负责支付交易费用。
  • Paymaster 合约在接到支付请求后,会根据内部逻辑验证请求的有效性,并决定是否支付交易费用。
  • 如果 Paymaster 同意支付,它会向网络支付所需的费用,使用户交易得以执行。
  1. validateAndPayForPaymasterTransaction(必须):由引导程序调用,以验证支付方是否同意支付交易的费用。如果支付人愿意为交易付款,则此它必须至少发送 tx.gasprice * tx.gasLimit 给 Operator。若验证成功,则返回 magic 值 PAYMASTER_VALIDATION_SUCCESS_MAGIC 和交易上下文 context(最多 1024 字节长度的字节数组,将传递给 postTransaction 方法)。

  2. postTransaction(可选):在事务执行后调用。请注意,与 EIP4337 不同,zkSync 抽象账户不能保证一定会调用此方法:比如事务因 out of gas 错误而失败,则不会调用此方法。它的参数分别为:的上下文 _context、交易对象 _transaction、交易哈希 _txHash,由 EOAs 签名的交易哈希 _suggestedSignedHash,交易执行的结果 _txResult,以及付款人可能收到 Gas 退款的最大值 _maxRefundedGas

contract MyPaymaster is IPaymaster {
    uint256 constant PRICE_FOR_PAYING_FEES = 1;

    address public allowedToken;

    modifier onlyBootloader() {
        require(msg.sender == BOOTLOADER_FORMAL_ADDRESS, "Only bootloader can call this method");
        // Continue execution if called from the bootloader.
        _;
    }

    constructor(address _erc20) {
        allowedToken = _erc20;
    }

    function validateAndPayForPaymasterTransaction  (
        bytes32,
        bytes32,
        Transaction calldata _transaction
    ) external payable onlyBootloader returns (bytes4 magic, bytes memory context) {
        // 自定义处理GAS支付逻辑
    }

    function postTransaction (
        bytes calldata _context,
        Transaction calldata _transaction,
        bytes32,
        bytes32,
        ExecutionResult _txResult,
        uint256 _maxRefundedGas
    ) external payable onlyBootloader override {
    }

    receive() external payable {}
}

应用场景

  • 代币支付交易费:用户可以使用特定的代币支付交易费,而 Paymaster 负责将这些代币转换成网络接受的费用形式。
  • NFT 权限给予:想象一下持有某个 NFT 时,执行交易没有手续费的特权,可以参考官方具有想象力的 Demo
  • 企业和应用赞助/用户免费交易:对于希望吸引用户参与的应用,企业或应用开发者可以作为 Paymaster,为其用户群体支付交易费用,降低用户参与门槛。【Gas代付,但要注意DoS攻击】
  • 智能合约钱包:结合用户友好的操作界面和后台的智能合约逻辑,提供更智能的资产管理和保护策略。
  • 去中心化金融(DeFi)应用:用户可以直接从其账户中执行复杂的金融操作,如借贷、杠杆交易等,无需转移到外部合约。
  • 自动化支付和订阅:定制智能合约以自动执行定期支付,支持订阅服务和定期费用支付,无需用户手动介入。
  • 多签名和安全控制:实现更复杂的访问和控制逻辑,如多签名验证,为企业和团队管理提供更高级的安全措施。

Reference

  1. WTF zkSync 极简入门: 3. 账户抽象(AA)
点赞 0
收藏 0
分享
本文参与登链社区写作激励计划 ,好文好收益,欢迎正在阅读的你也加入。

0 条评论

请先 登录 后评论
skysys.eth
skysys.eth
0xfd8D...FD45
区块链研究员