> ## 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.

# State Transition and Gas

## Purpose and Scope

This page documents the state transition process in StableNet, which defines how a transaction modifies the blockchain state.\
It covers gas mechanics, transaction validation, execution flow, fee delegation, and StableNet-specific features, including the gas policy of the Anzeon network.

For details on internal EVM execution, see [EVM Execution](/en/transaction-processing/6.3-evm-execution).\
For gas fee policy and pricing, see [Gas Fee Policy](/en/transaction-processing/6.4-gas-fee-policy).\
For transaction types and encoding, see [Transaction Types and Encoding](/en/core-architecture/3.5-transaction-types-and-encoding).

## Overview

A state transition refers to **the process of applying a single transaction to the current chain state (StateDB)**.\
The `StateTransition` type in `core/state_transition.go` orchestrates this process, handling nonce validation, gas purchase, value transfer, EVM execution, and gas refunds.\
This process is tightly integrated with the EVM to execute contract code and update account balances and storage.

## Core Data Structures

### Message

The `Message` structure represents transaction data prepared for state processing.\
It is derived from a signed transaction and includes execution-time computed fields such as the effective gas price.

```
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 (result after baseFee and 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

The `StateTransition` structure manages the lifecycle of a single transaction and tracks gas consumption.

| 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          |

## State Transition Flow

**Diagram: Complete State Transition Flow**

## Converting a Transaction to a Message

Before execution, a transaction is converted into a `Message` via `TransactionToMessage()`.\
At this stage, the effective gas price is calculated, and the governance-based gas tip policy of the Anzeon network is applied.

### Gas Tip Override (Anzeon)

In the Anzeon network, a network-enforced gas tip included in the block header is applied to unauthorized accounts, while only authorized accounts may use the tip specified in the transaction itself.

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

For EIP-1559 transactions, the effective gas price is calculated as\
`min(gasTipCap + baseFee, gasFeeCap)`.

## Pre-Execution Validation

### preCheck() Method

The `preCheck()` method validates whether a transaction satisfies consensus rules before any state changes occur.

| Check             | Error                                | Description                               |
| ----------------- | ------------------------------------ | ----------------------------------------- |
| Nonce correctness | `ErrNonceTooLow` / `ErrNonceTooHigh` | Nonce must exactly match the state nonce  |
| 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 the 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 the fee cap             |
| Blob validity     | `ErrBlobTxCreate`                    | Blob transactions cannot create contracts |
| Blob fee cap      | `ErrBlobFeeCapTooLow`                | Blob fee cap must meet the minimum        |

### Gas Purchase (buyGas)

After validation, `buyGas()` deducts gas costs upfront.\
The paying account depends on whether fee delegation is used.

**Diagram: Gas Purchase Flow with Fee Delegation**

* **Without delegation:** The sender pays both gas costs and value transfer
* **With delegation:** The FeePayer pays for gas, while the sender pays only for value transfer

## Intrinsic Gas Calculation

Intrinsic gas is the minimum gas required for a transaction to be executed.

| 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+) |

If `gasRemaining < intrinsicGas`, the transaction is immediately rejected with `ErrIntrinsicGas`.

## EVM Execution Integration

After intrinsic gas is deducted, the remaining gas is used for EVM execution.

### Contract Calls

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

For call transactions, the nonce is incremented before execution.

## Blacklist Validation (Anzeon)

In the Anzeon network, a blacklist managed by `GovValidator` is checked before execution.

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

When fee delegation is enabled, the FeePayer is also subject to blacklist checks.

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

## Gas Refunds and Fee Distribution

### Gas Refund Calculation

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

Refunds are returned to the account that actually paid for gas (either the FeePayer or the sender).

### Fee Distribution

In StableNet’s Anzeon network, validators receive the full fee corresponding to the effective gas price.

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

* `msg.GasPrice` is the final effective gas price computed during `TransactionToMessage`
* Unlike Ethereum London, there is no baseFee burn
* This design preserves the 1:1 fiat backing principle of the stablecoin

## Fee Delegation Details

### Balance Validation

With fee delegation, balance checks are clearly separated between sender and FeePayer.

### Gas Cost Calculation

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

### Transfer Log Generation

In Anzeon, explicit Transfer logs are generated for native coin movements.

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

## Execution Result

`ExecutionResult` represents the outcome of a state transition.

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

* **Consensus errors:** The transaction itself is rejected
* **EVM errors:** The transaction is included but recorded as failed

## Integration with Block Processing

State transitions are invoked sequentially by the `StateProcessor` during block processing.

**Diagram: Block Processing Loop**

`applyTransaction()` coordinates EVM context creation, execution, and receipt generation.

## Error Handling

| 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     |

These errors may cause a block to be considered invalid during block verification.

## State Transition Testing

StableNet includes the `t8n` state transition testing tool.

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

This tool outputs the pre-state, post-state root, and receipts for deterministic verification of state transitions.
