메인 콘텐츠로 건너뛰기

목적 및 범위

이 페이지는 StableNet의 상태 전환 프로세스를 문서화합니다. 이는 트랜잭션이 블록체인 상태를 수정하는 메커니즘입니다. 가스 메커니즘, 트랜잭션 검증, 실행 흐름, 수수료 위임 및 Anzeon 네트워크의 가스 정책을 포함한 StableNet 특정 기능을 다룹니다. EVM 실행 내부에 대한 정보는 EVM 실행을 참조하세요. 가스 수수료 정책 및 가격 책정은 가스 수수료 정책을 참조하세요. 트랜잭션 타입 및 인코딩은 트랜잭션 유형 및 인코딩을 참조하세요.

개요

상태 전환은 단일 트랜잭션을 현재 체인 상태(StateDB)에 적용하는 과정을 의미합니다.
core/state_transition.goStateTransition 타입은 이 프로세스를 총괄하며 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 구조체는 단일 트랜잭션의 전환 과정을 관리하고 가스 소비를 추적합니다.
FieldTypePurpose
gp*GasPoolBlock-level gas limit tracker
msg*MessageTransaction message being processed
gasRemaininguint64Unspent gas during execution
initialGasuint64Starting gas limit
statevm.StateDBState database interface
evm*vm.EVMEVM 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()는 상태 변경 이전에 트랜잭션이 합의 규칙을 충족하는지 검증합니다.
CheckErrorDescription
Nonce correctnessErrNonceTooLow / ErrNonceTooHighNonce must match state nonce exactly
Nonce overflowErrNonceMaxNonce cannot be uint64 max value
Sender is EOAErrSenderNoEOASender must not have contract code
Gas fee capErrFeeCapTooLowFee cap must exceed base fee
Tip sanityErrTipVeryHighTip cannot exceed 256 bits
Fee cap sanityErrFeeCapVeryHighFee cap cannot exceed 256 bits
Tip vs capErrTipAboveFeeCapTip cannot exceed fee cap
Blob validityErrBlobTxCreateBlob txs cannot be contract creation
Blob fee capErrBlobFeeCapTooLowBlob fee cap must meet minimum

가스 구매(buyGas)

검증 통과 후 buyGas()는 가스 비용을 선차감합니다. 수수료 위임 여부에 따라 차감 주체가 달라집니다. 다이어그램: 수수료 위임이 있는 가스 구매 흐름
  • 위임 없음: 발신자가 가스 비용과 값 전송을 모두 부담합니다
  • 위임 있음: FeePayer가 가스를 부담하고 발신자는 값 전송만 부담합니다

고유 가스 계산

고유 가스는 트랜잭션이 실행되기 위해 반드시 필요한 최소 가스입니다.
ComponentCostCondition
Base transaction21,000 gasAll transactions
Contract creation+32,000 gasto == nil and Homestead+
Zero byte data4 gas/byteEach zero byte
Non-zero byte data16 gas/byte (Istanbul+)Each non-zero byte
68 gas/byte (Frontier–Byzantium)
Access list2,400 gas/addressPer address
1,900 gas/keyPer storage key
Init code size2 gas/wordContract 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}

가스 환불 및 수수료 분배

가스 환불 계산

ForkRefund CapConstant
Pre-LondongasUsed / 2params.RefundQuotient
London+gasUsed / 5params.RefundQuotientEIP3529
환불은 실제 가스를 지불한 계정(FeePayer 또는 발신자)에게 반환됩니다.

수수료 분배

StableNet의 Anzeon 네트워크에서는 검증자가 전체 유효 가스 가격에 해당하는 수수료를 직접 수령합니다.
effectivePrice := msg.GasPrice
fee := gasUsed * effectivePrice
state.AddBalance(coinbase, fee)
  • msg.GasPriceTransactionToMessage 단계에서 계산된 최종 유효 가스 가격입니다
  • 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는 상태 전환 결과를 표현합니다.
FieldTypeDescription
UsedGasuint64Gas consumed excluding refunds
RefundedGasuint64Refunded gas
ErrerrorEVM execution error
ReturnData[]byteEVM return data
  • 합의 오류: 트랜잭션 자체가 거부됨
  • EVM 오류: 트랜잭션은 포함되나 실패 상태로 기록됨

블록 처리와의 통합

상태 전환은 StateProcessor가 블록 처리 중 순차적으로 호출합니다. 다이어그램: 블록 처리 루프 applyTransaction()은 EVM 컨텍스트 생성, 실행, 영수증 생성을 일괄 조정합니다.

오류 처리

ErrorCode LocationMeaning
ErrNonceTooLowstate_transition.goAlready executed
ErrNonceTooHighstate_transition.goNonce gap
ErrInsufficientFundsstate_transition.goCannot afford cost
ErrIntrinsicGasstate_transition.goGas limit too low
ErrGasLimitReachedgas_pool.goBlock gas exhausted
ErrBlacklistedAccountstate_transition.goBlacklisted
ErrTxTypeNotSupportedtypes/transaction.goFork not active
이러한 오류는 블록 검증 단계에서 bad block 판단의 원인이 됩니다.

상태 전환 테스트

StableNet은 t8n 상태 전환 테스트 도구를 포함합니다.
evm t8n --input.alloc=alloc.json \
        --input.txs=txs.json \
        --input.env=env.json \
        --state.fork=Shanghai
이 도구는 상태 전환의 결정론적 검증을 위해 사전 상태, 사후 상태 루트, 영수증을 출력합니다.