대중 과학: Ethereum Yellow Paper의 해석(2/7)
편집자 주: 이 기사의 출처는이더리움 애호가(ID: Ethfans)편집자 주: 이 기사의 출처는
이더리움 애호가(ID: Ethfans)
, 저자: Lucas Saldanha, 번역 및 교정: An Zi Clint & A Jian, 승인을 받아 Odaily에서 재인쇄함.
화면 앞에 있는 여러분이 Merkle 트리가 무엇인지, 이더리움에서 그 역할을 읽은 후 "월드 스테이트" 및 "계정 상태"의 개념을 이해하고 블록의 구조를 이해할 수 있기를 바랍니다.
(Disclaimer: 이 글은 2018년 6월 5일 Byzantine e94ebda 버전의 Yellow Paper를 기반으로 함)
보조 제목
머클 트리
이더리움의 주요 데이터 개체에 대해 논의하기 전에 Merkle 트리가 무엇인지, 그리고 이를 작동시키는 속성에 대해 간략하게 소개하고 싶습니다.
Merkle-Patricia 트리에는 흥미로운 속성이 많이 있으며 Ethereum에서 사용하는 방법에 대해 자세히 알아보려면 이 기사를 읽어 보는 것이 좋습니다.

Merkle 트리에서 리프 노드는 블록 데이터의 해시를 보유하고 비리프 노드는 하위 노드의 해시를 보유합니다.
이미지 설명
-머클 트리의 개략도(노드와 노드 간의 관계 포함)-
Merkle 트리가 가리키는 데이터가 변경되면 노드 해시가 변경됩니다. 각 부모 노드에 저장되는 해시 값은 자식 노드에 포함된 데이터에 따라 달라지므로 자식 노드의 데이터가 변경되면 부모 노드의 해시도 변경됩니다. 그리고 그러한 영향은 리프 노드에서 루트 노드로 이어지는 연쇄 반응입니다. 따라서 리프 노드가 가리키는 데이터가 변경되면 루트 노드가 저장한 해시가 변경됩니다. 위의 구조적 특징에서 두 가지 중요한 속성을 도출할 수 있습니다.
두 머클 트리가 가리키는 데이터가 정확히 같은지 판단할 때 각 리프 노드를 비교할 필요 없이 루트 노드에 저장된 해시만 비교하면 됩니다.
첫 번째 속성에 대한 중요한 점은 특정 순간에 전체 트리가 가리키는 데이터를 표시하기 위해 루트 노드의 해시 값만 사용할 수 있다는 것입니다. 즉, (블록체인에 모든 데이터를 저장하지 않고) 루트 노드의 해시 값을 저장해야만 블록에 마킹이 가능하고, 데이터를 변조할 수 없습니다.
지금까지 Merkle 트리에서 루트 노드 해시의 역할을 명확히 했으며, Ethereum의 주요 객체를 소개하겠습니다.
보조 제목
세계 상태는 주소(계정)에서 계정 상태로의 매핑입니다. 세계의 상태가 블록체인에 저장되지는 않지만 Yellow Paper의 설명에서 세계의 상태도 트리(이 트리는 상태 데이터베이스 또는 상태 트리라고도 함)에 의해 저장됩니다. world state는 트랜잭션이 실행됨에 따라 지속적으로 업데이트되는 전역 상태로 볼 수 있습니다. 이더리움은 분산형 컴퓨터와 같으며 세계의 상태는 이 컴퓨터의 하드 드라이브입니다.

이미지 설명
-세계 상태 트리 및 계정 저장소-
보조 제목
계정 상태
이더리움에는 외부 소유 계정(EOA)과 계약 계정의 두 가지 유형의 계정이 있습니다. 서로 이더리움을 주고받고 스마트 컨트랙트를 배포하기 위해 사용하는 계정이 EOA 계정이고, 스마트 컨트랙트 배포 시 자동으로 생성되는 계정이 컨트랙트 계정입니다. 각 스마트 계약에는 고유한 이더리움 계정이 있습니다.
nonce
계정 상태는 이더리움 계정의 다양한 정보를 반영합니다. 예를 들어, 현재 계정의 이더리움의 잔액 정보, 현재 계정에서 보낸 트랜잭션 수... 각 계정에는 계정 상태가 있습니다.
balance
계정 상태에 무엇이 포함되는지 살펴보겠습니다.
storageRoot
이 주소에서 전송된 트랜잭션의 수(현재 EOA 계정인 경우) 또는 이 계정에서 생성된 계약 생성 작업(현재 계약 생성 작업이 무엇인지 상관하지 않음).
codeHash
이 계정이 소유한 이더의 양(Wei로 측정).
계정 저장소 트리의 루트 노드의 해시 값(계정 저장소가 무엇인지는 나중에 소개하겠습니다).
계약 계정의 경우 EVM 코드의 해시 값을 저장하는 것은 이 계정입니다. EOA 계정의 경우 비워 둡니다.
codeHash의 불변성은 배포된 경우 취약성이 있는 스마트 계약을 수정하고 업데이트하는 것을 불가능하게 만듭니다. 이에 따라 하나의 새 계약만 배포할 수 있습니다(취약한 버전은 항상 블록체인에 존재합니다). 이것이 스마트 계약 개발 및 배포에 Truffle을 사용하고 Solidity로 프로그래밍할 때 모범 사례의 요구 사항을 따라야 하는 이유입니다.

-계정 상태 및 계정 스토리지 트리-
거래
보조 제목
거래
트랜잭션은 현재 상태에서 다음 상태로의 전환을 주도합니다. 이더리움에는 세 가지 유형의 트랜잭션이 있습니다.
EOA 간에 값을 전송하는 트랜잭션(예: 발신자와 수신자의 잔액 크기 변경).
계약의 트랜잭션을 호출하기 위해 메시지를 보냅니다(예: setter 메서드를 트리거하기 위해 메시지 호출을 보내 계약에 값을 설정하기 위해).
컨트랙트 배포를 위한 트랜잭션(따라서 컨트랙트 계정 생성).
nonce
(기술적인 관점에서 처음 두 트랜잭션은 동일합니다. 하나는 EOA 계정이고 다른 하나는 계약 계정이라는 점을 제외하면 메시지 호출을 통해 계정 상태를 변경하는 모든 트랜잭션입니다. 여기서 트랜잭션은 3가지로 구분하여 독자의 이해를 돕기 위함입니다.)
gasPrice
트랜잭션은 다음 부분으로 구성됩니다.
gasLimit
이 계정에서 발행된 트랜잭션의 수(교정 참고: 대략적으로 "이 계정의 첫 번째 트랜잭션입니다"로 이해될 수 있음).
to
이 트랜잭션을 수행할 때 계산을 수행할 때 가스 단위당 지불하는 수수료(Wei로 측정)입니다.
이 트랜잭션을 실행할 때 사용할 수 있는 최대 가스량입니다.
이 트랜잭션이 이더 전송을 위한 것이라면 이더를 받을 EOA 주소가 여기에 있습니다.
value
이 트랜잭션이 계약에 메시지를 보내는 데 사용되는 경우(예: 스마트 계약의 메서드 호출) 계약의 주소는 다음과 같습니다.
이 트랜잭션이 계약을 생성하는 데 사용되는 경우 여기의 값은 비어 있습니다.
이 트랜잭션이 이더를 보내거나 받는 경우 수신 계정으로 보낸 Wei 토큰의 양은 다음과 같습니다.
v, r, s
이 트랜잭션이 컨트랙트에 메시지 호출을 보내는 데 사용된다면 이 메시지를 받은 스마트 컨트랙트에 Wei가 지불한 금액입니다.
data이 트랜잭션을 사용하여 컨트랙트를 생성하는 경우 컨트랙트가 초기화될 때 계정에 저장된 Wei의 이더 금액은 다음과 같습니다.
거래의 발신자를 결정하는 데 사용할 수 있는 거래의 암호화 서명에 사용되는 값입니다.
init(가치 이전 및 스마트 계약에 메시지 호출 전송에만 사용됨)
메시지 호출에 첨부된 입력 데이터(예를 들어 스마트 계약에서 setter 메소드를 실행하려는 경우 데이터 영역에는 setter 메소드의 식별자와 설정하려는 매개 변수 값이 포함되어야 함).
(계약 작성에만 해당)
예상할 수 있듯이 블록의 모든 트랜잭션은 Merkle 트리에도 저장됩니다. 그리고 이 트리의 루트 노드의 해시 값은 블록 헤더에 의해 저장됩니다! 이더리움의 블록 구조를 분석해 봅시다.
차단하다
보조 제목
차단하다
블록 헤더는 이더리움 블록체인의 일부입니다. 이전 블록(부모 블록이라고도 함)의 해시 값을 저장하고 블록 헤더 연결을 통해 암호화된 보증 체인을 형성합니다.

블록 본문에는 이 블록에 기록된 일련의 트랜잭션과 엉클 블록(ommer) 블록 헤더 목록이 포함됩니다. 엉클블럭에 대해 더 알고 싶다면 이 글을 읽어보시길 추천합니다.
이미지 설명
parentHash
-이더리움 블록의 추상 개략도-
ommersHash
블록 헤더에는 어떤 부분이 포함되어 있는지 소개하겠습니다.
beneficiary
이전 블록의 블록 헤더 해시입니다. 각 블록에는 이전 블록의 해시가 포함되어 있으며 체인의 제네시스 블록까지 거슬러 올라갑니다. 이는 데이터가 변조되지 않도록 유지하는 구조적 설계이기도 합니다(이전 블록을 변조하면 이후 모든 블록의 해시 값에 영향을 미침).
stateRoot
엉클 블록 헤더와 블록 본문 일부의 해시 값입니다.
transactionsRoot
이 블록을 채굴하여 수입을 얻는 이더리움 계정.
receiptsRoot
세계 상태 트리의 루트 노드 해시(모든 트랜잭션이 실행된 후).
logsBloom
트랜잭션 트리 루트 노드의 해시 값입니다. 이 트리에는 블록 본체의 모든 트랜잭션이 포함됩니다.
difficulty
트랜잭션이 실행될 때마다 Ethereum은 결과에 해당하는 트랜잭션 영수증을 생성합니다. 다음은 트랜잭션 영수증 트리의 루트 노드 해시입니다.
number
특정 블록의 트랜잭션에 의해 특정 로그가 생성되었는지 확인하는 데 사용되는 Bloom 필터(이 측면에 관심이 있는 경우 Stack Overflow에서 이 답변을 참조할 수 있습니다). 이렇게 하면 로그 정보를 청크에 저장하지 않아도 됩니다(많은 공간 절약).
gasLimit
이 블록의 난이도 값입니다. 이것은 현재 블록 채굴의 난이도를 측정한 것입니다(이 개념의 세부 사항 및 계산은 여기에서 다루지 않습니다).
gasUsed
프리앰블 블록의 총 수입니다. 이것은 블록체인의 높이(즉, 블록체인에 있는 블록 수)를 나타냅니다. 제네시스 블록의 번호는 0입니다.
timestamp
모든 거래에는 가스 비용이 듭니다. 가스 한도는 이 블록에 기록된 모든 트랜잭션에서 사용할 수 있는 가스의 총량을 나타냅니다. 이는 블록 내 트랜잭션 수를 제한하는 수단입니다.
extraData
블록의 각 트랜잭션에서 실제로 소비한 가스의 총량.
mixHash
블록이 생성된 Unix 타임스탬프입니다. Ethereum 네트워크의 분산 특성으로 인해 특히 시간 관련 비즈니스 논리를 포함하는 스마트 계약을 작성할 때 이 값을 신뢰할 수 없다는 점을 명심하십시오.
nonce
무엇이든 입력할 수 있는 가변 길이 바이트 배열입니다. 광부가 블록을 만들 때 이 영역에 무엇이든 추가할 수 있습니다.
앗... 얘기하면 입이 떡벌어지네요... 천천히 천천히 흡수하시길 추천드려요! 하지만 이 글을 읽는 것이 모든 명사와 그 기능을 기억하는 것을 목표로 해서는 안 된다는 점을 다시 한 번 강조하고 싶습니다(Google에서 찾을 수 있음). 내 글의 원래 의도는 이더리움 개체의 모든 측면을 간단한 방법(적어도 노란색 종이보다 더 간단함)으로 소개하여 초보자가 이러한 전문 용어가 나타내는 것을 이해하도록 돕는 것입니다. 이 글을 "Ethereum Objects the Stupid Way 배우기"라고 생각하세요! 🙂
결론적으로
보조 제목
결론적으로
배운 내용을 간단히 요약해 봅시다! 일반적으로 Ethereum에는 4개의 접두사 트리가 있습니다.
세계 상태 트리에는 주소에서 계정 상태로의 매핑이 포함됩니다. 세계 상태 트리의 루트 노드의 해시 값은 블록이 생성될 때 현재 상태를 나타내는 블록(stateRoot 필드)에 의해 저장됩니다. 전체 네트워크에는 하나의 세계 상태 트리만 있습니다.
계정 저장소 트리는 특정 스마트 계약과 관련된 데이터 정보를 저장합니다. 계정 저장소 트리의 루트 노드(storageRoot 필드)의 해시는 계정 상태에 의해 저장됩니다. 각 계정에는 계정 스토리지 트리가 있습니다.
트랜잭션 트리에는 블록의 모든 트랜잭션 정보가 포함됩니다. 트랜잭션 트리의 루트 노드 해시는 블록 헤더(transactionsRoot 필드)에 저장됩니다. 각 블록에는 트랜잭션 트리가 있습니다.
트랜잭션 영수증 트리에는 블록의 모든 트랜잭션에 대한 영수증 정보가 포함됩니다. 또한 블록 헤더(receiptsRoot 영역에 있음)는 트랜잭션 수신 트리의 루트 노드의 해시 값을 보유하며 각 블록에는 해당 트랜잭션 수신 트리가 있습니다.
오늘 논의할 객체는 다음과 같습니다.
세계의 상태: 분산 컴퓨터 Ethereum의 하드 드라이브. 주소에서 계정 상태로의 매핑입니다.
계정 상태: 각 이더리움 계정의 상태 정보를 저장합니다. 계정 상태는 계정의 저장소 데이터를 포함하는 계정 상태 트리의 storageRoot도 보유합니다.
블록: 이전 블록(parentHash)에 대한 링크를 포함하고 실행될 때 시스템에서 새로운 상태가 되는 트랜잭션을 보유합니다. 블록은 또한 stateRoot, transactionRoot, receiptsRoot, 세계 상태 트리의 루트 노드 해시, 트랜잭션 트리 및 해당 트랜잭션 영수증 트리를 저장합니다.

기사에서 언급한 다양한 개념 정보를 그림으로 표현하고 싶습니다.
이미지 설명


