無知

갈 길이 먼 공부 일기

기술 공부/블록체인

이더리움의 작동방식 (2) | 계정, 트랜잭션 논스, 머클 파트리샤 트리

moozii 2022. 1. 5. 20:12

* 이 글은 How does Ethereum work, anyway? 라는 글을 읽어가며 이해한 바를 한국어로 번역하여 정리하는 글입니다. 시리즈의 형태로 끊어가며 업로드되었으니, 참고 부탁드립니다.

 

이더리움 블록체인의 구성 요소

 

이더리움 블록체인은, 

계정 / 상태 / 가스 및 수수료 / 상호작용 / 블록 / 상호작용의 집행 / 채굴 / 작업 증명 

등으로 구성된다. 

 

또한, 이더리움 내의 해쉬를 이야기할 때는, KECCAK-256 해쉬를 의미한다. 

이더리움은 해당 해쉬를 기반으로 한다. 

 

 

1. 계정

글로벌하게 상태를 공유하는 이더리움은, <메시지 전송 프레임워크>를 기반으로 서로 상호작용이 가능한 여러 계정들로 구성되어 있다. 

각 계정은, 계정의 현재 상태와, 20바이트 크기의 계정 주소를 보유하고 있다. 

이더리움의 주소는 각 계정 별로 식별 가능한 고유 식별자 160바이트를 의미한다.

 

계정의 종류에는 두 가지가 있다. 

 

1. 외부 소유 계정 : 프라이빗 키로 통제되며, 코드가 연동되지 않은 계정을 의미한다.

2. 계약 계정 : 계약 코드에 의해 통제되며, 코드가 연동된 계정을 의미한다.

 

외부 소유 계정은, 다른 외부 소유 계정 혹은 계약 계정에 메시지를 전송할 수 있다. 

메시지를 전송하는 방식은, 프라이빗 키를 활용한 상호작용의 생성 및 서명이다.

두 개의 외부 소유 계정 간 메시지 전송은 단순한 값의 전송이다. 

이에 반해 외부 소유 계정에서 계약 계정으로 메시지를 전송하는 과정은, 

계약 계정의 코드를 실행하기 때문에, 다양한 액션을 실행시킬 수 있다. 

그 과정에서 토큰을 이동실 수도 있고, 내부 스토리지에 무언가를 작성할 수도 있고, 

새로운 토큰을 생성(민팅)할 수도 있고, 특정 계산 작업을 수행하거나, 새로운 계약을 생성할 수도 있다.

 

외부 소유 계정과 달리, 계약 계정은 신규 상호작용을 스스로 작동시킬 수 없다. 

대신, 계약 계정은 다른 계정 (외부 소유 계정 혹은 다른 계약 계정)으로부터 수령한 상호작용의 반응 차원에서만, 

상호작용을 시작할 수 있다.

 

https://preethikasireddy.medium.com/how-does-ethereum-work-anyway-22d1df506369

 

즉, 이더리움 블록체인 내 모든 액션은, 

외부 소유 계정에서 최초로 시작된 상호작용의 연쇄작용으로 발생한다. 

 

2. 상태

2-1. 계정 상태

 

계정 상태라 함은 4개의 구성 요소를 가진다. 

 

2-1-1. 논스 (트랜잭션 논스)

논스는 계정의 상태 별로 정의가 사뭇 다르다. 

외부 소유 계정의 상태에서의 논스란, 해당 계정 주소가 전송한 거래/상호작용의 수이다.

계약 계정의 논스란, 해당 계정이 생성한 계약의 수이다.

 

사실 어떤 계정(주소)이 전송한 트랜잭션 개수라고 정의해도 무방하다. 

계약 계정이 계약을 생성할 때에도 트랜잭션을 전송하는 행위이기 때문에, 계약 수 = 트랜잭션 수로 일치한다. 

 

nonce: If the account is an externally owned account, this number represents the number of transactions sent from the account’s address. If the account is a contract account, the nonce is the number of contracts created by the account.

https://preethikasireddy.medium.com/how-does-ethereum-work-anyway-22d1df506369

 

블록체인 채굴에서의 논스와 트랜잭션 논스는 다르다!

<블록체인 채굴에서의 논스(임시 값)>

논스(nonce)는 블록체인에서 목표값 이하의 블록 해시를 찾기 위해 임시로 사용하는 숫자이다. 넌스, 난스 또는 임시 값이라고도 한다.
일반적으로 블록의 해시값은 해당 블록의 생성일시, 버전, 비츠(bits), 루트 해시, 이전 블록의 해시, 그리고 논스(nonce)라고 불리는 임시 값 등을 조합한 후 해시로 변환하여 생성한다. 해당 블록의 생성 일시, 버전, 난이도, 루트 해시와 이전 블록의 해시값은 이미 확정되어 정해진 값을 가지고 있지만, 논스라는 임시 값이 달라짐에 따라 해시 연산 결과로 생성되는 블록 해시값도 다양하게 나올 수 있다. 예를 들어 논스가 1인 경우의 해시값과 2인 경우의 해시값은 전혀 다르다. 이 논스 값을 수없이 바꿔가면서 하나씩 대입하다가 새로 생성된 해시값이 일정한 목푯값보다 더 작을 경우에 새로운 블록이 성공적으로 생성된다. 이처럼 특정한 블록에 대해 목표값 이하의 크기를 가진 해시값을 생성하는 논스값을 찾음으로써 새로운 블록을 생성하는 행위를 작업 증명(PoW)이라고 한다. 작업 증명의 대가로 일정한 개수의 암호화폐를 지급받는 것을 채굴(採掘) 또는 마이닝(mining)이라고 한다. 결국 채굴을 통한 작업 증명 과정은 목푯값 이하의 블록 해시를 생성하는 '논스값'을 찾는 행위이다.

http://wiki.hash.kr/index.php/%EB%85%BC%EC%8A%A4_(%EC%9E%84%EC%8B%9C%EA%B0%92)
<이더리움 트랜잭션 논스의 정의와 그 필요성>

아래 인용한 문장을 다시 한번 읽고 이더리움이 비트코인과 달리 계정 기반이고, 계정 기반 프로토콜의 경우 ‘논스’와 같은 개념이 필수적으로 사용될 수밖에 없음을 이해하도록 합니다. 비트코인은 UTXO를 가지고 잔고를 관리하지만 이더리움은 계정에 직접 잔고를 두고 관리합니다.

It is important to note that the use of the nonce is actually vital for an account-based protocol, in contrast to the “Unspent Transaction Output” (UTXO) mechanism of the Bitcoin protocol.

비트코인에서는 비트코인 잔고가 UTXO set으로 관리됩니다. 비트코인 전송에 사용된 UTXO들은 트랜잭션이 처리되고 나면 UTXO set에서 제거되어 더 이상 사용할 수 없게 됩니다. 같은 트랜잭션을 복제해서 실행한다고 해도 입력이 참조한 UTXO가 더 이상 UTXO가 아니기 때문에 유효하지 않은 트랜잭션이 됩니다.

이더리움의 경우 잔고는 잔고 값으로 관리됩니다. 트랜잭션이 실행되면 잔고 값이 바뀌는 것입니다. 잔고 값만 바꿀 수 있다면 잔고를 조작하는 것이 가능하다는 것입니다. 같은 트랜잭션을 반복한다면 잔고가 있는 한 반복해서 이더를 인출할 수 있게 됩니다. 이러한 반복 실행을 막기 위해 이더리움이 선택한 방법이 논스입니다. ‘논스’라는 용어는 채굴에서도 같은 용어를 사용하기 때문에 블록의 논스와 트랜잭션 논스를 구분할 수 있어야 합니다.

http://www.umlcert.com/mastering_ethereum-4/

 

2-1-2. 잔고 (Balance)

계정 내에 소유한 Wei의 수를 의미한다. 이더리움 당 1e+18 Wei가 존재한다. 

웨이(wei)는 이더리움에서 사용하는 암호화폐인 이더의 가장 작은 단위이다. 1 웨이(wei)는 10^-18 이더(ether)와 같다. 다시 말하면, 1 이더(ether)는 10^18 웨이(wei)와 같다. 웨이는 기본적으로 인식할 수 없을 정도의 작은 디지털 단위로서, 기술적인 경우나 코드 작성에만 사용된다.

http://wiki.hash.kr/index.php/%EC%9B%A8%EC%9D%B4_(%EB%B8%94%EB%A1%9D%EC%B2%B4%EC%9D%B8)

 

2-1-3. 스토리지 루트 (storageRoot)

머클 파트리샤 트리 자료 구조의 루트 노드의 해쉬 값을 의미한다. 

이 트리 구조는 계정의 스토리지 콘텐츠의 해쉬를 인코딩하는 구조이다. 

(디폴트로는 비어있다)

머클 트리(Merkle Tree)는 블록에 포함된 거래 내역을 나무 형태로 요약한 것이다. 1979년 머클 트리를 개발한 랄프 머클(Ralph Merkle)의 이름을 따서 머클 트리라고 부르며 해시 트리(Hash Tree), 혹은 이진트리(Binary Tree)라고도 한다.

머클 트리는 블록 내에서 다수의 원장(ledger)들을 암호화하고 합치는 과정을 반복하여 최종적으로 하나의 유닛(Unit)으로 암호화하는 방법이다. 머클 트리의 형태는 블록이 보유하고 있는 거래 내역들의 해시값을 가장 가까운 거래내역끼리 쌍을 지어 해시화하고, 쌍을 지을 수 없을 때까지 해당 과정을 반복하여 완성되는데, 이 과정을 통해 다수의 데이터를 하나로 묶어 용량을 절약할 수 있다. 머클 트리에서는모든 거래내역들을 해시화한 머클 루트를 통해 거래내역의 변동 여부를 쉽게 확인할 수 있고 이 머클 루트를 헤더에 담아 트랜잭션의 유효성을 보장한다. 또한 머클 경로(Merkle path)를 제공받아 특정한 트랜잭션이 블록에 유효하게 있는 효율적인 검사가 가능하다. 즉, 머클 트리는 모든 정보를 압축하여 간단하게 표현한 데이터로서 머클 트리를 통해 데이터의 간편하고 확실한 인증이 가능하다.

http://wiki.hash.kr/index.php/%EB%A8%B8%ED%81%B4%ED%8A%B8%EB%A6%AC

 

2-1-4. 코드 해쉬

이 계정의 이더리움 가상 머신 코드의 해쉬를 의미한다.

계약 계정의 경우, 코드 해쉬는 실제로 해쉬 되어 코드 해쉬로 저장되지만, 

외부 소유 계정의 경우 빈 스트링이 코드 해쉬 자리를 채운다.

이더리움의 심장부에는 가상 컴퓨터가 있다. 바로 이더리움 가상 머신, 즉 EVM(Ethereum Virtual Machine)이다. EVM은 플랫폼을 이루는 수만 개의 노드에 저장되어 있으며, 이더리움을 구성하는 수많은 토큰과 분산 애플리케이션 댑(dapp), 탈중앙화 자율조직 DAO, 크립토 키티의 실행을 책임진다. EVM은 이더리움 전체를 작동하는 엔진으로 “EVM 바이트코드(bytecode)”라는 언어를 사용한다. EVM 바이트코드는 (플랫폼이 스스로 부과하는 한계인 가스의 범위 내에서) 조합 가능한 모든 계산을 수행할 수 있는 256비트의 원시 문자열 정보로 구성된다.

출처 : 코인데스크 코리아 (http://www.coindeskkorea.com/news/articleView.html?idxno=28961)
비탈릭 부테린은 이더리움 가상 머신(EVM, Ethereum Virtual Machine)이라는 새로운 기술을 도입했다. 이더리움은 프로그래밍이 가능한 블록체인으로서, 사용자에게 사전 정의된 일련의 작업을 제공하기보다 사용자가 원하는 복잡성을 따라 직접 작업을 만들 수 있도록 한다. 좁은 의미에서 이더리움은 디앱을 위한 플랫폼을 정의하는 일련의 프로토콜을 의미한다. 그 중심에 이더리움 가상 머신이 있다. 이더리움 가상 머신은 임의의 복잡한 알고리즘 코드를 실행할 수 있다. 개발자는 자바스크립트 및 파이썬과 같은 기존 언어를 모델로 한 친숙한 프로그래밍 언어를 사용하여 이더리움 가상머신 위에서 실행되는 응용 프로그램을 만들 수 있다. 즉, 이더리움은 이더리움 가상 머신이라고 하는 블록체인에서 실행 환경을 구현한다. 네트워크에 참여하는 모든 노드는 블록 검증 프로토콜의 일부로 이더리움 가상 머신을 실행한다. 네트워크 내 모든 노드는 이더리움 가상머신을 구동하는 것이다. 모든 노드는 이더리움 가상머신을 사용해 스마트 계약을 가리키는 모든 트랜잭션을 실행하므로 모든 노드는 동일한 계산을 수행하며 같은 값을 저장한다. 이렇게 이더리움 가상 머신(EVM)을 통해 모든 노드들의 컴퓨터에서 동일한 연산을 수행함으로 동일한 상태(state)에 합의한다. 이더리움은 전 세계 모든 참가자가 동일한 하나의 컴퓨터를 돌리는 것과 같기 때문에 '세계 컴퓨터'(world computer)라고 불리기도 한다.

스마트 계약에 기반한 디앱은 모두 이더리움 가상 머신(EVM) 환경에서 동작하며, 솔리디티라는 이더리움 고유의 프로그래밍 언어로 작성된다. 이것을 solc로 컴파일해서 생성된 이더리움 바이트코드는 geth를 통해 블록체인에 등록된다. 블록체인에 저장된 바이트코드는 결국 이더리움 가상 머신(EVM)에서 실행된다. geth와 이더리움 가상 머신은 하나의 프로세스로 동작하고, 솔리디티로 작성된 스마트 계약은 이더리움 가상머신에서 동작하기 때문에 특정 운영체제에 종속되지 않는다.

이더리움 가상 머신은 앞으로 웹 어셈블리(WASM) 언어 기반으로 변경될 예정이다. 이더리움 가상머신은 내부적 일관성도 있고 광범위한 명령어를 사용할 수 있는 장점이 있지만, 현실 세계에서 프로그램을 구현하려고 하면 상당이 불편하고 제약이 많다는 비판을 받고 있다. 이더리움의 핵심 개발자인 닉 존슨은 "이더리움 가상머신은 상용화보다는 순수 이론에 적합하다"고 말했다. 반면, 웹어셈블리 코드는 처음부터 대량생산을 염두에 두고 개발되었기 때문에 프로그램 작업이 매우 효율적이며, 하드웨어 명령어를 정교하게 다룰 수 있고, 솔리디티가 아닌 다른 여러 언어를 사용하여 자유롭게 코딩할 수 있다. 웹 어셈블리를 사용하면 시스템 업그레이드를 할 때마다 굳이 번거로운 하드 포크를 하지 않고도 스마트 계약만으로 연산을 간단히 작성할 수 있다는 장점이 있다.

http://wiki.hash.kr/index.php/%EC%9D%B4%EB%8D%94%EB%A6%AC%EC%9B%80

 

2-2. World State

이더리움의 글로벌 상태란, 

계정의 주소와 계정의 상태를 매핑하는 것으로 구성됨을 알게 되었다. 

이 연결 정보는 머클 패트리샤 트리라는 자료 구조로 저장된다. 

 

머클 트리는, 아래의 노드들로 구성된 이진트리 구조이다. 

1. 데이터를 보유한 리프 노드

2. 두 자식 노드의 해시 값을 가지는 중개 노드

3. 루트 노드 (두 자식 노드의 해시 값으로 트리 전체를 나타냄)

 

각 노드는 각각의 값 (해시 혹은 노드)과 함께 키를 가지는데, 

각 키는 어느 자식 노드와 연결되어 있는지를 가리킨다. 

이더리움의 경우 키-값 매핑이 계정 주소 - 계정으로 진행되며,

계정은 여러 구성요소(잔고, 논스, 코드 해시, 스토리지 루트)로 구성된다.

 

Source: Ethereum whitepaper

이진트리는, 각 노드가 최대 두 개의 자식 노드를 가지는 트리 자료 구조를 의미한다.
https://ko.wikipedia.org/wiki/%EC%9D%B4%EC%A7%84_%ED%8A%B8%EB%A6%AC
해시 트리 혹은 머클 트리는, 모든 비-리프 노드의 이름이 자식 노드들 이름의 해시로 구성된 트리 구조를 의미한다. 
(잎 노드는 가장 끝 노드를 의미하는 것으로, 머클 트리에서는 파일 등의 데이터를 의미한다.)

상위 노드는 각 자식 노드의 해시 값이 되기 때문에, 
데이터를 검증하고자 하는 사용자는 루트 노드의 해시 값(루트 해시 혹은 마스터 해시)만 알면 데이터가 옳은지를 확인할 수 있다.

https://ko.wikipedia.org/wiki/%ED%95%B4%EC%8B%9C_%ED%8A%B8%EB%A6%AC
Patricia Tries are n-ary trees which unlike Merkel Trees, is used for storage of data instead of verification. To simply put, Patricia Tries is a tree data structure in which all the data is store in the leaf nodes, where each non-leaf nodes is a character of a unique string identifying the data.

https://medium.com/coinmonks/implementing-merkle-tree-and-patricia-trie-b8badd6d9591
보다 선명한 이해를 위해서는 비트코인의 "머클 트리"는 "바이너리 머클 트리"라고 말해야 하며, 이더리움의 "머클 패트리샤 트리" 는 "상태전이 일반 머클 확장 페트리샤 트리" 라고 말해야 합니다. 각각의 단어마다 중요한 의미를 가지고 있으며 본 글을 통해 차차 설명드릴 예정입니다. 

1) 상태 전이 : 기존 블록체인에서는 거래 내역을 계속 쌓으며 값을 교체해나가지 수정하지 않는데, 이더리움은 이와 달리 상태 전이를 통해 상태 값을 수정해서 증감시키는 변화가 일어난다는 특징을 이야기합니다. 공간을 절약하는 효과가 발생합니다.

2) 상태 전이 일반 머클 트리 : 앞서 이야기한, <이더리움은 값을 변경시켜 상태 전이를 진행한다>는 특성을 반영해, 값이 변경될 때마다 새로이 그 값을 저장하는 이진 머클 트리를 생성하는 것이 아니라, 변경되지 않은 값은 과거의 트리와 공유하고, 새로이 변경하는 노드만 신규로 생성해 트리를 만드는 방식을 의미합니다. 공간을 절약하는 효과가 발생합니다.

3) 패트리샤 트리 : 각 데이터를 잎 노드(끝)에 기록하는 방식이 아니라, 각 공통되는 부분은 공유하도록 데이터를 쪼개서 노드에 저장하는 방식의 트리를 의미합니다. 공간을 절약하는 효과가 발생합니다.

4) 확장 패트리샤 트리 : 이더리움은 3번의 패트리샤 트리를 조금 더 확장해서 사용합니다.
확장 노드는, 공유하는 니블(4비트) 주소 값을 가지고 있으며, 다음 노드를 가리키고,
브랜치 노드는, 0~f까지 공유하는 니블(4비트) 주소 값과 Value를 보유하고 있고,
리프 노드는 가지의 끝에서, 마지막 주소 값과 함께 Value 값을 저장하고 있어,
주소 값은 쪼개서 저장하는 패트리샤 트리 구조로 공간을 절약하되, 노드의 역할을 구분해 이를 수행하게 하고, 
리프에는 값을 해당 계정 주소의 상태 값을 가지고 있도록 합니다.

즉 머클 패트리샤 트리는, 
확장 패트리샤 구조를 통해 상위 노드로 올라가면서 최종적으로 루트 해시를 만들어내고, 
상태 전이를 반영한다는 특성을 가지고 있습니다.

https://hamait.tistory.com/959

 

이러한 트리 형태의 자료 구조는 트랜잭션 저장에도 활용된다.

각 블록은 <헤더>를 보유해, 총 3개의 머클 트리의 루트 해시를 저장한다. 

각 트리는, 상태 트리, 트랜잭션 트리, 영수증 트리이다.

https://preethikasireddy.medium.com/how-does-ethereum-work-anyway-22d1df506369

머클 트리의 정보 저장 방식은 라이트 노드 사용에 있어 매우 효율적이다. 

라이트 노드는, 머클 트리 정보와 같은 거래 내역 핵심본만을 저장한 가벼운 노드를 의미한다.

그에 반해 풀 노드는 체인의 시작점부터 전체를 모두 다운로드해 블록체인 전체와 동기화를 진행한다.

하지만 굳이 모든 노드가 전체 체인을 저장하고 있을 필요는 없기 때문에 라이트 노드를 활용한다.

체인의 헤더만을 다운로드하여 트랜잭션 실행 없이 트랜잭션에 대한 검증 가능한 답을 생성 및 수령하는 정도만 가능한 것이 라이트 노드이다.

머클 트리는 루트를 향해 올라가는 형식의 해시를 취해서, 거래 내역의 일부만 변경되어도 변조 여부를 확인할 수 있다는 특성을 활용해, 가볍게 검증하고자 하는 라이트 노드에서 활용하기 좋다.

 

라이트 노드(light node)는 블록체인 거래내역 중 일종의 핵심본만 저장하는 노드이다. 모든 블록 정보를 가지고 있지 않고, 필요한 부분만 저장한다는 특징이 있다. 블록체인 네트워크의 모든 거래 정보를 모두 가지고 있으면 풀 노드(full blockchain node), 머클 트리만 가지고 있으면 라이트 노드(lightweight node)라고 부른다.

노드는 풀 노드(full node)와 라이트 노드(light node)로 나뉜다. 풀 노드는 네트워크의 모든 거래정보를 전부 저장하고 사용자들의 지갑을 관리한다. 라이트 노드는 사용자 지갑을 저장하지만 네트워크 접근을 위해 풀 노드에 의존한다. 노드는 네트워크의 구성 요소이며 풀 노드는 블록체인을 유지하는 것, 라이트 노드는 참여자를 위해 접속 권한을 부여하는 것이라고 이해할 수 있다. 금고와 파수꾼 비유를 다시 사용해보면 풀 노드는 군대급의 강화된 파수꾼이고, 라이트 노드는 금고를 활용해 입출금을 시도하는 통로로 볼 수 있다. 풀노드와 라이트노드 중에서 블록체인 네트워크에 기여가 큰 것은 역시 풀 노드이다. 결국 라이트 노드와 개별 노드는 노드에 저장되어 있는 블록체인을 읽어 와서 네트워크에 참여되는 것이기 때문이다.

http://wiki.hash.kr/index.php/%EB%9D%BC%EC%9D%B4%ED%8A%B8%EB%85%B8%EB%93%9C

 

 

머클 패트리샤 트리의 의의는,
구조 상 루트 노드 값은 트리 내 데이터와 상호의존적이므로,
데이터가 변조되지 않았다는 보안 인증을 제공하는 것과 같다는 것이다.

블록 헤더가 루트 해시의 상태, 거래 내역, 영수증 트리 등을 포함하는 한,
어떠한 노드도 이더리움 상태의 일부를, 전체 상태를 저장하지 않더라도 검증해낼 수 있다.