메인 콘텐츠로 건너뛰기

목적 및 범위

이 페이지는 StableNet의 Ethereum Virtual Machine(EVM) 실행 레이어에 대한 세부사항을 제공하며, 인터프리터 아키텍처, opcode 실행 메커니즘, 점프 테이블, 가스 미터링, 컨트랙트 호출 처리에 중점을 둡니다.
트랜잭션이 실행 파이프라인에 진입하는 방법에 대한 정보는 트랜잭션 라이프사이클을 참조하세요.
EVM 실행을 래핑하는 상태 전환 모델은 상태 전환 및 가스을 참조하세요.
StableNet의 특정 가스 가격 정책은 가스 수수료 정책을 참조하세요.

EVM 아키텍처

EVM은 바이트코드를 실행하고 상태 변경을 관리하는 스택 기반 가상 머신으로 구현됩니다.
핵심 구성 요소는 여러 주요 구조로 구성됩니다.
아키텍처 개요: EVM 구성 요소 계층 구조

EVM 구조

EVM 구조체는 실행에 필요한 모든 컨텍스트를 포함합니다.
FieldTypePurpose
ContextBlockContextBlock-level information (coinbase, gas limit, block number, timestamp 등)
TxContextTxContextTransaction-level information (origin, gas price, blob hashes)
StateDBStateDBAccount 및 storage 상태 인터페이스
depthint현재 호출 스택 깊이 (최대 1024)
chainConfig*params.ChainConfig체인 구성
chainRulesparams.Rules현재 블록에 대한 포크 규칙
ConfigConfigVM 구성 (tracer, ExtraEips, NoBaseFee 등)
interpreter*EVMInterpreter바이트코드 인터프리터
abortatomic.Bool비동기 중단 플래그
callGasTempuint64CALL 계열 opcode용 임시 가스 계산 공간

EVMInterpreter 구조

인터프리터는 점프 테이블을 사용하여 바이트코드를 실행합니다.
FieldTypePurpose
evm*EVM상위 EVM 참조
table*JumpTable256개 opcode 정의 배열
hashercrypto.KeccakStateKECCAK256 opcode용 해시 인스턴스
hasherBufcommon.Hash해시 결과 버퍼
readOnlyboolSTATICCALL 여부 플래그
returnData[]byte마지막 호출의 반환 데이터

ScopeContext 구조

ScopeContext는 호출 단위 실행 리소스를 보유합니다.
이 구조는 각 컨트랙트 실행마다 생성되며 모든 opcode 실행 함수에 전달되어 스택과 메모리에 대한 접근을 제공합니다.

인터프리터 루프

EVMInterpreter.Run()의 핵심 실행 루프는 바이트코드 명령을 하나씩 처리합니다. 인터프리터 루프 실행 흐름

스택 및 메모리 관리

EVM은 실행 중 피연산자에 스택을 사용하고 데이터 저장을 위해 확장 가능한 메모리를 사용합니다.

스택 구현

Stack은 256비트 정수로 구성된 제한 배열입니다.
ComponentDescription
Structure[]uint256.Int, 최대 크기 1024
Pool호출 간 재사용을 위한 sync.Pool
Operationspush, pop, peek, swap, dup
Validation각 opcode 실행 전 검증
스택은 각 opcode 실행 전에 다음을 보장합니다.
  • stack.len() >= operation.minStack
  • stack.len() <= operation.maxStack

메모리 구현

Memory는 32바이트 워드 단위로 확장되는 바이트 배열입니다.
ComponentDescription
Storage[]byte
Gas TrackinglastGasCost로 누적 확장 비용 추적
OperationsSet, Set32, Resize, GetPtr, GetCopy
Cost Model3 * words + words² / 512
메모리 확장 가스 계산:
newMemSizeWords = (newMemSize + 31) / 32
newTotalFee = 3 * newMemSizeWords + newMemSizeWords² / 512
expansionCost = newTotalFee - lastGasCost

주요 실행 단계

  1. 초기화
    • 호출 깊이 증가
    • STATICCALL이면 readOnly 설정
    • returnData 초기화
    • 새로운 Stack, Memory 생성
    • ScopeContext 구성
  2. Opcode 가져오기
    • 프로그램 카운터에서 opcode 로드
  3. 스택 검증
    • 언더플로우 및 오버플로우 검사
  4. 가스 소비
    • 고정 가스 차감
    • 필요 시 동적 가스 계산
    • 메모리 확장 가스 적용
  5. 실행
    • opcode 실행 함수 호출
  6. 프로그램 카운터 업데이트
    • JUMP 계열이 아니면 pc++

점프 테이블 및 Opcode

점프 테이블은 256개의 opcode를 실행 함수, 가스 비용, 스택 요구사항에 매핑합니다.
포크에 따라 서로 다른 명령 세트가 선택됩니다.

포크별 명령 세트

Instruction SetForkFeatures
frontierFrontier기본 opcode
homesteadHomesteadDELEGATECALL
byzantiumByzantiumSTATICCALL, REVERT
constantinopleConstantinopleCREATE2
istanbulIstanbul가스 재조정
berlinBerlinEIP-2929
londonLondonBASEFEE
shanghaiShanghaiPUSH0
cancunCancunBLOB 계열
anzeonAnzeonLondon + Shanghai + 일부 Cancun (blob 제외)
점프 테이블은 체인 규칙을 기반으로 NewEVMInterpreter()에서 선택됩니다.

컨트랙트 호출

EVM은 CALL, DELEGATECALL, STATICCALL, CREATE, CREATE2를 지원합니다.

호출 시 주요 처리

  • 호출 깊이 제한 1024
  • Anzeon: 값 전송 대상 제한
  • 블랙리스트 검사
  • 상태 스냅샷 생성 및 오류 시 롤백
  • 트레이서 이벤트 호출

프리컴파일된 컨트랙트

AddressContractPurpose
0x01ecrecoverECDSA 복구
0x02sha256해시
0x03ripemd160해시
0x04identity데이터 복사
0x05modexp모듈러 지수
0x06–0x08bn256페어링 연산
0x09blake2F압축
0xb00001blsPoPAnzeon BLS PoP

네이티브 관리자 컨트랙트(Anzeon)

StableNet은 시스템 수준 작업을 위해 네이티브 Go 구현 컨트랙트를 제공합니다.
AddressContractPurpose
0xb00002NativeCoinManager잔액 직접 조작
0xb00003AccountManager계정 추가 데이터 관리
이들은 일반 CALL 흐름에 통합되며 StateDB와 직접 상호작용합니다.

가스 미터링

가스는 다음 단계에서 계산됩니다.
  • 고유 가스
  • 메모리 확장 가스
  • opcode 동적 가스
  • 실행 후 환불
환불 상한:
  • London 이전: gasUsed / 2
  • London 이후: gasUsed / 5

오류 처리

Error TypeBehaviorExample
Consensus트랜잭션 무효ErrNonceTooLow
Execution가스 전부 소모ErrOutOfGas
Revert상태 롤백, 가스 일부 환불ErrExecutionReverted
Internal발생 불가ErrGasUintOverflow
REVERT opcode는 상태를 되돌리고 반환 데이터를 유지합니다.