# 가스와 수수료

> NeuroChain 수수료의 동작 방식 — uNRO 단위, 작업별 가스, EIP-1559 방식의 기본 수수료, 50% 소각, 블록 가스 예산과 mempool 규칙을 노드의 정확한 상수와 함께 설명합니다.

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

체인상의 모든 금액은 **uNRO** 단위의 정수입니다: `1 NRO = 1 000 000 uNRO`.

수수료는 **가스 단위 × 가스 가격**이며, 가스 가격은 가스 단위당 uNRO로 표시합니다:

```
수수료 (uNRO) = gas_units × gas_price
```

## 작업별 가스

| 작업 | 가스 단위 | 상수 |
|------|-----------|------|
| 전송 | 21 | `GAS_BASE_TRANSFER` |
| 컨트랙트 호출 (호출 데이터가 있는 `.app` 주소) | 50 선불, 이후 실제 사용량으로 정산 — 아래 참고 | `GAS_CONTRACT_CALL` |
| 컨트랙트 배포 | 10 000, 고정 | `DEPLOY_GAS_UNITS` |
| 유료 이름 양도 (`.node`, `.vault`, `.agent`) | 고정 수수료 **100 uNRO** | `NFT_TRANSFER_FEE` |
| 시스템 작업 (스테이킹, 등록, faucet, 거버넌스 마커) | 0 | — |

최소 가스 가격 1 uNRO 기준으로 전송 비용은 **21 uNRO = 0.000021 NRO**입니다.

### 컨트랙트 호출

호출 시 50 가스 단위가 먼저 청구됩니다. 그런 다음 컨트랙트는 **1 000 000 fuel**(`MAX_CONTRACT_GAS`)의 예산으로 WASM 인터프리터에서 실행됩니다. 실행이 끝나면 노드는 실제로 소모된 fuel을 가스 단위로 환산하고 — `ceil(fuel / 20 000)`, 최소 1 — 차액을 환불하거나 추가로 청구합니다.

환산 비율은 `NEUROCHAIN_FUEL_PER_GAS_UNIT`(기본값 20 000)이며, fuel을 모두 소진한 호출의 비용이 선불로 낸 50 단위와 정확히 같아지도록 정해졌습니다. 스토리지 읽기와 쓰기 같은 호스트 함수는 추가 fuel을 소모합니다. [NeuroWASM 가스와 제한](/ko/neurowasm/gas-limits)을 참고하세요.

컨트랙트가 trap되거나 fuel이 소진되면 스토리지 변경은 롤백되고 금액은 전송되지 않습니다 — 하지만 **nonce와 수수료는 그대로 소비되므로**, 실패한 호출을 무료로 재전송할 수 없습니다.

## 기본 수수료

프로토콜은 Ethereum의 EIP-1559 방식으로 수요에 따라 움직이는 **기본 수수료**(base fee)를 유지합니다:

- 가스 단위당 1 uNRO에서 시작하며, 이 하한(`MIN_GAS_PRICE`) 아래로는 절대 내려가지 않습니다.
- 각 블록 이후, 블록 가스 예산의 절반(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/api/v1/gas/estimate`에서 같은 데이터를 제공합니다. 웹 지갑은 기본 수수료 상승에 앞서도록 `gas_price = base_fee × 1.5`로 전송합니다.

## 수수료가 가는 곳

![수수료 흐름: 각 트랜잭션의 수수료는 나뉘어 50%는 소각되고 50%는 블록 제안자에게 지급됩니다. 기본 수수료가 최소 가스 가격을 정합니다](/diagrams/ko/fee-flow.svg)

각 블록 이후, 블록 수수료의 합계는 다음과 같이 나뉩니다:

- **50%는 소각**(`BURN_RATE_BPS = 5000`)되어 누적 `total_burned`에 더해집니다.
- **50%는 블록 제안자에게 지급됩니다.**

`.app`과 `.vault` 이름의 등록 수수료는 전액 소각되며, `.node` 등록은 대신 스테이크가 됩니다. [주소](./addresses)를 참고하세요.

## 블록 예산과 mempool

| 규칙 | 기본값 | 재정의 | 비고 |
|------|--------|--------|------|
| 블록당 가스 | 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)`를 다시 보내면, 가스 가격이 최소 이만큼 높을 때만 대기 중인 트랜잭션을 교체함 |
| 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_CONTRACT_CALL` | 50 | 컨트랙트 호출에 선불로 내는 가스 단위 |
| `DEPLOY_GAS_UNITS` | 10 000 | 배포의 가스 단위 |
| `MAX_CONTRACT_GAS` | 1 000 000 | 컨트랙트 호출당 fuel 예산 |
| `NEUROCHAIN_FUEL_PER_GAS_UNIT` | 20 000 | 호출 정산 시 가스 단위당 fuel |
| `MIN_GAS_PRICE` | 1 | 기본 수수료 하한, 가스 단위당 uNRO |
| `MAX_BLOCK_GAS` | 10 000 | 블록당 가스 단위 |
| `BURN_RATE_BPS` | 5 000 | 소각되는 수수료 비율, 베이시스 포인트 단위 (50%) |
| `NFT_TRANSFER_FEE` | 100 | 유료 이름 양도 고정 수수료, uNRO |
