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

# 상태 전환 및 가스

## 목적 및 범위

이 페이지는 StableNet의 상태 전환 프로세스를 문서화합니다. 이는 트랜잭션이 블록체인 상태를 수정하는 메커니즘입니다. 가스 메커니즘, 트랜잭션 검증, 실행 흐름, 수수료 위임 및 Anzeon 네트워크의 가스 정책을 포함한 StableNet 특정 기능을 다룹니다.

EVM 실행 내부에 대한 정보는 [EVM 실행](/ko/transaction-processing/6.3-evm-execution)을 참조하세요. 가스 수수료 정책 및 가격 책정은 [가스 수수료 정책](/ko/transaction-processing/6.4-gas-fee-policy)을 참조하세요. 트랜잭션 타입 및 인코딩은 [트랜잭션 유형 및 인코딩](/ko/core-architecture/3.5-transaction-types-and-encoding)을 참조하세요.

## 개요

상태 전환은 **단일 트랜잭션을 현재 체인 상태(StateDB)에 적용하는 과정**을 의미합니다.\
`core/state_transition.go`의 `StateTransition` 타입은 이 프로세스를 총괄하며 nonce 검증, 가스 구매, 값 전송, EVM 실행, 가스 환불을 처리합니다. 이 과정은 EVM과 직접 통합되어 컨트랙트 코드를 실행하고 계정 잔액 및 저장소를 업데이트합니다.

## 핵심 데이터 구조

### Message

`Message` 구조체는 상태 처리에 준비된 트랜잭션 데이터를 나타냅니다. 서명된 트랜잭션에서 파생되며, 유효 가스 가격과 같은 실행 시점 기준의 계산된 필드를 포함합니다.

```
Message Structure (core/state_transition.go):
- To: recipient address (nil for contract creation)
- From: sender address
- Nonce: transaction nonce
- Value: wei amount to transfer
- GasLimit: maximum gas available
- GasPrice: effective gas price paid (baseFee 및 tip 반영 결과)
- GasFeeCap: max fee per gas (EIP-1559)
- GasTipCap: priority fee per gas (EIP-1559)
- Data: call data or init code
- AccessList: EIP-2930 access list
- SetCodeAuthorizations: EIP-7702 code delegation list
- FeePayer: optional fee payer address (StableNet fee delegation)
- BlobGasFeeCap, BlobHashes: EIP-4844 blob fields
- SkipAccountChecks: bypass validation (for eth_call)
```

### StateTransition

`StateTransition` 구조체는 단일 트랜잭션의 전환 과정을 관리하고 가스 소비를 추적합니다.

| Field          | Type         | Purpose                             |
| -------------- | ------------ | ----------------------------------- |
| `gp`           | `*GasPool`   | Block-level gas limit tracker       |
| `msg`          | `*Message`   | Transaction message being processed |
| `gasRemaining` | `uint64`     | Unspent gas during execution        |
| `initialGas`   | `uint64`     | Starting gas limit                  |
| `state`        | `vm.StateDB` | State database interface            |
| `evm`          | `*vm.EVM`    | EVM instance for execution          |

## 상태 전환 흐름

**다이어그램: 완전한 상태 전환 흐름**

## 트랜잭션을 메시지로 변환

트랜잭션은 실행 전에 `TransactionToMessage()`를 통해 `Message`로 변환됩니다. 이 단계에서 유효 가스 가격이 계산되며, Anzeon 네트워크의 거버넌스 기반 가스 팁 정책이 적용됩니다.

### 가스 팁 오버라이드(Anzeon)

Anzeon 네트워크에서는 승인되지 않은 계정에 대해 블록 헤더에 포함된 네트워크 강제 가스 팁이 적용되며, 승인된 계정만이 트랜잭션 자체의 팁을 사용할 수 있습니다.

```
if headerGasTip != nil:
    if !statedb.IsAuthorized(sender):
        gasTipCap = headerGasTip // Override with mandatory tip
    else:
        gasTipCap = tx.GasTipCap() // Use transaction's tip
```

EIP-1559 트랜잭션의 유효 가스 가격은 `min(gasTipCap + baseFee, gasFeeCap)` 기준으로 계산됩니다.

## 실행 전 검증

### preCheck() 메서드

`preCheck()`는 상태 변경 이전에 트랜잭션이 합의 규칙을 충족하는지 검증합니다.

| Check             | Error                                | Description                          |
| ----------------- | ------------------------------------ | ------------------------------------ |
| Nonce correctness | `ErrNonceTooLow` / `ErrNonceTooHigh` | Nonce must match state nonce exactly |
| Nonce overflow    | `ErrNonceMax`                        | Nonce cannot be `uint64` max value   |
| Sender is EOA     | `ErrSenderNoEOA`                     | Sender must not have contract code   |
| Gas fee cap       | `ErrFeeCapTooLow`                    | Fee cap must exceed base fee         |
| Tip sanity        | `ErrTipVeryHigh`                     | Tip cannot exceed 256 bits           |
| Fee cap sanity    | `ErrFeeCapVeryHigh`                  | Fee cap cannot exceed 256 bits       |
| Tip vs cap        | `ErrTipAboveFeeCap`                  | Tip cannot exceed fee cap            |
| Blob validity     | `ErrBlobTxCreate`                    | Blob txs cannot be contract creation |
| Blob fee cap      | `ErrBlobFeeCapTooLow`                | Blob fee cap must meet minimum       |

### 가스 구매(buyGas)

검증 통과 후 `buyGas()`는 가스 비용을 선차감합니다. 수수료 위임 여부에 따라 차감 주체가 달라집니다.

**다이어그램: 수수료 위임이 있는 가스 구매 흐름**

* **위임 없음:** 발신자가 가스 비용과 값 전송을 모두 부담합니다
* **위임 있음:** FeePayer가 가스를 부담하고 발신자는 값 전송만 부담합니다

## 고유 가스 계산

고유 가스는 트랜잭션이 실행되기 위해 반드시 필요한 최소 가스입니다.

| Component          | Cost                             | Condition                     |
| ------------------ | -------------------------------- | ----------------------------- |
| Base transaction   | 21,000 gas                       | All transactions              |
| Contract creation  | +32,000 gas                      | `to == nil` and Homestead+    |
| Zero byte data     | 4 gas/byte                       | Each zero byte                |
| Non-zero byte data | 16 gas/byte (Istanbul+)          | Each non-zero byte            |
|                    | 68 gas/byte (Frontier–Byzantium) |                               |
| Access list        | 2,400 gas/address                | Per address                   |
|                    | 1,900 gas/key                    | Per storage key               |
| Init code size     | 2 gas/word                       | Contract creation (Shanghai+) |

`gasRemaining < intrinsicGas`인 경우 트랜잭션은 `ErrIntrinsicGas`로 즉시 거부됩니다.

## EVM 실행 통합

고유 가스를 차감한 이후 남은 가스가 EVM 실행에 사용됩니다.

### 컨트랙트 호출

```
state.SetNonce(sender, nonce + 1)
ret, gasRemaining, err = evm.Call(
    sender,
    *msg.To,
    msg.Data,
    gasRemaining,
    value
)
```

호출 트랜잭션의 경우 nonce는 실행 전에 증가합니다.

## 블랙리스트 검증(Anzeon)

Anzeon 네트워크에서는 실행 전에 GovValidator가 관리하는 블랙리스트를 검사합니다.

```
if rules.IsAnzeon:
    if state.IsBlacklisted(msg.From):
        return ErrBlacklistedAccount{msg.From}
    if msg.To != nil && state.IsBlacklisted(*msg.To):
        return ErrBlacklistedAccount{*msg.To}
```

수수료 위임이 활성화된 경우 FeePayer 또한 검사 대상입니다.

```
if msg.FeePayer != nil && rules.IsAnzeon:
    if state.IsBlacklisted(*msg.FeePayer):
        return ErrBlacklistedAccount{*msg.FeePayer}
```

## 가스 환불 및 수수료 분배

### 가스 환불 계산

| Fork       | Refund Cap    | Constant                       |
| ---------- | ------------- | ------------------------------ |
| Pre-London | `gasUsed / 2` | `params.RefundQuotient`        |
| London+    | `gasUsed / 5` | `params.RefundQuotientEIP3529` |

환불은 실제 가스를 지불한 계정(FeePayer 또는 발신자)에게 반환됩니다.

### 수수료 분배

StableNet의 Anzeon 네트워크에서는 검증자가 전체 유효 가스 가격에 해당하는 수수료를 직접 수령합니다.

```
effectivePrice := msg.GasPrice
fee := gasUsed * effectivePrice
state.AddBalance(coinbase, fee)
```

* `msg.GasPrice`는 `TransactionToMessage` 단계에서 계산된 최종 유효 가스 가격입니다
* Ethereum London과 달리 baseFee 소각 단계가 존재하지 않습니다
* 이는 스테이블코인의 1:1 법정화폐 담보 원칙을 유지하기 위한 설계입니다

## 수수료 위임 세부사항

### 잔액 검증

수수료 위임 시 잔액 검증은 명확히 분리됩니다.

### 가스 비용 계산

```
feeCheck = gasLimit * gasFeeCap
actualDebit = gasLimit * gasPrice
if Anzeon && isFeeDelegation:
    feeCheck = gasLimit * gasPrice
```

### 전송 로그 생성

Anzeon에서는 네이티브 코인 이동에 대해 명시적인 Transfer 로그를 생성합니다.

```
func (evm *EVM) AddTransferLog(sender, recipient common.Address, amount *uint256.Int) {
    if !evm.chainConfig.AnzeonEnabled() {
        return
    }
    // Transfer 로그 기록
}
```

## 실행 결과

`ExecutionResult`는 상태 전환 결과를 표현합니다.

| Field         | Type     | Description                    |
| ------------- | -------- | ------------------------------ |
| `UsedGas`     | `uint64` | Gas consumed excluding refunds |
| `RefundedGas` | `uint64` | Refunded gas                   |
| `Err`         | `error`  | EVM execution error            |
| `ReturnData`  | `[]byte` | EVM return data                |

* **합의 오류:** 트랜잭션 자체가 거부됨
* **EVM 오류:** 트랜잭션은 포함되나 실패 상태로 기록됨

## 블록 처리와의 통합

상태 전환은 `StateProcessor`가 블록 처리 중 순차적으로 호출합니다.

**다이어그램: 블록 처리 루프**

`applyTransaction()`은 EVM 컨텍스트 생성, 실행, 영수증 생성을 일괄 조정합니다.

## 오류 처리

| Error                   | Code Location        | Meaning             |
| ----------------------- | -------------------- | ------------------- |
| `ErrNonceTooLow`        | state\_transition.go | Already executed    |
| `ErrNonceTooHigh`       | state\_transition.go | Nonce gap           |
| `ErrInsufficientFunds`  | state\_transition.go | Cannot afford cost  |
| `ErrIntrinsicGas`       | state\_transition.go | Gas limit too low   |
| `ErrGasLimitReached`    | gas\_pool.go         | Block gas exhausted |
| `ErrBlacklistedAccount` | state\_transition.go | Blacklisted         |
| `ErrTxTypeNotSupported` | types/transaction.go | Fork not active     |

이러한 오류는 블록 검증 단계에서 bad block 판단의 원인이 됩니다.

## 상태 전환 테스트

StableNet은 `t8n` 상태 전환 테스트 도구를 포함합니다.

```
evm t8n --input.alloc=alloc.json \
        --input.txs=txs.json \
        --input.env=env.json \
        --state.fork=Shanghai
```

이 도구는 상태 전환의 결정론적 검증을 위해 사전 상태, 사후 상태 루트, 영수증을 출력합니다.
