本文介绍了zkSync Era中交易处理的流程,包括L1和L2两种交易的处理方式。L2交易处理流程包含解析、资源计算、账户模型交互、Nonce验证、手续费收取、Paymaster处理、执行和退款等步骤。L1交易处理的主要区别在于没有验证步骤,并且不支持从L1交易发起部署交易。
本节介绍如何处理交易。交易处理有两个流程,一个用于 L1 交易,一个用于 L2 交易。我们将首先描述后者,因为它更通用,章节 L1 -> L2 交易 将解释前者的差异。
EOA 或 Contract)进行交易处理。负责实现交易处理的模块是 process_transaction。
交易处理从解析交易开始,如 交易格式 中所述。
解析交易后,引导加载程序会计算交易可以花费多少资源。此资源计算包括获取交易的 gas 限制,检查其是否受块的 gas 限制约束,并减去 calldata 和内在 gas 成本。
在继续描述交易处理之前,我们需要介绍此模块中的一个关键抽象:Account models。此接口是 Era 的 IAccount 接口的一个层,用于 Account Abstraction。
此接口提供用于验证交易、执行交易、检查 nonce、支付交易费用以及为 paymaster 做准备的方法。它有两个实现:
EOA:引导加载程序直接实现该接口,就像 Ethereum 会处理从 EOA 发起的交易一样。此处需要的大部分系统工作(签名验证除外)不收费,因为它已包含在内在成本中。Contract:实际合约调用的包装器,用于合约账户。仅在启用 AA 时才允许。引导加载程序执行的第一个验证步骤是检查 nonce 是否未使用。这是通过调用相应的账户模型方法来完成的。对于 EOA,我们使用像 Ethereum 中的那样的增量 nonce。请注意,对于此操作以及许多类似的操作,引导加载程序需要通过 System 访问存储。
然后调用账户模型验证方法。对于 EOA,这将执行 token 转账的余额检查、签名验证和 nonce 增加。在此之后,引导加载程序会检查 nonce 是否已被使用(请注意,对于 EOA,此步骤不执行任何操作,但必须包含在合约账户中)。
下一步是收取费用。这包括计算所需的资金(gas_price * gas_limit),调用账户模型的支付方法,并检查引导加载程序是否实际在其正式地址收到了预期的资金。如果收到的资金多于预期,则会退还多余的资金。
如果交易声明了一个 paymaster(并且启用了 AA),则最后描述的步骤会略有修改。引导加载程序不会调用账户的支付方法,而是调用账户的 paymaster 准备方法。之后,它会调用 paymaster 的验证和支付方法,并存储 paymaster 上下文。在这种情况下,任何多余的资金都将退还给 paymaster。
ZKsyncOS 必须将一些数据发布到结算层,以确保 rollup 的状态可以随时恢复。这就是我们所说的 "pubdata",其中包括块应用后的状态差异和一些必需的 preimage。鉴于提供此数据需要花费金钱,我们需要确保交易有足够的资源来支付其 pubdata 份额。因此,验证的最后一步是收取验证后生成的 pubdata 大小的费用。
验证可能会因多种不同的原因而失败,这些原因在 Errors 模块中的 InvalidTransaction 类型中详细说明。如果验证成功,引导加载程序将继续执行交易。
此步骤很简单:引导加载程序只需调用账户模式的执行方法。
对于 EOA,这包括确定它是正常调用还是部署。在第一种情况下,该调用由 run_single_interaction 助手处理,如 Runner flow 中所述。在部署的情况下,引导加载程序将收取一些额外的内在 gas 并对 init 代码大小执行检查。在此之后,将通过调用 run_till_completion 来处理部署,如 Runner flow 中所述。
交易执行后,引导加载程序会检查是否还有足够的资源用于 pubdata。
交易处理的最后一步是退还未使用的资源。如果是 paymaster,引导加载程序会在退款前调用其 post_op 方法。
总而言之,L2 交易的生命周期可以可视化如下:
L1 交易处理的主要区别在于没有验证步骤。此交易的值是新创建的,因为这些资金现在已锁定在 L1 桥中。目前,不支持来自 L1 交易的部署交易。
- 原文链接: github.com/matter-labs/z...
- 登链社区 AI 助手,为大家转译优秀英文文章,如有翻译不通的地方,还请包涵~
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!