---
title: "用户操作费用的估算与收取方式"
description: "了解 bundler 的激励机制、bundler 如何估算用户操作的 gas 费用，以及发送方如何在 Arbitrum 和 Optimism 上估算用户操作费用。"
---

# 用户操作费用的估算与收取方式

在我们关于 ERC-4337 gas 估算的系列文章中，从[ERC-4337 gas 估算的工作原理](https://www.alchemy.com/blog/erc-4337-gas-estimation)开始，我们讨论了“User Operation Flow”的第 2 步 `eth\_estimateUserOperationGas`，以及其中的复杂问题，包括[gas token 转账问题](https://www.alchemy.com/blog/dummy-signatures-and-gas-token-transfers)和[估算 L2 gas](https://www.alchemy.com/blog/l2-gas-and-signature-aggregators)的挑战。本文将聚焦于该流程的第 3 步，详细说明 gas 费用是如何被估算和收取的。

出于本文讨论的目的，我们假设所处理的链支持 EIP-1559。理解 [EIP-1559](https://eips.ethereum.org/EIPS/eip-1559) 是掌握 user operation 中费用字段的必要前提。

User operation 具有与 EIP-1559 交易相同的费用字段：

- `maxFeePerGas`：用户愿意支付的最高总金额（base fee \+ priority fee）
- `maxPriorityFeePerGas`：用户愿意支付的最高 priority fee，即“小费”

Entry point 使用以下公式，根据这两个字段[计算最终的 gas price](https://github.com/eth-infinitism/account-abstraction/blob/033b4be2a606defd5cd5226bdde3afcea21db5fa/contracts/core/EntryPoint.sol#L600)：

可以看到，`maxFeePerGas` 对 gas price 起到绝对上限的作用，而 `maxPriorityFeePerGas` 则是在区块 base fee 之上的小费。

## Bundle 交易

当 [bundler 向 entry point 发送 bundle 交易](https://www.alchemy.com/overviews/what-is-a-bundler)时，它们同样受 EIP-1559 机制所决定的 gas price 约束。Bundler 会设置 `maxFeePerGas` 和 `maxPriorityFeePerGas`。最终的 gas price 由这两个值以及交易所在区块的 base fee 共同计算得出。

Bundler 以某一 gas price 提交交易，随后按照该 bundle 中每个 user operation 设定的（可能不同的）gas price 获得补偿。如果 user operation 的 gas price 更高，bundler 就能盈利；否则 bundler 在该 user operation 上会产生亏损。`maxPriorityFeePerGas` 不仅是给 bundler 的小费，也帮助 bundler 弥补其为使 bundle 交易被打包而支付给 block builder 的小费（除非该 bundler 本身就是 builder）。

### Bundler 如何获得经济激励？

Bundling 可能是一项成本高昂的任务，主要原因是为确保 bundler 安全所需的复杂模拟。为了让 bundler 能够收回这些计算成本，并激励形成一个健康的 user operation 市场（从而通过缩短打包时间来改善用户体验），必须以超额收入的形式为 bundler 提供经济激励。

这种收入可以有多种形式：priority fee、MEV，以及链下协议。

#### 1. Priority fee

Bundler 可能会要求发送方在其 operation 中包含高于 bundler 自身交易所支付的 priority fee。在拥堵严重时段，希望提高被打包概率的发送方可以提高其 priority fee 出价。

#### 2. MEV 收入

由于 bundler 在 bundle 中拥有排序权，因此可以从 mempool 中的 operation 中提取 MEV。它们可以自由地进行 back-run 和夹子攻击（sandwich）来获取这部分利润。

#### 3. 链下协议

Bundler 可以运行私有 mempool（具备 MEV 保护等功能），并与 user operation 发送方达成链下协议。费用将通过某种链下机制来强制执行。

为确保网络健康，我们认为对大多数 user operation 而言，（1）是必需的选项。

并非每种 user operation 类型都存在可提取的正向 MEV。如果只依赖这一激励方式，bundler 将不会接受大多数 user operation。链下协议具有中心化倾向，许多用户会希望避免这种方式。因此剩下的就是 Priority Fee。

Alchemy 的 Rundler 目前定义了一个用于 bundling 的动态 priority fee 要求。该费用基于当前估算的网络费用。如果某个 user operation 的出价低于估算的网络费用加上 bundler 的少量额外小费，它将不会被打包，而是留在 mempool 中。

<CalloutBlock>

💡 当 P2P 网络出现后，情况将更接近于一个市场，类似于交易的情形。发送方可以分析先前被打包的 user operation，以估算最低价格。Bundler 可以根据当前 mempool 的内容为用户提供提示。MEV 搜索者也可能从 mempool 中挑选出关联 MEV 较高、但 gas 出价较低（甚至为零）的 user operation（甚至可能要求搜索者向其[付费](https://github.com/blunt-instruments/MevWallet)）。这种 MEV 市场可以由 [Orderflow Auction](https://frontier.tech/the-orderflow-auction-design-space)（OFA）来促成。

</CalloutBlock>

## Bundler 如何估算 gas 费用？

在[打包](https://www.alchemy.com/overviews/what-is-account-abstraction)之前，bundler 必须对自己将要提交的费用进行估算，以确保该 bundle 交易能通过 bundle 市场被打包上链。通常 bundler 会为下一个区块的打包做准备，并出一个合理的价格以确保被打包。

为估算 base fee，bundler 可以查询网络当前区块的 base fee。通常建议至少加上 25% 的额外余量（这是接下来 2 个区块中费用可能上涨的最大幅度），以确保交易不会被卡住。

为估算 priority fee，bundler 可以使用 `eth\_maxPriorityFeePerGas`。与 base fee 类似，建议在此基础上加上一定比例的额外余量，以确保交易能被及时处理。

估算出这些费用后，bundler 便可以查询 mempool，筛选出出价足以被纳入（包括给 bundler 的少量“小费”）的 user operation。

<CalloutBlock>

💡 本节描述的是通过 bundle 市场提交 bundle 的 bundler。Bundler 必须使用 bundle 市场（例如 [Flashbots](https://www.alchemy.com/dapps/flashbots)），以确保其 user operation bundle 不会被抢跑（front-run），从而导致上链回滚，使 bundler 自行承担 gas 费用。

如果 bundler 本身是 block builder 的一部分，情况则有所不同。

</CalloutBlock>

### 发送方应如何估算 user operation 费用？

在客户端，发送方必须估算打包所需的费用。如果估算过低，其 user operation 可能会卡在 mempool 中；如果估算过高，尤其是 priority fee 部分，则可能为打包支付过多费用。

**在 p2p 网络出现之前，与 Rundler 交互时，我们建议采用以下方法：**

1. 估算 base fee。加上你可以接受的余量，以确保在价格向不利方向变动时仍能被打包。我们建议至少加 25%。
1. 使用 `eth\_maxPriorityFeePerGas` 估算 priority fee。加上你可以接受的余量。我们建议至少加 10%。
1. 在 priority fee 上加上与网络相关的 bundler“小费”余量。
1. 将 priority fee 加到 base fee 上得到 `maxFeePerGas`，`maxPriorityFeePerGas` 是第 2 步估算出的费用。

### Arbitrum 费用估算

Arbitrum 的 sequencer 会忽略 priority fee，`eth\_maxPriorityFeePerGas ` 始终返回 0。为了补偿 bundler，我们要求 priority fee 为 bundler 估算的最大 base fee 的固定百分比。目前我们设定为 5%。

### Optimism 费用估算

Optimism 存在一个边界情况，在我们此前关于[估算 L2 gas](https://www.alchemy.com/blog/l2-gas-and-signature-aggregators)的文章中已有描述，这会影响费用估算。

在 Optimism 上，我们设置 `maxPriorityFeePerGas = l1\_gas / l2\_base\_fee`。然而，由于在正常的 Optimism 交易中，priority fee 只作用于 L2 gas 部分，其数值可能比 L2 base fee 高出几个数量级。因此，我们要求 bundle 的 priority fee 为估算 base fee 的固定百分比。目前我们设定为 5%。

<CalloutBlock>

💡 关于 Alchemy 的 [bundler 费用逻辑](https://www.alchemy.com/docs/reference/bundler-api-quickstart)的更多细节，可以在我们的文档中找到。

</CalloutBlock>

## P2p mempool

一旦 P2P mempool 投入运行，将出现一个独立的 user operation 费用市场。这可能会大大简化 user operation 的费用估算。用户无需像上文那样对 priority fee 进行静态计算，而是可以使用费用历史来估算自己的出价。此时，单个 bundler 选择 user operation 所依据的具体标准已不再重要，重要的只是_某个_ bundler 认为该 user operation 值得打包。

Rundler 将支持一个类似于 `eth\_feeHistory` 的 `rundler\_userOperationFeeHistory` 方法（或类似方法，也可能被标准化），用户可以据此查询，基于此前已打包的 operation 来估算自己的出价。

🦀

## 继续阅读

如果你错过了本系列关于 ERC-4337 gas 估算技术探讨的前三篇文章，可以了解 ERC-4337 gas 估算的工作原理，以及我们如何克服各种难题，为 user operation 提供准确的 gas 估算。

- [ERC-4337 Gas 估算的工作原理](https://www.alchemy.com/blog/erc-4337-gas-estimation)
- [Dummy 签名与 Gas Token 转账](https://www.alchemy.com/blog/dummy-signatures-and-gas-token-transfers)
- [L2 Gas 与签名聚合器](https://www.alchemy.com/blog/l2-gas-and-signature-aggregators)
