1 EVM이란 무엇인가?
- 이더리움 가상 머신이라고 하는 에뮬레이트된 컴퓨터에서 스마트 컨트랙트라는 프로그램을 실행한다.
- EVM은 싱글톤으로 전 세계에 걸친 단일 인스턴스 컴퓨터인 것처럼 작동한다.
- EVM은 모든 이더리움 노드에서 로컬 인스턴스로 실행된다.
- EVM의 모든 인스턴스 동일한 초기 상태에서 동작하고 동일한 최종 상태를 생성하기 때문에 시스템 전체가 단일 월드 컴퓨터로 작동한다.
- 각 노드들은 컨트랙트 실행을 확인하기 위해 EVM의 로컬 사본을 실행하고 이더리움 블록체인은 트랜잭션과 스마트 컨트랙트를 처리할 때 월드 컴퓨터의 변화하는 상태를 기록한다.
- EVM은 머신 코드를 실행하는 컴퓨터의 CPU와 유사한 EVM바이트코드라는 특수한 코드를 실행하는 가상 머신이다.
EVM 특징
튜링 완전 머신
- 앨런 튜링이 고안한 개념으로, 수학적으로 어떠한 알고리즘이든 실행시킬 수 있는 머신
- 정확히는 유사 튜링 완전 머신
- 스마트 컨트랙트 실행에 사용할 수 있는 가스양에 따라 모든 실행 프로세스가 유한개의 계산 단계로 제한된다는 것을 의미한다.
- 따라서 정지 문제를 해결해 실행이 영원히 지속되어 이더리움 플랫폼이 중단되는 상황을 피할 수 있다.
GAS
- 정지되지 않고 무한히 수행되는 프로그램(Halting Problem)을 방지하기 위해 수수료를 낸만큼만 EVM을 사용할 수 있음
바이트 코드
- 스택 기반으로 실행될 수 있는 저수준의 기계어에 가까운 코드로써, EVM은 바이트 코드만을 수행함.
1.1 EVM의 architecture
- EVM은 간단한 Stack 기반 architecture를 지님
컴퓨터와 같은 구조
- 코드와 저장소, 스택, 인자, 메모리 등 일반적인 컴퓨터가 갖는 구조를 그대로 가지고 있음
스택

- 프로그램의 수행 과정에서 데이터가 스택이라는 자료구조를 활용하는 머신
- 스택 프레임의 크기는 256비트 총 1024개의 스택 프레임을 가짐
메모리

- 256비트의 데이터가 배열로 저장된 형태로 영구적이 아닌 휘발성 메모리를 보유
- 초기값 0으로 설정됨
저장소

- 키-값 형태의 데이터 저장소로써 데이터는 블록체인 위에 영속적으로 저장됨.
- 초기값 0으로 설정됨
1.2 EVM 명령어 집합
- EVM은 모든 피연산자를 스택에서 가져와 결과를 스택 상단에 다시 넣는다.
산술 연산
ADD //Add the top two stack items
MUL //Multiply the top two stack items
SUB //Subtract the top two stack items
DIV //Integer division
SDIV //Signed integer division
MOD //Modulo (remainder) operation
SMOD //Signed modulo operation
ADDMOD //Addition modulo any number
MULMOD //Multiplication modulo any number
EXP //Exponential operation
SIGNEXTEND //Extend the length of a two's complement signed integer
SHA3 //Compute the Keccak-256 hash of a block of memory
스택 연산
POP //Remove the top item from the stack
MLOAD //Load a word from memory
MSTORE //Save a word to memory
MSTORE8 //Save a byte to memory
SLOAD //Load a word from storage
SSTORE //Save a word to storage
MSIZE //Get the size of the active memory in bytes
PUSHx //Place x byte item on the stack, where x can be any integer from 1 to 32 (full word) inclusive
DUPx //Duplicate the x-th stack item, where x can be any integer from 1 to 16 inclusive
SWAPx //Exchange 1st and (x+1)-th stack items, where x can be any integer from 1 to 16 inclusive
프로세스 흐름 연산
STOP //실행중지
JUMP //프로그램 카운터를 임의 값으로 설정
JUMPI //조건부로 프로그램 카운터 변경
PC //프로그램 카운터 값을 조회
JUMPDEST //점프에 대한 유효한 대상을 표시
시스템 연산
LOGx //X항목이 있는 로그 레코드를 추가.
CREATE //관련된 코드로 새 계정 생성
CALL //다른 계정으로 메시지 호출. 즉, 다른계정 코드 실행
CALLCODE //Message-call into this account with another account's code
RETURN //실행을 중단하고 출력 데이터 반환
DELEGATECALL //Sender와 value의 현재 값은 유지하면서 대체 계정 코드에서 이 계정으로 메시지 호출
STATICCALL //Static message-call into an account
REVERT //Halt execution, reverting state changes but returning data and remaining gas
INVALID //잘못된 명령어
SELFDESTRUCT //Halt execution and register account for deletion
논리 연산
LT //Less-than comparison
GT //Greater-than comparison
SLT //Signed less-than comparison
SGT //Signed greater-than comparison
EQ //Equality comparison
ISZERO //Simple NOT operator
AND //Bitwise AND operation
OR //Bitwise OR operation
XOR //Bitwise XOR operation
NOT //Bitwise NOT operation
BYTE //Retrieve a single byte from a full-width 256-bit word
환경 연산
GAS //Get the amount of available gas (after the reduction for this instruction)
ADDRESS //Get the address of the currently executing account
BALANCE //Get the account balance of any given account
ORIGIN //Get the address of the EOA that initiated this EVM execution
CALLER //Get the address of the caller immediately responsible for this execution
CALLVALUE //Get the ether amount deposited by the caller responsible for this execution
CALLDATALOAD //Get the input data sent by the caller responsible for this execution
CALLDATASIZE //Get the size of the input data
CALLDATACOPY //Copy the input data to memory
CODESIZE //Get the size of code running in the current environment
CODECOPY //Copy the code running in the current environment to memory
GASPRICE //Get the gas price specified by the originating transaction
EXTCODESIZE //Get the size of any account's code
EXTCODECOPY //Copy any account's code to memory
RETURNDATASIZE //Get the size of the output data from the previous call in the current environment
RETURNDATACOPY //Copy data output from the previous call to memory
블록 연산
BLOCKHASH //Get the hash of one of the 256 most recently completed blocks
COINBASE //Get the block's beneficiary address for the block reward
TIMESTAMP //Get the block's timestamp
NUMBER //Get the block's number
DIFFICULTY //Get the block's difficulty
GASLIMIT //Get the block's gas limit