목적 및 범위
이 페이지는 StableNet의 Ethereum Virtual Machine(EVM) 실행 레이어에 대한 세부사항을 제공하며, 인터프리터 아키텍처, opcode 실행 메커니즘, 점프 테이블, 가스 미터링, 컨트랙트 호출 처리에 중점을 둡니다.트랜잭션이 실행 파이프라인에 진입하는 방법에 대한 정보는 트랜잭션 라이프사이클을 참조하세요.
EVM 실행을 래핑하는 상태 전환 모델은 상태 전환 및 가스을 참조하세요.
StableNet의 특정 가스 가격 정책은 가스 수수료 정책을 참조하세요.
EVM 아키텍처
EVM은 바이트코드를 실행하고 상태 변경을 관리하는 스택 기반 가상 머신으로 구현됩니다.핵심 구성 요소는 여러 주요 구조로 구성됩니다. 아키텍처 개요: EVM 구성 요소 계층 구조
EVM 구조
EVM 구조체는 실행에 필요한 모든 컨텍스트를 포함합니다.
| Field | Type | Purpose |
|---|---|---|
Context | BlockContext | Block-level information (coinbase, gas limit, block number, timestamp 등) |
TxContext | TxContext | Transaction-level information (origin, gas price, blob hashes) |
StateDB | StateDB | Account 및 storage 상태 인터페이스 |
depth | int | 현재 호출 스택 깊이 (최대 1024) |
chainConfig | *params.ChainConfig | 체인 구성 |
chainRules | params.Rules | 현재 블록에 대한 포크 규칙 |
Config | Config | VM 구성 (tracer, ExtraEips, NoBaseFee 등) |
interpreter | *EVMInterpreter | 바이트코드 인터프리터 |
abort | atomic.Bool | 비동기 중단 플래그 |
callGasTemp | uint64 | CALL 계열 opcode용 임시 가스 계산 공간 |
EVMInterpreter 구조
인터프리터는 점프 테이블을 사용하여 바이트코드를 실행합니다.| Field | Type | Purpose |
|---|---|---|
evm | *EVM | 상위 EVM 참조 |
table | *JumpTable | 256개 opcode 정의 배열 |
hasher | crypto.KeccakState | KECCAK256 opcode용 해시 인스턴스 |
hasherBuf | common.Hash | 해시 결과 버퍼 |
readOnly | bool | STATICCALL 여부 플래그 |
returnData | []byte | 마지막 호출의 반환 데이터 |
ScopeContext 구조
ScopeContext는 호출 단위 실행 리소스를 보유합니다.이 구조는 각 컨트랙트 실행마다 생성되며 모든 opcode 실행 함수에 전달되어 스택과 메모리에 대한 접근을 제공합니다.
인터프리터 루프
EVMInterpreter.Run()의 핵심 실행 루프는 바이트코드 명령을 하나씩 처리합니다.
인터프리터 루프 실행 흐름
스택 및 메모리 관리
EVM은 실행 중 피연산자에 스택을 사용하고 데이터 저장을 위해 확장 가능한 메모리를 사용합니다.스택 구현
Stack은 256비트 정수로 구성된 제한 배열입니다.
| Component | Description |
|---|---|
| Structure | []uint256.Int, 최대 크기 1024 |
| Pool | 호출 간 재사용을 위한 sync.Pool |
| Operations | push, pop, peek, swap, dup |
| Validation | 각 opcode 실행 전 검증 |
stack.len() >= operation.minStackstack.len() <= operation.maxStack
메모리 구현
Memory는 32바이트 워드 단위로 확장되는 바이트 배열입니다.
| Component | Description |
|---|---|
| Storage | []byte |
| Gas Tracking | lastGasCost로 누적 확장 비용 추적 |
| Operations | Set, Set32, Resize, GetPtr, GetCopy |
| Cost Model | 3 * words + words² / 512 |
주요 실행 단계
- 초기화
- 호출 깊이 증가
- STATICCALL이면
readOnly설정 returnData초기화- 새로운
Stack,Memory생성 ScopeContext구성
- Opcode 가져오기
- 프로그램 카운터에서 opcode 로드
- 스택 검증
- 언더플로우 및 오버플로우 검사
- 가스 소비
- 고정 가스 차감
- 필요 시 동적 가스 계산
- 메모리 확장 가스 적용
- 실행
- opcode 실행 함수 호출
- 프로그램 카운터 업데이트
- JUMP 계열이 아니면
pc++
- JUMP 계열이 아니면
점프 테이블 및 Opcode
점프 테이블은 256개의 opcode를 실행 함수, 가스 비용, 스택 요구사항에 매핑합니다.포크에 따라 서로 다른 명령 세트가 선택됩니다.
포크별 명령 세트
| Instruction Set | Fork | Features |
|---|---|---|
| frontier | Frontier | 기본 opcode |
| homestead | Homestead | DELEGATECALL |
| byzantium | Byzantium | STATICCALL, REVERT |
| constantinople | Constantinople | CREATE2 |
| istanbul | Istanbul | 가스 재조정 |
| berlin | Berlin | EIP-2929 |
| london | London | BASEFEE |
| shanghai | Shanghai | PUSH0 |
| cancun | Cancun | BLOB 계열 |
| anzeon | Anzeon | London + Shanghai + 일부 Cancun (blob 제외) |
NewEVMInterpreter()에서 선택됩니다.
컨트랙트 호출
EVM은 CALL, DELEGATECALL, STATICCALL, CREATE, CREATE2를 지원합니다.호출 시 주요 처리
- 호출 깊이 제한 1024
- Anzeon: 값 전송 대상 제한
- 블랙리스트 검사
- 상태 스냅샷 생성 및 오류 시 롤백
- 트레이서 이벤트 호출
프리컴파일된 컨트랙트
| Address | Contract | Purpose |
|---|---|---|
| 0x01 | ecrecover | ECDSA 복구 |
| 0x02 | sha256 | 해시 |
| 0x03 | ripemd160 | 해시 |
| 0x04 | identity | 데이터 복사 |
| 0x05 | modexp | 모듈러 지수 |
| 0x06–0x08 | bn256 | 페어링 연산 |
| 0x09 | blake2F | 압축 |
| 0xb00001 | blsPoP | Anzeon BLS PoP |
네이티브 관리자 컨트랙트(Anzeon)
StableNet은 시스템 수준 작업을 위해 네이티브 Go 구현 컨트랙트를 제공합니다.| Address | Contract | Purpose |
|---|---|---|
| 0xb00002 | NativeCoinManager | 잔액 직접 조작 |
| 0xb00003 | AccountManager | 계정 추가 데이터 관리 |
가스 미터링
가스는 다음 단계에서 계산됩니다.- 고유 가스
- 메모리 확장 가스
- opcode 동적 가스
- 실행 후 환불
- London 이전:
gasUsed / 2 - London 이후:
gasUsed / 5
오류 처리
| Error Type | Behavior | Example |
|---|---|---|
| Consensus | 트랜잭션 무효 | ErrNonceTooLow |
| Execution | 가스 전부 소모 | ErrOutOfGas |
| Revert | 상태 롤백, 가스 일부 환불 | ErrExecutionReverted |
| Internal | 발생 불가 | ErrGasUintOverflow |

