메인 콘텐츠로 건너뛰기

옐로우 페이퍼의 EVM 사양 이해하기

evm
중급
qbzzt
2022년 5월 15일
33 1분의 읽기 소요시간

옐로우 페이퍼 (opens in a new tab)는 이더리움의 공식 사양입니다. EIP 프로세스에 의해 수정된 경우를 제외하고, 모든 것이 작동하는 방식에 대한 정확한 설명이 포함되어 있습니다. 이 페이퍼는 수학 논문으로 작성되었으며, 프로그래머에게 익숙하지 않은 용어가 포함될 수 있습니다. 이 문서를 통해 옐로우 페이퍼를 읽는 방법과 더 나아가 다른 관련 수학 논문을 읽는 방법을 배울 수 있습니다.

어떤 옐로우 페이퍼?

이더리움의 거의 모든 것과 마찬가지로 옐로우 페이퍼도 시간이 지남에 따라 발전합니다. 특정 버전을 참조할 수 있도록 작성 시점의 현재 버전을 업로드했습니다. 제가 사용하는 섹션, 페이지 및 방정식 번호는 해당 버전을 참조합니다. 이 문서를 읽는 동안 다른 창에서 열어두는 것이 좋습니다.

왜 EVM인가?

최초의 옐로우 페이퍼는 이더리움 개발 초기에 작성되었습니다. 네트워크를 보호하기 위해 원래 사용되었던 작업 증명 기반 합의 메커니즘을 설명합니다. 그러나 이더리움은 2022년 9월에 작업 증명을 중단하고 지분 증명 기반 합의를 사용하기 시작했습니다. 이 튜토리얼에서는 이더리움 가상 머신을 정의하는 옐로우 페이퍼의 일부에 중점을 둘 것입니다. EVM은 지분 증명으로 전환되어도 (DIFFICULTY 연산 부호의 반환 값을 제외하고) 변경되지 않았습니다.

9 실행 모델

이 섹션(12-14페이지)에는 EVM의 대부분의 정의가 포함되어 있습니다.

시스템 상태라는 용어에는 시스템을 실행하기 위해 알아야 할 모든 것이 포함됩니다. 일반적인 컴퓨터에서 이는 메모리, 레지스터의 내용 등을 의미합니다.

튜링 머신 (opens in a new tab)은 계산 모델입니다. 기본적으로 튜링 머신은 컴퓨터의 단순화된 버전으로, 일반 컴퓨터와 동일한 계산 실행 능력을 갖춘 것으로 입증되었습니다(컴퓨터가 계산할 수 있는 모든 것을 튜링 머신이 계산할 수 있으며 그 반대도 마찬가지입니다). 이 모델을 사용하면 계산 가능한 것과 계산할 수 없는 것에 대한 다양한 정리를 더 쉽게 증명할 수 있습니다.

튜링 완전 (opens in a new tab)이라는 용어는 튜링 머신과 동일한 계산을 실행할 수 있는 컴퓨터를 의미합니다. 튜링 머신은 무한 루프에 빠질 수 있지만 EVM은 가스를 소진하기 때문에 그럴 수 없으므로 준-튜링-완전(quasi-Turing-complete)일 뿐입니다.

9.1 기본 사항

이 섹션에서는 EVM의 기본 사항과 다른 계산 모델과 비교하는 방법을 설명합니다.

스택 머신 (opens in a new tab)은 레지스터가 아닌 스택 (opens in a new tab)에 중간 데이터를 저장하는 컴퓨터입니다. 구현이 쉽고 버그 및 보안 취약점이 발생할 가능성이 훨씬 적기 때문에 가상 머신에 선호되는 아키텍처입니다. 스택의 메모리는 256비트 워드로 나뉩니다. 이는 Keccak-256 해시 및 타원 곡선 계산과 같은 이더리움의 핵심 암호화 작업에 편리하기 때문에 선택되었습니다. 스택의 최대 크기는 1024개 항목(1024 x 256비트)입니다. 연산 부호가 실행될 때 일반적으로 스택에서 매개변수를 가져옵니다. POP(스택 맨 위에서 항목 제거), DUP_N(스택의 N번째 항목 복제) 등과 같이 스택의 요소를 재구성하기 위한 연산 부호가 있습니다.

또한 EVM에는 실행 중에 데이터를 저장하는 데 사용되는 메모리라는 휘발성 공간이 있습니다. 이 메모리는 32바이트 워드로 구성됩니다. 모든 메모리 위치는 0으로 초기화됩니다. 이 Yul (opens in a new tab) 코드를 실행하여 메모리에 단어를 추가하면 단어의 빈 공간을 0으로 채워 32바이트의 메모리를 채웁니다. 즉, 위치 0-29에 0, 30에 0x60, 31에 0xA7이 있는 단어 하나를 생성합니다.

1mstore(0, 0x60A7)

mstore는 EVM이 메모리와 상호 작용하기 위해 제공하는 세 가지 연산 부호 중 하나로, 메모리에 단어를 로드합니다. 다른 두 가지는 단일 바이트를 메모리에 로드하는 mstore8과 메모리에서 스택으로 단어를 이동하는 mload입니다.

또한 EVM에는 시스템 상태의 일부로 유지되는 별도의 비휘발성 저장 공간 모델이 있습니다. 이 메모리는 (스택의 단어 주소 지정 가능 바이트 배열과 달리) 단어 배열로 구성됩니다. 이 저장 공간은 계약이 영구 데이터를 보관하는 곳이며, 계약은 자체 저장 공간과만 상호 작용할 수 있습니다. 저장 공간은 키-값 매핑으로 구성됩니다.

이 섹션의 옐로우 페이퍼에서는 언급되지 않았지만 네 번째 유형의 메모리가 있다는 것을 아는 것도 유용합니다. 호출 데이터(Calldata)는 트랜잭션의 data 매개변수와 함께 전달된 값을 저장하는 데 사용되는 바이트 주소 지정 가능 읽기 전용 메모리입니다. EVM에는 calldata를 관리하기 위한 특정 연산 부호가 있습니다. calldatasize는 데이터의 크기를 반환합니다. calldataload는 데이터를 스택에 로드합니다. calldatacopy는 데이터를 메모리에 복사합니다.

표준 폰 노이만 아키텍처 (opens in a new tab)는 코드와 데이터를 동일한 메모리에 저장합니다. EVM은 보안상의 이유로 이 표준을 따르지 않습니다. 휘발성 메모리를 공유하면 프로그램 코드를 변경할 수 있습니다. 대신 코드는 저장 공간에 저장됩니다.

메모리에서 코드가 실행되는 경우는 두 가지뿐입니다.

  • 계약이 다른 계약을 생성할 때(CREATE (opens in a new tab) 또는 CREATE2 (opens in a new tab) 사용), 계약 생성자 코드는 메모리에서 가져옵니다.
  • 모든 계약을 생성하는 동안 생성자 코드가 실행된 다음 실제 계약의 코드를 메모리에서 반환합니다.

예외적 실행이라는 용어는 현재 계약의 실행을 중단시키는 예외를 의미합니다.

9.2 수수료 개요

이 섹션에서는 가스 수수료가 계산되는 방법을 설명합니다. 세 가지 비용이 있습니다.

연산 부호 비용

특정 연산 부호의 고유 비용. 이 값을 얻으려면 부록 H(28페이지, 방정식 (327) 아래)에서 연산 부호의 비용 그룹을 찾고 방정식 (324)에서 비용 그룹을 찾으십시오. 그러면 대부분의 경우 부록 G(27페이지)의 매개변수를 사용하는 비용 함수가 제공됩니다.

예를 들어, CALLDATACOPY (opens in a new tab) 연산 부호는 Wcopy 그룹의 구성원입니다. 해당 그룹의 연산 부호 비용은 Gverylow+Gcopy×⌈μs[2]÷32⌉입니다. 부록 G를 보면 두 상수가 모두 3이므로 3+3×⌈μs[2]÷32⌉가 됩니다.

아직 ⌈μs[2]÷32⌉ 표현식을 해독해야 합니다. 가장 바깥쪽 부분인 ⌈ <값> ⌉은 올림 함수로, 주어진 값보다 작지 않은 가장 작은 정수를 반환하는 함수입니다. 예를 들어, ⌈2.5⌉ = ⌈3⌉ = 3입니다. 안쪽 부분은 μs[2]÷32입니다. 3페이지의 3절(규칙)을 보면 μ는 머신 상태입니다. 머신 상태는 13페이지의 9.4.1절에 정의되어 있습니다. 해당 섹션에 따르면 머신 상태 매개변수 중 하나는 스택을 위한 s입니다. 종합해 보면 μs[2]는 스택의 위치 #2인 것 같습니다. 연산 부호 (opens in a new tab)를 보면 스택의 위치 #2는 데이터의 크기(바이트)입니다. Wcopy 그룹의 다른 연산 부호인 CODECOPY (opens in a new tab)RETURNDATACOPY (opens in a new tab)를 보면, 이들도 같은 위치에 데이터 크기를 가집니다. 따라서 ⌈μs[2]÷32⌉는 복사되는 데이터를 저장하는 데 필요한 32바이트 워드의 수입니다. 모든 것을 종합하면 CALLDATACOPY (opens in a new tab)의 고유 비용은 3 가스에 복사되는 데이터 워드당 3이 추가됩니다.

실행 비용

호출하는 코드를 실행하는 비용.

메모리 확장 비용

메모리 확장 비용(필요한 경우).

방정식 324에서 이 값은 Cmemi')-Cmemi)로 작성됩니다. 9.4.1절을 다시 보면 μi가 메모리의 단어 수임을 알 수 있습니다. 따라서 μi는 연산 부호 전 메모리의 단어 수이고 μi'는 연산 부호 후 메모리의 단어 수입니다.

Cmem 함수는 방정식 326에 정의되어 있습니다: Cmem(a) = Gmemory × a + ⌊a2 ÷ 512⌋. ⌊x⌋는 내림 함수로, 주어진 값보다 크지 않은 가장 큰 정수를 반환하는 함수입니다. 예를 들어, ⌊2.5⌋ = ⌊2⌋ = 2. a < √512일 때, a2 < 512이고 내림 함수의 결과는 0입니다. 따라서 처음 22개 단어(704바이트)의 경우 비용은 필요한 메모리 단어 수에 따라 선형적으로 증가합니다. 그 지점을 넘어서면 ⌊a2 ÷ 512⌋는 양수입니다. 필요한 메모리가 충분히 높으면 가스 비용은 메모리 양의 제곱에 비례합니다.

참고 이러한 요소는 고유 가스 비용에만 영향을 미칩니다. 최종 사용자가 지불해야 하는 금액을 결정하는 수수료 시장이나 검증자에게 주는 팁은 고려하지 않습니다. 이것은 EVM에서 특정 작업을 실행하는 데 드는 순수 비용일 뿐입니다.

가스에 대해 자세히 알아보기.

9.3 실행 환경

실행 환경은 블록체인 상태나 EVM의 일부가 아닌 정보를 포함하는 튜플, I입니다.

매개 변수데이터에 접근하기 위한 연산 부호데이터에 접근하기 위한 솔리디티 코드
IaADDRESS (opens in a new tab)address(this)
IoORIGIN (opens in a new tab)tx.origin
IpGASPRICE (opens in a new tab)tx.gasprice
IdCALLDATALOAD (opens in a new tab)msg.data
IsCALLER (opens in a new tab)msg.sender
IvCALLVALUE (opens in a new tab)msg.value
IbCODECOPY (opens in a new tab)address(this).code
IHNUMBER (opens in a new tab)DIFFICULTY (opens in a new tab)와 같은 블록 헤더 필드block.number, block.difficulty
Ie계약 간 호출(계약 생성 포함)을 위한 호출 스택의 깊이
IwEVM이 상태를 변경할 수 있는지 또는 정적으로 실행 중인지

9절의 나머지 부분을 이해하려면 몇 가지 다른 매개변수가 필요합니다.

매개 변수정의된 섹션의미
σ2 (2페이지, 방정식 1)블록체인의 상태
g9.3 (13페이지)남은 가스
A6.1 (8페이지)누적된 하위 상태(트랜잭션이 종료될 때 예정된 변경 사항)
o9.3 (13페이지)출력 - 내부 트랜잭션(한 계약이 다른 계약을 호출하는 경우) 및 뷰 함수 호출(정보만 요청하므로 트랜잭션을 기다릴 필요가 없는 경우)의 반환 결과

9.4 실행 개요

이제 모든 예비 작업을 마쳤으므로 마침내 EVM이 어떻게 작동하는지 알아볼 수 있습니다.

방정식 137-142는 EVM을 실행하기 위한 초기 조건을 제공합니다.

기호초기값의미
μgg남은 가스
μpc0프로그램 카운터, 다음에 실행할 명령어의 주소
μm(0, 0, ...)메모리, 모두 0으로 초기화됨
μi0사용된 가장 높은 메모리 위치
μs()스택, 초기에 비어 있음
μo출력, 반환 데이터(RETURN (opens in a new tab) 또는 REVERT (opens in a new tab))가 있거나 없는(STOP (opens in a new tab) 또는 SELFDESTRUCT (opens in a new tab)) 경우 중단될 때까지 빈 집합입니다.

방정식 143은 실행 중 각 시점에서 네 가지 가능한 조건과 이를 어떻게 처리해야 하는지를 알려줍니다.

  1. Z(σ,μ,A,I). Z는 작업이 잘못된 상태 전환을 생성하는지 테스트하는 함수를 나타냅니다(참조: 예외적 중단). True로 평가되면 변경 사항이 구현되지 않았기 때문에 새 상태는 이전 상태와 동일합니다(가스가 소모되는 경우 제외).
  2. 실행 중인 연산 부호가 REVERT (opens in a new tab)인 경우 새 상태는 이전 상태와 동일하며 일부 가스가 손실됩니다.
  3. 작업 순서가 RETURN (opens in a new tab)으로 표시된 대로 완료되면 상태가 새 상태로 업데이트됩니다.
  4. 종료 조건 1-3 중 하나에 해당하지 않으면 계속 실행합니다.

9.4.1 머신 상태

이 섹션에서는 머신 상태에 대해 자세히 설명합니다. w가 현재 연산 부호임을 지정합니다. 만약 μpc가 코드의 길이인 ||Ib||보다 작으면 해당 바이트(Ibpc])는 연산 부호입니다. 그렇지 않으면 연산 부호는 STOP (opens in a new tab)으로 정의됩니다.

이것은 스택 머신 (opens in a new tab)이므로 각 연산 부호에 의해 팝(δ) 및 푸시(α)된 항목 수를 추적해야 합니다.

9.4.2 예외적 중단

이 섹션에서는 비정상적인 종료가 발생할 때를 지정하는 Z 함수를 정의합니다. 이것은 부울 (opens in a new tab) 함수이므로 논리합에  (opens in a new tab)논리곱에  (opens in a new tab)를 사용합니다.

다음 조건 중 하나라도 참이면 예외적 중단이 발생합니다.

  • μg < C(σ,μ,A,I) 9.2절에서 보았듯이 C는 가스 비용을 지정하는 함수입니다. 다음 연산 부호를 처리할 가스가 충분하지 않습니다.

  • δw=∅ 연산 부호에 대해 팝된 항목 수가 정의되지 않은 경우 연산 부호 자체도 정의되지 않습니다.

  • || μs || < δw 스택 언더플로, 현재 연산 부호에 대한 스택에 항목이 충분하지 않습니다.

  • w = JUMP ∧ μs[0]∉D(Ib) 연산 부호는 JUMP (opens in a new tab)이고 주소는 JUMPDEST (opens in a new tab)가 아닙니다. 점프는 대상이 JUMPDEST (opens in a new tab)인 경우에만 유효합니다.

  • w = JUMPI ∧ μs[1]≠0 ∧ μs[0] ∉ D(Ib) 연산 부호는 JUMPI (opens in a new tab)이고, 조건이 참(0이 아님)이므로 점프가 발생해야 하지만 주소는 JUMPDEST (opens in a new tab)가 아닙니다. 점프는 대상이 JUMPDEST (opens in a new tab)인 경우에만 유효합니다.

  • w = RETURNDATACOPY ∧ μs[1]+μs[2]>|| μo || 연산 부호는 RETURNDATACOPY (opens in a new tab)입니다. 이 연산 부호 스택 요소 μs[1]은 반환 데이터 버퍼에서 읽을 오프셋이고 스택 요소 μs[2]는 데이터의 길이입니다. 이 조건은 반환 데이터 버퍼의 끝을 넘어서 읽으려고 할 때 발생합니다. 호출 데이터나 코드 자체에 대해서는 유사한 조건이 없다는 점에 유의하십시오. 해당 버퍼의 끝을 넘어서 읽으려고 하면 0만 얻게 됩니다.

  • || μs || - δw + αw > 1024

    스택 오버플로우. 연산 부호를 실행하면 스택에 1024개 이상의 항목이 생기면 중단합니다.

  • ¬Iw ∧ W(w,μ) 정적으로 실행 중입니까?(¬는 부정 (opens in a new tab)이고 Iw는 블록체인 상태를 변경할 수 있을 때 참입니다). 그렇다면 상태 변경 작업을 시도하는 것이므로 발생할 수 없습니다.

    W(w,μ) 함수는 나중에 방정식 150에 정의됩니다. 다음 조건 중 하나가 참이면 W(w,μ)는 참입니다.

    • w ∈ {CREATE, CREATE2, SSTORE, SELFDESTRUCT} 이러한 연산 부호는 새 계약을 생성하거나, 값을 저장하거나, 현재 계약을 파기하여 상태를 변경합니다.

    • LOG0≤w ∧ w≤LOG4 정적으로 호출되면 로그 항목을 내보낼 수 없습니다. 로그 연산 부호는 모두 LOG0(A0) (opens in a new tab)LOG4(A4) (opens in a new tab) 사이의 범위에 있습니다. 로그 연산 부호 뒤의 숫자는 로그 항목에 포함된 주제 수를 지정합니다.

    • w=CALL ∧ μs[2]≠0 정적일 때 다른 계약을 호출할 수 있지만, 그렇게 하면 ETH를 전송할 수 없습니다.

  • w = SSTORE ∧ μg ≤ Gcallstipend Gcallstipend(부록 G에서 2300으로 정의) 가스보다 많지 않으면 SSTORE (opens in a new tab)를 실행할 수 없습니다.

9.4.3 점프 대상 유효성

여기에서는 JUMPDEST (opens in a new tab) 연산 부호가 무엇인지 공식적으로 정의합니다. 바이트 값 0x5B는 PUSH 내부에 있을 수 있으므로(따라서 연산 부호가 아닌 데이터) 그냥 찾을 수는 없습니다.

방정식 (153)에서 함수 N(i,w)를 정의합니다. 첫 번째 매개변수 i는 연산 부호의 위치입니다. 두 번째 매개변수 w는 연산 부호 자체입니다. w∈[PUSH1, PUSH32]이면 연산 부호가 PUSH임을 의미합니다(대괄호는 끝점을 포함하는 범위를 정의합니다). 이 경우 다음 연산 부호는 i+2+(w−PUSH1)에 있습니다. PUSH1 (opens in a new tab)의 경우 2바이트(PUSH 자체와 1바이트 값)를, PUSH2 (opens in a new tab)의 경우 2바이트 값이므로 3바이트를 전진해야 합니다. 다른 모든 EVM 연산 부호는 길이가 1바이트이므로 다른 모든 경우에 N(i,w)=i+1입니다.

이 함수는 방정식 (152)에서 DJ(c,i)를 정의하는 데 사용되며, 이는 연산 부호 위치 i에서 시작하는 코드 c의 모든 유효한 점프 대상 집합 (opens in a new tab)입니다. 이 함수는 재귀적으로 정의됩니다. i≥||c||이면 코드의 끝 또는 그 이후에 있다는 의미입니다. 더 이상 점프 대상을 찾을 수 없으므로 빈 집합을 반환합니다.

다른 모든 경우에는 다음 연산 부호로 이동하여 해당 연산 부호에서 시작하는 집합을 얻어 나머지 코드를 살펴봅니다. c[i]는 현재 연산 부호이므로 N(i,c[i])는 다음 연산 부호의 위치입니다. 따라서 DJ(c,N(i,c[i]))는 다음 연산 부호에서 시작하는 유효한 점프 대상의 집합입니다. 현재 연산 부호가 JUMPDEST가 아니면 해당 집합을 반환합니다. 만약 JUMPDEST라면 결과 집합에 포함시켜 반환합니다.

9.4.4 정상 중단

중단 함수 H는 세 가지 유형의 값을 반환할 수 있습니다.

  • 중단 연산 부호에 있지 않으면 빈 집합인 를 반환합니다. 관례적으로 이 값은 부울 거짓으로 해석됩니다.
  • 출력을 생성하지 않는 중단 연산 부호(STOP (opens in a new tab) 또는 SELFDESTRUCT (opens in a new tab))가 있는 경우 반환 값으로 크기가 0바이트인 시퀀스를 반환합니다. 이는 빈 집합과는 매우 다릅니다. 이 값은 EVM이 실제로 중단되었지만 읽을 반환 데이터가 없음을 의미합니다.
  • 출력을 생성하는 중단 연산 부호(RETURN (opens in a new tab) 또는 REVERT (opens in a new tab))가 있는 경우 해당 연산 부호로 지정된 바이트 시퀀스를 반환합니다. 이 시퀀스는 메모리에서 가져오며, 스택 상단의 값(μs[0])은 첫 번째 바이트이고 그 뒤의 값(μs[1])은 길이입니다.

H.2 명령어 집합

EVM의 마지막 하위 섹션인 9.5로 가기 전에 명령어 자체를 살펴보겠습니다. 이는 29페이지에서 시작하는 부록 H.2에 정의되어 있습니다. 특정 연산 부호로 변경되도록 지정되지 않은 모든 것은 동일하게 유지될 것으로 예상됩니다. 변경되는 변수는 <something>'(으)로 지정됩니다.

예를 들어, ADD (opens in a new tab) 연산 부호를 살펴보겠습니다.

니모닉δα설명
0x01ADD21덧셈 연산.
μ′s[0] ≡ μs[0] + μs[1]

δ는 스택에서 팝하는 값의 수입니다. 이 경우에는 상위 두 값을 더하기 때문에 2입니다.

α는 다시 푸시하는 값의 수입니다. 이 경우에는 합계인 1입니다.

따라서 새 스택 상단(μ′s[0])은 이전 스택 상단(μs[0])과 그 아래의 이전 값(μs[1])의 합입니다.

"눈이 핑 도는 목록"으로 모든 연산 부호를 살펴보는 대신, 이 글에서는 새로운 것을 소개하는 연산 부호만 설명합니다.

니모닉δα설명
0x20KECCAK25621Keccak-256 해시를 계산합니다.
μ′s[0] ≡ KEC(μms[0] . . . (μs[0] + μs[1] − 1)])
μ′i ≡ M(μis[0],μs[1])

이것은 메모리에 접근하는 첫 번째 연산 부호입니다(이 경우 읽기 전용). 그러나 메모리의 현재 한계를 넘어 확장될 수 있으므로 μi를 업데이트해야 합니다. 이는 29페이지의 방정식 328에 정의된 M 함수를 사용하여 수행합니다.

니모닉δα설명
0x31BALANCE11주어진 계정의 잔액을 가져옵니다.
...

찾아야 하는 잔액의 주소는 μs[0] mod 2160입니다. 스택의 맨 위는 주소이지만 주소는 160비트이므로 모듈로 (opens in a new tab) 2160 값을 계산합니다.

σ[μs[0] mod 2160] ≠ ∅이면 이 주소에 대한 정보가 있다는 의미입니다. 이 경우 σ[μs[0] mod 2160]b는 해당 주소의 잔액입니다. σ[μs[0] mod 2160] = ∅이면 이 주소가 초기화되지 않았고 잔액이 0이라는 의미입니다. 계정 정보 필드 목록은 4페이지의 4.1절에서 확인할 수 있습니다.

두 번째 방정식, A'a ≡ Aa ∪ {μs[0] mod 2160}는 웜 저장 공간(최근에 접근되어 캐시될 가능성이 높은 저장 공간)과 콜드 저장 공간(접근되지 않아 검색 비용이 더 많이 드는 느린 저장 공간에 있을 가능성이 높은 저장 공간) 접근 비용의 차이와 관련이 있습니다. Aa는 8페이지의 6.1절에 정의된 대로 트랜잭션에서 이전에 접근한 주소 목록으로, 따라서 더 저렴하게 접근할 수 있어야 합니다. 이 주제에 대한 자세한 내용은 EIP-2929 (opens in a new tab)에서 확인할 수 있습니다.

니모닉δα설명
0x8FDUP16161716번째 스택 항목을 복제합니다.
μ′s[0] ≡ μs[15]

스택 항목을 사용하려면 팝해야 하는데, 이는 그 위에 있는 모든 스택 항목도 팝해야 함을 의미합니다. DUP<n> (opens in a new tab)SWAP<n> (opens in a new tab)의 경우, 이는 최대 16개의 값을 팝한 다음 푸시해야 함을 의미합니다.

9.5 실행 주기

이제 모든 부분을 갖추었으므로 EVM의 실행 주기가 어떻게 문서화되었는지 마침내 이해할 수 있습니다.

방정식 (155)은 다음과 같은 상태가 주어졌을 때를 나타냅니다.

  • σ (전역 블록체인 상태)
  • μ (EVM 상태)
  • A (하위 상태, 트랜잭션이 종료될 때 발생하는 변경 사항)
  • I (실행 환경)

새로운 상태는 (σ', μ', A', I')입니다.

방정식 (156)-(158)은 스택과 연산 부호로 인한 변경 사항(μs)을 정의합니다. 방정식 (159)는 가스의 변화(μg)입니다. 방정식 (160)은 프로그램 카운터(μpc)의 변화입니다. 마지막으로, 방정식 (161)-(164)는 연산 부호에 의해 명시적으로 변경되지 않는 한 다른 매개변수는 동일하게 유지된다고 명시합니다.

이것으로 EVM이 완전히 정의됩니다.

결론

수학적 표기법은 정확하며 옐로우 페이퍼가 이더리움의 모든 세부 사항을 명시할 수 있도록 했습니다. 하지만 몇 가지 단점이 있습니다.

  • 인간만이 이해할 수 있으므로 규정 준수 테스트 (opens in a new tab)를 수동으로 작성해야 합니다.
  • 프로그래머는 컴퓨터 코드를 이해합니다. 수학적 표기법을 이해할 수도 있고 그렇지 않을 수도 있습니다.

아마도 이러한 이유로 최신 합의 레이어 사양 (opens in a new tab)은 Python으로 작성되었습니다. Python의 실행 레이어 사양 (opens in a new tab)이 있지만 완전하지는 않습니다. 전체 옐로우 페이퍼가 Python이나 유사한 언어로 번역될 때까지 옐로우 페이퍼는 계속 사용될 것이며, 이를 읽을 수 있는 것은 도움이 됩니다.

페이지 마지막 업데이트됨: 2026년 2월 1일

이 튜토리얼이 도움이 되셨나요?