Bitroot블로그
공식 사이트로 돌아가기 ↗
© 2026 Bitroot · 본 사이트의 내용은 일반 정보이며 금융, 투자, 법률 또는 세무 조언이 아닙니다.
편집 기준공식 사이트로 돌아가기
← 전체 글
EVM 기초·2026/10/09·약 4분

클라이언트 속 EVM: 인터프리터, JIT, revm/evmone 개관

실행 클라이언트는 EVM을 교체 가능한 실행기 한 조각으로 취급하고, 그 사이에 상태 접근 인터페이스 한 겹을 둡니다. go-ethereum의 내장 인터프리터와 evmone, revm은 위치가 각기 다르고, 다중 구현 일관성은 명세 테스트 벡터로 보장하며, 인터프리터의 최적화 여지는 디스패치와 gas 계량, 메모리 관리에 집중됩니다.

By Bitroot Core Team · Editorial standards

실행 클라이언트(execution client)는 블록 동기화, 트랜잭션 풀, 상태 저장, JSON-RPC와 합의 연동을 동시에 처리해야 하며, 이더리움 가상 머신(Ethereum Virtual Machine, EVM)은 그중 한 조각일 뿐입니다. EVM은 블록이 어디서 오는지 모르고, 한 트랜잭션의 gas 가격이 어느 규칙으로 정해지는지도 결정하지 않습니다. EVM은 바이트코드, 콜데이터, 실행 환경과 gas를 받아 반환 데이터, 남은 gas, 예외 상태와 상태 변경 집합을 돌려줍니다.

이 경계를 분명히 그어야 go-ethereum, evmone, revm이 왜 서로 다른 위치에 있는지 이해할 수 있습니다. 하나는 클라이언트에 내장된 인터프리터, 하나는 언어를 넘나드는 독립 라이브러리, 하나는 의존성으로 가져다 쓰는 Rust 프레임워크입니다. 아래에서는 범용 클라이언트에 EVM을 끼워 넣는 방식과 다중 구현 일관성을 어떻게 보장하는지만 다루고, 병렬 스케줄링과 다중 엔진 설계는 펼치지 않습니다. 그 부분은 글 끝의 더 읽기를 참고하십시오.

EVM과 클라이언트 나머지 부분의 경계

어느 구현이든 EVM과 호스트 사이의 상호작용은 같은 조작 집합으로 수렴합니다. 계정의 잔액과 nonce, 코드를 읽고, 스토리지 슬롯을 읽고, 과거 블록 해시를 읽습니다. 스토리지 변경을 되쓰고, 로그를 내보내고, 계정을 만들거나 지웁니다. 그리고 gas를 수입하고 지출합니다. 차이는 이 조작 집합이 어떤 형태로 노출되는지뿐입니다.

go-ethereum의 core/vm은 EVM을 구조체 하나에 인터프리터 루프 하나를 더한 형태로 구현합니다. 인터프리터는 fork에 따라 256개 항목을 가진 점프 테이블(jump table)을 고르고, 각 항목에는 실행 함수, 상수 gas, 동적 gas 계산 함수, 스택 높이 제약과 메모리 요구량이 들어 있습니다. 루프의 순서는 오프코드를 가져오고, 스택을 검증하고, 상수 gas를 차감하고, 동적 gas를 계산하고, 필요하면 메모리를 확장하고, 실행 함수를 호출하는 것이며, gas가 부족하면 일괄적으로 ErrOutOfGas를 반환합니다. 상태 접근은 StateDB를 거치고, 블록과 트랜잭션 컨텍스트는 BlockContext와 TxContext를 거칩니다. 고유 gas, nonce 검증, 수수료 차감과 환불 계산은 인터프리터에 없고 상태 전환 계층에서 끝납니다.

revm의 구조는 더 명시적입니다. Evm은 Context와 생성자로 이루어지고, Context는 다시 세 덩어리, 즉 환경(Transaction, Block, Cfg), Journal, Database로 구성됩니다. Database는 필수 메서드가 네 개뿐인 인터페이스입니다. basic은 계정을, code_by_hash는 코드를, storage는 스토리지 슬롯을, block_hash는 과거 블록 해시를 읽습니다. 이렇게 읽어 들인 데이터는 Journal에 캐시되고, Journal은 실행 중의 변경도 함께 기록하며 실행이 끝난 뒤 상태 차이를 돌려줍니다. 인터프리터는 데이터베이스를 직접 건드리지 않고 Host 트레이트를 통해 접근합니다. 이 트레이트는 블록, 트랜잭션, 설정, 데이터베이스와 Journal로 묶여 있으며 sload, sstore, tload, tstore, 계정 로딩, 로그와 자멸을 포괄합니다.

evmone는 이 경계를 C 언어 ABI로 만들어 놓았습니다. evmone는 EVMC(Ethereum Client-VM Connector API)를 구현하는데, 이 인터페이스는 EVM과 클라이언트 사이의 저수준 ABI로 정의되며 클라이언트 쪽에서 EVM이 환경과 상태에 접근하는 방식을 규정합니다. 경계가 C ABI라서 evmone는 다른 언어로 작성한 클라이언트에도 적재될 수 있습니다. Erigon의 회고에 따르면 Erigon은 EVMC를 통해 evmone을 자신의 실행 계층에 연결했고, 인터페이스 오버헤드를 줄이기 위해 C++ 코드 한 겹을 덧씌웠습니다.

세 구현의 위치 차이

구현언어와 라이선스형태상태 인터페이스전형적인 재사용 방식
go-ethereum core/vmGo, 라이브러리 코드는 LGPL-3.0, cmd/ 아래는 GPL-3.0클라이언트 내장 인터프리터StateDBL2 실행 클라이언트로 포크됨, 예: OP Stack의 op-geth
evmoneC++20, Apache-2.0독립 모듈, EVMC로 노출EVMC 호스트 인터페이스Silkworm 등 클라이언트에 실행 모듈로 적재됨
revmRust, MIT라이브러리와 프레임워크, crate 단위로 분리Database와 Host 트레이트Reth, Foundry, Helios 등이 직접 의존성으로 사용하며 L2와 zkVM의 흔한 선택이기도 함

세 가지 형태는 세 가지 엔지니어링 절충에 대응합니다. 내장 인터프리터는 자신의 상태 계층, 점프 테이블, 트레이서와 함께 최적화할 수 있지만 다른 클라이언트가 재사용하기 어렵다는 대가가 따릅니다. 독립 라이브러리는 언어를 넘어 재사용할 수 있지만 공통 인터페이스 한 겹을 반드시 지나야 하고, 인터페이스 양쪽의 호출 오버헤드가 곧 비용입니다. 같은 회고는 EVMC가 설계상 호스트가 EVM을 호출하는 것도, EVM이 호스트를 역으로 호출하는 것도 허용한다고 언급합니다. 후자는 CGo로 Erigon에 연결할 때 상당한 인터페이스 오버헤드를 낳았고, 결국 C++ 코드를 보강해 없애야 했습니다. 이 경험은 가장 빠른 EVM을 클라이언트에 연결하는 일과 클라이언트를 즉시 빠르게 만드는 일이 서로 다른 문제임을 보여 줍니다.

라이브러리 형태의 이득은 생태계 차원에서 더 두드러집니다. revm 문서가 나열한 사용자에는 블록 빌더, Reth와 Helios 같은 클라이언트, Foundry와 Hardhat 같은 도구, 여러 L2와 여러 zkVM 프로젝트가 포함됩니다. 반대로 go-ethereum을 포크하는 노선은 L2 쪽에서 축소 신호가 나타났습니다. Optimism 문서에 따르면 op-geth는 2026년 5월 31일자로 지원이 종료되었고 현재 활성화된 Karst 하드포크도 지원하지 않으며, 주력 실행 클라이언트가 Reth와 revm 기반의 op-reth로 바뀌었습니다.

일관성은 자체 테스트로 나오지 않는다: state test와 다중 클라이언트 테스트

합의는 모든 노드가 같은 바이트코드에 대해 완전히 동일한 상태를 얻을 것을 요구합니다. 어떤 단일 클라이언트 자체 테스트도 자기 일관성만 증명할 뿐, 일관성을 증명하지는 못합니다.

역사에서 불일치의 대가는 수치로 환산할 수 있습니다. 2016년 11월 24일 이더리움은 블록 2686351에서 포크가 발생했습니다. 빈 계정 삭제를 유발하는 트랜잭션이 out-of-gas로 끝났을 때 go-ethereum은 그 삭제를 롤백하지 않았고 Parity는 롤백했습니다. 소수파 체인은 블록 2686516 부근에서 버려졌고 약 165개 블록의 산출물이 무효가 되었습니다. go-ethereum은 v1.5.3에서 Parity의 동작에 맞춰 로그 메커니즘을 수정했고, 공식 설명은 동시에 Parity가 "out-of-gas로 프리컴파일 컨트랙트를 호출하는" 더 좁은 시나리오에서도 불일치가 있었다고 지적합니다. 이번 수정은 EIP-161에 "상태 롤백 시 빈 계정 삭제도 롤백해야 한다"는 설명을 보강했습니다. 클라이언트 코드에는 같은 종류의 흔적이 하나 더 남아 있습니다. go-ethereum의 상태 로그는 RIPEMD160 프리컴파일 주소 0x03에 대해 명시적인 touch 표시를 남기며, 소스 주석은 이것이 블록 1714175의 빈 계정 touch/revert 특례를 재현하기 위한 것이라고 설명합니다. 명세와 구현 사이의 이런 하드코딩 호환은 오래 남을 것이고, 다중 구현 일관성을 사례별로 대조해야 하는 이유이기도 합니다.

업계의 대응은 명세와 테스트 벡터를 같은 출처로 만드는 것이었습니다. 실행 계층 명세는 Python 참조 구현(Execution Layer Specification, 흔히 EELS)의 형태로 유지되고, 테스트 프레임워크는 명세에서 출발해 테스트 벡터(fixture)를 생성합니다. execution-spec-tests는 원래 테스트 벡터를 생성하는 Python 프레임워크와 사례 집합이었는데, 2025년 11월 통째로 ethereum/execution-specs로 옮겨졌고(옛 저장소는 이후 아카이브됨) 공식 설명에 따르면 클라이언트용 fixture 배포 위치는 바뀌지 않아 명세와 테스트가 이때부터 같은 출처가 되었습니다.

상태 테스트(state test)의 판정 방식은 아주 직접적입니다. 실행 전 상태 pre, 환경 env, 트랜잭션 transaction과 fork별로 나눈 기대 결과 post가 주어지면, 클라이언트가 그 트랜잭션을 적용한 뒤 post에 기록된 상태 루트 hash와 로그 요약 logs에 일치해야 합니다. 실패해야 하는 트랜잭션은 expectException으로 기대 예외 타입을 적습니다. 블록 테스트는 여기에 더해 블록 수준 처리를 포괄합니다. 이 벡터들은 각 클라이언트가 가진 테스트 진입점으로 직접 실행할 수도 있습니다. go-ethereum은 evm statetest, Besu는 evmtool state-test, Nethermind는 nethtest, evmone은 evmone-statetest와 evmone-blockchaintest를 씁니다. Hive에 넣어 Engine API로 클라이언트에 블록 페이로드를 보내고 응답과 상태 동기화를 검증할 수도 있는데, 이것이 생산 동작에 가장 가까운 테스트 형태입니다. ethpandaops의 hive-tests 저장소는 이런 테스트를 매일 도는 파이프라인으로 만들어 Besu, Erigon, EthereumJS, Ethrex, go-ethereum, Nethermind, Nimbus-EL과 Reth를 포괄합니다.

테스트의 경계도 분명히 해야 합니다. 테스트는 이미 적어 둔 동작만 포괄할 수 있고, fork가 하나 도입될 때마다 벡터로 고정되지 않은 창이 하나씩 늘어납니다. 테스트가 구속하는 것은 관측 가능한 의미론이며 성능도, 내부 구조도 아닙니다.

명령어 디스패치: 점프 테이블, 생성형 switch와 인라인

인터프리터의 메인 루프는 명령어를 하나 실행할 때마다 먼저 그 처리 함수를 찾아야 합니다. 점프 테이블 방식은 256개 항목 배열을 한 번 조회한 뒤 함수 포인터로 호출합니다. Go는 함수 값을 넘어서 인라인할 수 없어, 명령어마다 배열 로드 한 번과 간접 호출 한 번을 치러야 합니다.

go-ethereum은 2026년에 디스패치를 생성형 switch로 바꾸는 변경을 제출했습니다(PR #35144와 이를 대체한 PR #35638). 오프코드 바이트에 대한 밀집 switch는 점프 테이블로 컴파일되어 컴파일러가 핫 처리 함수를 루프 안으로 인라인할 수 있습니다. 변경은 세 층으로 나뉩니다. fork 사이에서 동작이 안정적인 핫 오프코드는 개별 case로 두고, 상수 gas와 스택 상하한은 상수로 직접 적습니다. 동적 gas가 있지만 fork 사이에서 변하지 않는 소수 오프코드는 여전히 테이블로 값을 매기되 이름으로 처리 함수를 호출합니다. fork에 따라 변하는 모든 오프코드(CALL, CREATE, SSTORE, SLOAD, 로그와 복사 계열)는 계속 현재 fork의 테이블로 디스패치합니다. 원래 인터프리터 루프는 참조 구현으로 남겨 두고, 테스트가 두 루프를 동시에 돌려 출력, gas, 오류, 환불, 로그와 상태 루트를 비교하며, 임의 바이트코드에 대한 차분 퍼징 테스트도 별도로 둡니다.

PR #35638 안의 A/B 벤치마크가 제시한 숫자는 다음과 같습니다. 조건은 메인넷 블록 2000개(블록 번호 25677501~25679500), geth-benchmark-1 머신, go1.27.0, 각 측 3회 실행입니다. 처리량은 391.2 MGas/s에서 424.9 MGas/s로 올랐고, newPayload 평균 소요 시간은 71.6 ms에서 65.1 ms로, 실행 단계 p50은 37.47 ms에서 31.58 ms로 내렸습니다. 2026년 9월 18일 기준으로 이 PR은 GitHub에서 여전히 open이며 병합되지 않았으므로, 이 숫자들은 PR 내부 벤치마크이지 배포판 측정값이 아니고 인용할 때는 검증 대기로 취급해야 합니다.

evmone은 다른 길을 갔습니다. 기본 baseline 인터프리터는 가장 기본적인 JUMPDEST 분석만 합니다. 선택적인 advanced 인터프리터는 간접 호출 스레딩(indirect call threading)을 사용해, 적재한 EVM 프로그램을 가상 명령어 구현 함수를 가리키는 포인터 테이블로 표현하고, 기본 블록 단위로 gas와 스택 요구량을 미리 계산해 블록 진입 시점에 한 번에 검증합니다. 그 대가는 실행 전 바이트코드 분석이 더 무거워진다는 것입니다.

gas 계량: 상수와 동적의 분리, 콜드/핫 접근은 슬롯 단위로 값을 매긴다

인터프리터는 오프코드를 실행하기 전에 비용을 다 계산해야 합니다. go-ethereum은 이를 상수 부분과 동적 부분으로 나눕니다. 상수 gas는 바로 차감하고, 동적 gas는 처리 함수가 스택과 메모리, 상태를 보고 계산합니다. 메모리 확장 비용은 필요한 워드 수에 대해 초선형으로 늘어나므로, 인터프리터는 오프코드가 요구하는 메모리 크기를 먼저 계산한 뒤 값을 매깁니다.

EIP-2929 이후 gas 계량과 상태 접근 계층은 서로 묶였습니다. 이 제안은 트랜잭션마다 접근한 주소와 접근한 스토리지 슬롯 두 집합을 유지할 것을 요구하고, 스토리지 슬롯의 원소 타입은 Set[Tuple[Address, Bytes32]]입니다. 어떤 슬롯을 처음 접근하면 COLD_SLOAD_COST, 즉 2100 gas가 부과되고, 반복 접근하면 WARM_STORAGE_READ_COST, 즉 100 gas가 부과되며, 어떤 주소를 처음 접근하면 COLD_ACCOUNT_ACCESS_COST, 즉 2600 gas가 부과됩니다. 접근 집합은 트랜잭션 컨텍스트에 속하고 물리적으로는 클라이언트의 실행 환경이 들고 있으며, 인터프리터는 SLOAD나 호출을 할 때마다 돌아와 그것을 조회하고 갱신해야 합니다. 이것도 인터프리터를 상태 계층과 떼어 놓고 고치기 어려운 이유입니다.

블록 단위로 gas를 미리 계산하면 관측 가능한 부작용이 있습니다. evmone 문서는 기본 블록 전체의 요구량을 미리 검사하기 때문에, 명령어별로 값을 매길 때는 실행되었을 외부 가시적 조작이 미리 값을 매기면 실행되지 않을 수 있다고 분명히 밝힙니다. 문서는 이것이 합의 문제는 아니라고 봅니다. 실행이 하드 예외로 끝나고 모든 효과가 롤백되기 때문입니다. 다만 실행 트레이스가 달라지거나 다른 예외 타입으로 끝날 수 있습니다. 이런 차이는 정확히 테스트 벡터가 구속하는 범위 안에 있습니다.

메모리와 호출 프레임: 할당을 핫 경로 밖으로 옮긴다

컨트랙트 호출마다 스택과 메모리가 필요합니다. EVM의 스택에는 1024개 항목 상한이 있고, 메모리는 필요할 때 확장되며 값을 매기고, 반환 데이터에도 버퍼가 필요합니다. 이 객체들은 수명이 짧고 생성 빈도가 높아, 구현은 대체로 매번 할당하기보다 재사용하는 쪽을 택합니다. go-ethereum은 인터프리터 진입점에서 Memory 객체 하나를 만들어 두고 오프코드가 더 큰 메모리를 요구하면 워드 단위로 확장하며, revm의 컨텍스트 계층은 항목 풀링(item-pooling) 방식의 FrameStack을 들고 인덱스로 호출 프레임을 재사용합니다.

프리컴파일: 네이티브 구현과 의존성 절충

프리컴파일 컨트랙트는 소수의 고정 주소에 있는 네이티브 구현으로, 실행할 때 호스트가 직접 계산하고 바이트코드를 해석하지 않으며 인터프리터는 라우팅과 gas 값 매기기만 맡습니다. 일부 프리컴파일의 비용은 입력 길이와도 관련이 있습니다.

독립 라이브러리가 이 계층에서 하는 절충은 따로 볼 만합니다. evmone 문서는 두 가지 타협을 설명합니다. ecrecover는 evmone이 직접 구현하는데 성능이 다소 떨어집니다. expmod는 기본적으로 스텁 구현을 쓰므로 알려진 입력에만 올바르게 응답하고, 완전한 구현을 얻으려면 빌드할 때 EVMONE_PRECOMPILES_GMP=1을 켜고 GMP를 빌드 및 런타임 의존성으로 끌어와야 합니다. 이는 일반적인 문제를 드러냅니다. 프리컴파일의 정확성은 임의 입력에 대해 성립해야 하는데, 큰 정수 연산과 타원 곡선 복원, Keccak 해시 같은 네이티브 코드를 다른 구현과 비트 단위로 일치시키는 일 자체가 분기가 숨어들기 쉬운 지점입니다.

JIT가 주류 선택이 되지 못한 이유

EVM 클라이언트에서 JIT(just-in-time compilation, 즉시 컴파일)는 공식 시도가 한 번뿐이었습니다. ethereum/evmjit는 LLVM을 기반으로 런타임에 컨트랙트 코드를 기계어로 컴파일해 클라이언트의 인터프리터 기반 EVM을 대체하려 했습니다. 그 저장소는 지금 아카이브되었고, README에는 프로젝트를 더 이상 유지하지 않으며 중요한 용도로 쓰지 말라고 적혀 있습니다.

유지가 중단된 이유는 README에 설명되어 있지 않고, 기술적 조건을 보면 장애물이 몇 가지 있습니다. EVM의 점프 대상은 스택 위의 값에서 오고 코드는 런타임에 읽힐 수 있어 프로그램 구조가 실행 시점에야 정해지므로, 컴파일러가 JVM에서처럼 컴파일 시점에 안정적인 제어 흐름 그래프를 얻기 어렵습니다. 한 번의 호출에 쓸 수 있는 연산량도 블록 gas 상한에 묶여 있어 이득 총량에 천장이 있습니다. 비교적 성숙한 대안은 분석을 정적 단계로 옮기는 것이고, EOF(EVM Object Format, EIP-7692)가 바로 이 방향의 시도로 컨테이너 형식, 정적 상대 점프, 스택 검증과 코드 세그먼트·데이터 세그먼트 분리 같은 항목을 담고 있습니다. 그러나 이 노선은 현재 활발하지 않습니다. EOF는 2025년 4월 28일 Fusaka 업그레이드 범위에서 제외되었고 EIPs PR #9703이 그날 병합되어 Fusaka 단계의 제거만 다루었습니다. EIP-7692 자체의 상태는 stagnant로 표시되어 있고, Glamsterdam의 공식 범위 목록인 EIP-7773에도 들어 있지 않습니다. 제3자 추적 사이트 eipsinsight의 변경 기록에 따르면 EIP-7692는 2026년 8월 27일 Glamsterdam 범위 정리에서 후보 버킷에서 빠졌는데, 이 항목은 제3자 출처뿐입니다. 따라서 단기적으로 범용 클라이언트 최적화의 주 전장은 여전히 인터프리터이고, 컴파일 실행은 아직 자리 잡을 공간이 없습니다.

어떤 조건에서 이런 최적화가 효과가 없는가

실행이 더 이상 시간 소모의 주체가 아니면 이득은 체감합니다. 위에서 인용한 go-ethereum 벤치마크에서 실행 단계 p50은 37.47 ms에서 31.58 ms로 내렸지만 블록 총 시간 p50은 62.1 ms에서 56.2 ms로 내렸습니다. 같은 표의 셈으로 상태 읽기, 상태 해싱과 커밋이 합쳐 총 시간의 약 3분의 1을 차지하고, 엔진 계층 오버헤드까지 더하면 절반에 가까워지므로 인터프리터 최적화의 천장은 이 비율이 결정합니다. 부하가 상태 접근과 디스크 I/O 쪽으로 기울수록 인터프리터를 최적화하는 한계 이득은 낮아집니다.

fork 차이 때문에 최적화를 전면에 적용할 수는 없습니다. 점프 테이블은 fork별로 생성되고, 생성형 switch도 fork 사이에서 동작이 안정적인 오프코드만 인라인할 수 있습니다. 메타데이터가 fork에 따라 변하는 오프코드는 반드시 테이블 디스패치 경로에 남아야 하며, 그렇지 않으면 잘못된 상수를 쓰게 됩니다.

의미론 제약이 최적화의 경계를 정합니다. 최적화는 로그 순서, 트레이싱 훅 순서, 예외 타입과 gas 계량을 바꿔서는 안 되고, 이들은 모두 테스트 벡터로 고정되어 있습니다. evmone의 기본 블록 수준 사전 검사가 조기에 종료될 수 있다는 그 예가, 최적화와 관측 가능한 의미론 사이에서 명시적으로 절충해야 하는 지점입니다.

일관성 비용은 구현 수가 늘수록 올라갑니다. 구현이 하나 늘 때마다 합의 경계에 분기할 수 있는 지점이 하나씩 늘어납니다. 테스트 벡터는 이 면을 압축할 수 있지만 없애지는 못합니다. 다중 구현이 주는 중복의 가치와 이 비용은 같은 절충의 양끝입니다.

출처

  • revm 문서, Introduction: https://bluealloy.github.io/revm/
  • revm 문서, Architecture: https://bluealloy.github.io/revm/architecture.html
  • revm, Database 트레이트: https://docs.rs/revm/latest/revm/context/trait.Database.html
  • revm, Host 트레이트: https://docs.rs/revm-interpreter/latest/revm_interpreter/trait.Host.html
  • revm 저장소와 사용자 목록: https://github.com/bluealloy/revm
  • evmone 저장소 설명(baseline과 advanced 인터프리터, 프리컴파일 절충): https://github.com/ethereum/evmone
  • evmone, Efficient gas calculation algorithm for EVM: https://github.com/ethereum/evmone/blob/master/docs/efficient_gas_calculation_algorithm.md
  • EVMC, Ethereum Client-VM Connector API: https://github.com/ethereum/evmc
  • Silkworm 프로젝트 기원 회고(EVMC와 CGo 인터페이스 오버헤드): https://erigon.substack.com/p/staged-sync-and-short-history-of
  • go-ethereum 인터프리터 루프: https://github.com/ethereum/go-ethereum/blob/master/core/vm/interpreter.go
  • go-ethereum 점프 테이블 정의: https://github.com/ethereum/go-ethereum/blob/master/core/vm/jump_table.go
  • go-ethereum PR #35638(생성형 switch와 PGO 인라인, 벤치마크 조건 포함): https://github.com/ethereum/go-ethereum/pull/35638
  • go-ethereum 저장소와 라이선스 설명: https://github.com/ethereum/go-ethereum
  • go-ethereum 상태 전환 계층(고유 gas, nonce 검증, 환불): https://github.com/ethereum/go-ethereum/blob/master/core/state_transition.go
  • 이더리움 옐로 페이퍼(메모리 확장 비용 함수): https://ethereum.github.io/yellowpaper/paper.pdf
  • EIP-2929, Gas cost increases for state access opcodes: https://eips.ethereum.org/EIPS/eip-2929
  • execution-specs 저장소(명세와 테스트 벡터): https://github.com/ethereum/execution-specs
  • The Weld is Complete(execution-spec-tests 병합 공지): https://steel.ethereum.foundation/blog/2025-11-04_weld_final/
  • 상태 테스트 형식 설명: https://steel.ethereum.foundation/docs/execution-specs/running_tests/test_formats/state_test/
  • 테스트 벡터 직접 실행과 각 클라이언트 진입점: https://steel.ethereum.foundation/docs/execution-specs/running_tests/consume/direct/
  • ethpandaops/hive-tests(다중 클라이언트 일일 일관성 테스트): https://github.com/ethpandaops/hive-tests
  • 이더리움 재단 보안 공지, 2016-11-24 합의 결함: https://blog.ethereum.org/2016/11/25/security-alert-11242016-consensus-bug-geth-v1-4-19-v1-5-2
  • go-ethereum v1.5.3 릴리스 노트: https://github.com/ethereum/go-ethereum/releases/tag/v1.5.3
  • ethereum/evmjit 저장소(아카이브됨): https://github.com/ethereum/evmjit
  • EIP-7692, EVM Object Format (EOFv1) Meta: https://eips.ethereum.org/EIPS/eip-7692
  • EIP-7607의 EOF 제거 설명(EIPs PR #9703): https://github.com/ethereum/EIPs/pull/9703
  • EIP-7773, Hardfork Meta - Glamsterdam(공식 범위 목록, EOF 미포함): https://eips.ethereum.org/EIPS/eip-7773
  • Optimism 문서, op-geth 지원 종료 공지: https://docs.optimism.io/notices/op-geth-deprecation
  • 제3자 추적 사이트 eipsinsight, Glamsterdam 업그레이드 범위와 변경 기록: https://eipsinsight.com/upgrade/glamsterdam

더 읽기

Bitroot 멀티 엔진 병렬 실행: 스케줄링, 샤딩, 충돌 영역관련 글Bitroot 병렬 EVM 아키텍처 개요: 합의, 실행, 상태가 함께 동작하는 방식관련 글EVM 호환성의 실제 의미: 바이트코드, 프리컴파일, JSON-RPC, 툴링호환성 심화
← 이전Storage Layout: Solidity 상태 변수가 slot에 놓이는 방식
목차
EVM과 클라이언트 나머지 부분의 경계세 구현의 위치 차이일관성은 자체 테스트로 나오지 않는다: state test와 다중 클라이언트 테스트명령어 디스패치: 점프 테이블, 생성형 switch와 인라인gas 계량: 상수와 동적의 분리, 콜드/핫 접근은 슬롯 단위로 값을 매긴다메모리와 호출 프레임: 할당을 핫 경로 밖으로 옮긴다프리컴파일: 네이티브 구현과 의존성 절충JIT가 주류 선택이 되지 못한 이유어떤 조건에서 이런 최적화가 효과가 없는가출처더 읽기
읽기 설정