> ## Documentation Index
> Fetch the complete documentation index at: https://docs.monad.xyz/llms.txt
> Use this file to discover all available pages before exploring further.

# Gas 定价

> 一笔典型 Monad 交易估算的美元成本,以及 gas 费用的计算方式。

## 摘要

与以太坊一样,Monad 根据交易的复杂度对处理交易进行收费。复杂度以 **gas** 为单位计量。

本页面总结了 gas 的收费方式,即交易的 gas 与用户必须支付的 MON 数量之间的转换关系。 单独的 [Opcode 定价](/zh/developer-essentials/opcode-pricing) 页面描述了每个 opcode 以 gas 为单位的费用。

| 功能               | 详情                                                                                                          |
| ---------------- | ----------------------------------------------------------------------------------------------------------- |
| **收取的 gas**      | 交易收取的 gas 是 **Gas Limit**。[讨论](#gas-limit-not-gas-used)                                                     |
| **每 gas 单价**     | 兼容 EIP-1559,即每单位 gas 支付的价格是系统控制的 base fee 与用户指定的优先费之和。[讨论](#eip-1559-compatibility)                         |
| **Base fee**     | Base fee(即 `base_price_per_gas`)遵循一个动态控制器,类似于 EIP-1559 的控制器,但增长更慢、下降更快。[详情](#base_price_per_gas-controller) |
| **最低 base fee**  | 100 MON-gwei(`100 * 10^-9 MON`)                                                                             |
| **典型成本**         | 一笔典型的 200,000 gas 交易在最低 base fee 下约需 **\$0.0005**(约 0.02 MON)。[计算示例](#how-much-does-a-transaction-cost)     |
| **区块 Gas Limit** | 150M gas                                                                                                    |
| **交易 Gas Limit** | 30M gas                                                                                                     |
| **Opcode 定价**    | 参见 [Opcode 定价](/zh/developer-essentials/opcode-pricing)                                                     |
| **交易排序**         | 默认的 Monad 客户端行为是根据优先 gas 拍卖(按总 gas 价格降序)对交易进行排序。                                                            |

<Note>
  这些变更在 [Monad 初始规范提案](https://category-labs.github.io/category-research/monad-initial-spec-proposal.pdf)中正式涵盖。
</Note>

## 一笔交易需要多少费用?

在 Monad 上,一笔典型的 200,000 gas 交易在最低 base fee 为 100 MON-gwei 时约需 **\$0.0005**;
一次简单的 MON 转账(21,000 gas)约需 **\$0.00005**,不到一美分的一小部分。费用以 MON 支付,
因此这些美元金额只是近似值;MON 金额是精确的。

一笔交易的费用等于所收取的 gas 乘以每单位 gas 的价格。在 100 MON-gwei 的最低 base fee 且不付
优先费时,一笔 200,000 gas 的交易需要 0.02 MON,约合 \$0.0005:

$$
\text{fee} = \text{gas limit} \times \text{price per gas} = 200{,}000 \times \left(100 \times 10^{-9}\ \text{MON}\right) = 0.02\ \text{MON}
$$

200,000 gas 是 swap 或类似合约调用的常见参考规模;交易的实际 gas 取决于其具体行为。下表列出
了一些代表性规模。

| 交易          | Gas Limit | 成本(MON)      | 成本(美元,约)    |
| ----------- | --------- | ------------ | ----------- |
| 原生 MON 转账   | 21,000    | 0.0021 MON   | \~\$0.00005 |
| ERC-20 代币转账 | \~65,000  | \~0.0065 MON | \~\$0.00016 |
| 典型 DEX swap | \~200,000 | \~0.02 MON   | \~\$0.0005  |

<Note>
  Monad 按您设置的 **gas limit** 计费,而不是按实际使用的 gas
  ([详情](#gas-limit-not-gas-used)),因此这些金额不会像基于已用 gas 的估算那样在执行后上升。
  当 base fee 处于下限时,这些是您最多需要支付的金额。在持续的网络负载下,base fee 可能会
  超过 100 MON-gwei(参见 [base fee 控制器](#base_price_per_gas-controller))。
  原生 MON 转账始终恰好使用 21,000 gas;代币转账和 swap 的 gas 因合约而异。
</Note>

## Gas 定义

用户中一个常见的困惑点是交易的 **gas**(工作单位)和交易的 **gas price**(每单位工作以原生代币计的价格)之间的区别。

| 功能                             | 定义                                                                                             |
| ------------------------------ | ---------------------------------------------------------------------------------------------- |
| **Gas**                        | 一个工作单位。Gas 衡量网络处理某个操作所需的工作量。<br /><br /> 由于网络有多种资源(网络带宽、CPU、SSD 带宽和状态增长),gas 本质上是将多个维度投影为单一维度。 |
| **Gas Price(price\_per\_gas)** | 处理一单位 gas 所支付的**价格**(以原生代币计)。                                                                  |
| **Gas Limit**                  | 交易允许消耗的**最大 gas 单位数**。                                                                         |

## Gas Limit,而非 Gas Usage

在 Monad 中,交易收取的 gas 是交易中设置的 Gas Limit,而不是执行过程中使用的 gas。

这是为了支持异步执行而做出的设计决定。在异步执行下,leader 在执行前构建区块 (并且验证者对区块有效性投票)。

如果协议按 `gas_used` 收费,用户可以提交一个具有较大 `gas_limit` 但实际消耗很少 gas 的交易。 该交易将占用区块 Gas Limit 的大量空间,但为占用该空间支付的费用很少,从而打开了 DOS 攻击向量。

```text theme={null}
gas_paid = gas_limit * price_per_gas
```

## EIP-1559 兼容性

Monad 支持 EIP-1559。

EIP-1559(类型 2)交易具有参数 `priority_price_per_gas` 和 `max_price_per_gas`, 与 `base_price_per_gas`(每个区块都会变化的系统参数)一起,决定交易的 gas 竞价:

```text theme={null}
price_per_gas = min(base_price_per_gas + priority_price_per_gas, max_price_per_gas)
```

说明:

* `base_price_per_gas` 是每个区块都会变化的系统参数。同一区块中的每笔交易都将具有相同的 `base_price_per_gas`
* 用户在签署交易时指定 `priority_price_per_gas` 和 `max_price_per_gas`
* 由于同一区块中每个人都将支付相同的 `base_price_per_gas`,`priority_price_per_gas` 是用户为其交易优先级而多付费用的方式。
* 由于用户不决定 `base_price_per_gas`,`max_price_per_gas` 是一种保障措施,限制了他们最终可能支付的金额。当然,如果该值设置得过低,交易将不会被选择包含。

[这篇](https://www.blocknative.com/blog/eip-1559-fees)文章提供了关于 EIP-1559 gas 定价的另一个很好的解释。

## `base_price_per_gas` 控制器

Monad 对 `base_price_per_gas` 使用了与以太坊不同的控制器:

$$
\begin{align*}
\mathrm{block\_gas}_{k} &= \sum\limits_{\mathrm{tx} \in \mathrm{block}_k}\mathrm{gas\_limit}_\mathrm{tx}\\
\mathrm{base\_price\_per\_gas}_{k+1} &= \max\left\{\text{min\_base\_price\_per\_gas}, \mathrm{base\_price\_per\_gas}_k \cdot \exp \left(
\eta_k \cdot \frac{\mathrm{block\_gas}_{k} - \text{target}}{\text{block\_gas\_limit} - \text{target}}
\right) \right\} \\
\eta_k &= \frac{\text{max\_step\_size}\cdot\epsilon}{\epsilon+\sqrt{\mathrm{moment}_k - \mathrm{trend}_k^2}} \\
\mathrm{trend}_{k+1} &= \beta\cdot \mathrm{trend}_k + (1-\beta)\cdot \left(\text{target}-\mathrm{block\_gas}_{k} \right) \\
\mathrm{moment}_{k+1} &= \beta\cdot \mathrm{moment}_k + (1-\beta)\cdot \left(\text{target}-\mathrm{block\_gas}_{k} \right)^2
\end{align*}
$$

这个归纳公式从以下起点开始:

$$
\begin{align*}
\mathrm{base\_price\_per\_gas}_{0} &= 0 \\
\mathrm{moment}_{0} &= 0 \\
\mathrm{trend}_{0} &= 0
\end{align*}
$$

参数如下:

$$
\begin{align*}
\mathrm{max\_step\_size} &= 1/28 \\
\mathrm{target} &= 160\text{M}\ \text{(80\% full)}\ \\
\beta &= 0.96 \\
\epsilon &= \mathrm{target} = 160\text{M}
\end{align*}
$$

并且

$$
\text{min\_base\_price\_per\_gas} = 100\ \text{MON-gwei}\ (100 \times 10^{-9}\ \text{MON})
$$

与以太坊的 `base_price_per_gas` 控制器相比,该控制器增长更慢,下降更快。 这是为了避免由于 `base_price_per_gas` 定价过高而导致的区块空间利用率不足。

有关 Monad 控制器设计考虑因素和行为的更全面讨论,请查看 Category Labs 的[这篇](https://www.category.xyz/blogs/redesigning-a-base-fee-for-monad)博客文章。

## 对开发者的建议

### 如果 Gas Limit 是常量,请显式设置

许多链上操作具有固定的 gas 成本。最简单的例子是,原生代币的转账始终花费 21,000 gas, 但还有许多其他情况。

对于交易的 gas 成本预先已知的操作,建议在将交易交给钱包之前直接设置它。这具有几个好处:

* 它降低了延迟并为用户提供了更好的体验,因为钱包不必调用 `eth_estimateGas` 并等待 RPC 响应。
* 它保留了对用户体验的更大控制权,避免了钱包在某些特殊情况下设置高 Gas Limit 的情况, 如下面的警告所述。

<Warning>
  一些钱包(包括 MetaMask)已知具有以下行为:当 `eth_estimateGas` 被调用且合约调用回滚时, 它们会将此交易的 Gas Limit 设置为一个非常高的值。

  这是钱包放弃设置 Gas Limit 并接受执行时的任何 Gas Usage 的方式。但这在 Monad 上没有意义, 因为 Monad 会收取完整的 Gas Limit。

  只要用户试图做一些不可能的事情,就会发生合约调用回滚。例如,用户可能试图铸造一个已经铸造完毕的 NFT。

  如果 Gas Limit 预先已知,那么显式设置它是最佳实践,因为这可以确保钱包不会意外处理此情况。
</Warning>
