# Gas 与手续费

> NeuroChain 手续费如何运作——uNRO 单位、每项操作的 gas、EIP-1559 风格的基础费用、50% 销毁、区块 gas 预算与 mempool 规则，并附节点中的确切常量。

Source: https://docs.nro.world/zh/learn/gas

链上每个金额都是以 **uNRO** 计的整数：`1 NRO = 1 000 000 uNRO`。

手续费等于 **gas 单位 × gas 价格**，其中 gas 价格以每 gas 单位多少 uNRO 计：

```
手续费 (uNRO) = gas_units × gas_price
```

## 每项操作的 gas

| 操作 | Gas 单位 | 常量 |
|-----------|-----------|----------|
| 转账 | 21 | `GAS_BASE_TRANSFER` |
| 合约调用（带调用数据的 `.app` 地址） | 预付 50，之后按实际用量结算——见下文 | `GAS_CONTRACT_CALL` |
| 合约部署 | 10 000，固定 | `DEPLOY_GAS_UNITS` |
| 付费名称转让（`.node`、`.vault`、`.agent`） | 固定 **100 uNRO** 费用 | `NFT_TRANSFER_FEE` |
| 系统操作（质押、注册、水龙头、治理标记） | 0 | — |

在 1 uNRO 的最低 gas 价格下，一笔转账花费 **21 uNRO = 0.000021 NRO**。

### 合约调用

一次调用预先收取 50 个 gas 单位。随后合约在 WASM 解释器中运行，预算为 **1 000 000 fuel**（`MAX_CONTRACT_GAS`）。运行结束后，节点把实际消耗的 fuel 换算为 gas 单位——`ceil(fuel / 20 000)`，至少为 1——并退还或补收差额。

换算比率为 `NEUROCHAIN_FUEL_PER_GAS_UNIT`（默认 20 000），其取值使得耗尽 fuel 的调用恰好花费预付的 50 个单位。存储读写等 host 函数会额外消耗 fuel；见 [NeuroWASM gas 与限制](/zh/neurowasm/gas-limits)。

如果合约触发 trap 或耗尽 fuel，其存储变更会被回滚，金额也不会转出——但 **nonce 和手续费仍会被消耗**，因此失败的调用无法被免费重放。

## 基础费用

协议维护一个随需求变化的**基础费用**，风格与以太坊的 EIP-1559 相同：

- 它从每 gas 单位 1 uNRO 起步，且永远不会低于这个下限（`MIN_GAS_PRICE`）。
- 每个区块之后，它朝着区块 gas 预算一半（5 000 单位）的目标移动：区块用量更多时上调，更少时下调，每个区块最多变动 12.5%。只要变动，至少变动 1 uNRO，因此拥堵过后它会一路回到下限。
- **`gas_price` 低于当前基础费用的交易会被每个验证者拒绝。** 这一点在共识中强制执行，而不只是由 mempool 检查，因此提议者无法让一笔出价过低的交易绕过其他验证者。

发送前先读取当前值：

```bash
curl -s "$NODE_RPC/api/v1/gas/estimate"
```

```json
{
  "base_fee": 1,
  "gas_base_transfer": 21,
  "gas_contract_call": 50,
  "estimated_transfer": 21,
  "estimated_contract": 50,
  "estimated_transfer_human": "0.000021",
  "estimated_contract_human": "0.00005",
  "total_burned": 0,
  "nft_transfer_fee": 100,
  "nft_transfer_fee_human": "0.0001"
}
```

Gateway 在 `$GATEWAY/api/v1/gas/estimate` 提供相同的数据。Web 钱包发送 `gas_price = base_fee × 1.5`，以领先于上涨的基础费用。

## 手续费去向

![手续费流向：每笔交易的手续费被拆分，50% 销毁，50% 计入区块提议者；基础费用设定最低 gas 价格](/diagrams/zh/fee-flow.svg)

每个区块之后，其手续费总和被拆分：

- **50% 被销毁**（`BURN_RATE_BPS = 5000`），并累加到 `total_burned`。
- **50% 归区块提议者。**

`.app` 和 `.vault` 名称的注册费全额销毁；`.node` 的注册费则转为质押。见[地址](./addresses)。

## 区块预算与 mempool

| 规则 | 默认值 | 覆盖方式 | 说明 |
|------|---------|----------|-------|
| 每区块 gas | 10 000 单位 | 治理参数 `max_block_gas` | 1 到 1 000 000 000；在节点启动时读取 |
| 每区块交易数 | 500 | — | `MAX_BLOCK_TXS` |
| Mempool 容量 | 10 000 | `NEUROCHAIN_MAX_MEMPOOL` | 满了以后，新交易会挤出出价最低的待处理交易——仅当它出价更高时 |
| 在 mempool 中的时长 | 60 秒 | — | 到时仍未被打包的待处理交易会被丢弃 |
| 每个发送方的待处理交易数 | 64 | `NEUROCHAIN_MAX_PENDING_PER_ACCOUNT` | 同一地址的更多交易会被拒绝 |
| 按手续费替换 | +10% | `NEUROCHAIN_RBF_MIN_BUMP_PCT` | 重新发送相同的 `(from, nonce)` 时，只有 gas 价格至少高出这么多，才会替换待处理的那笔 |
| Mempool 价格下限 | 0（关闭） | `NEUROCHAIN_MIN_FEE_PER_GAS` | 在基础费用之上可选的入口下限 |

提议者按手续费顺序取待处理交易（同一发送方的交易保持 nonce 顺序），跳过低于基础费用的交易，并在区块预算填满后停止添加。选择时，它把每笔转账计为 21 个单位，每次 `.app` 调用计为 50 个单位。

## 常量一览

| 常量 | 默认值 | 含义 |
|----------|---------|---------|
| `UNRO_PER_NRO` | 1 000 000 | 1 NRO 中的 uNRO 数 |
| `GAS_BASE_TRANSFER` | 21 | 一笔转账的 gas 单位 |
| `GAS_CONTRACT_CALL` | 50 | 合约调用预付的 gas 单位 |
| `DEPLOY_GAS_UNITS` | 10 000 | 一次部署的 gas 单位 |
| `MAX_CONTRACT_GAS` | 1 000 000 | 每次合约调用的 fuel 预算 |
| `NEUROCHAIN_FUEL_PER_GAS_UNIT` | 20 000 | 结算调用时每 gas 单位对应的 fuel |
| `MIN_GAS_PRICE` | 1 | 基础费用下限，每 gas 单位 uNRO |
| `MAX_BLOCK_GAS` | 10 000 | 每区块的 gas 单位 |
| `BURN_RATE_BPS` | 5 000 | 被销毁的手续费比例，以基点计（50%） |
| `NFT_TRANSFER_FEE` | 100 | 转让付费名称的固定费用，uNRO |
