상태 머신이란 입력을 읽어서 새로운 상태로 전환하는 것입니다. 이더리움은 거래에 기반을 둔 상태 머신(Transaction-Based State Machine)입니다. 이더리움의 상태머신의 시작은 Genesis Block입니다. 이 후 새로운 트랜잭션이 실행되면 다음 상태로 전환되게 됩니다. 즉, 현재 상태는 새로운 트랜잭션이 들어오지 않은 마지막 상태입니다.
이더리움에는 여러개의 트랜잭션이 존재합니다. 각 트랜잭션들은 블록에 담기게 되며, 블록은 이전 블록과 연결되어 있습니다.
이더리움 계정(EOA, CA)
이더리움의 계정에는 EOA(Externally Owned Account)와 CA(Contract Account) 2가지 종류가 있습니다. 모든 계정들의 식별은 주소로 이뤄지며, 동일한 주소 공간을 가지고 있습니다. EVM은 160bit 길이의 주소들을 처리하게 됩니다. EOA와 CA 계정은 잔액(Balance), 논스(Nounce), 스토리지(StorageRoot), 컨트랙트 코드(Contract Code)로 구성되어 있습니다.
EOA와 CA계정의 차이점은 EOA는 주소에 연결된 비밀키를 가지지만 CA는 비밀키가 없습니다. 또한 CA는 스스로 새로운 트랜잭션을 생성할 수 없습니다. CA가 만드는 트랜잭션은 EOA나 다른 CA에서 받은 트랜잭션에 대한 응답을 통해서만 가능합니다. 즉 이더리움에서의 모든 액션은 항상 EOA가 만든 트랜잭션에서 부터 시작하게 됩니다.
- 잔액(Balance) : 계정의 현재 잔고(이더)
- 논스(Nounce) : EOA는 해당 EOA로 부터 보내진 트랜잭션 숫자, CA는 해당 CA로 부터 생성된 컨트랙스 숫자
- 스토리지(StorageRoot) : 머클 패트리시아 트리의 루트 노드를 해싱한 값
- 컨트랙트 코드(Contract Code) : EVM이 실행할 코드를 해싱한 결과값. EOA는 코드를 저장할 수 없어 비어있습니다.
이더리움 전역 상태(Global State)
이더리움의 전역 상태는 계정주소와 계정상태가 매핑된 상태입니다. 매핑은 머클 패트리시아 트리(Merkle Patricia Tree) 형태로 저장됩니다. 머클 트리는 저장하고자 하는 데이터를 청크(Chunk) 단위로 쪼개어 두개씩 모아 해싱하여 부모 노드를 생성합니다. 하나의 루트 노드가 남을 때 까지 반복해서 머클 루트를 생성합니다.
이더리움 블록 헤더에는 상태 트리(State Tree), 트랜잭션 트리(Transaction Tree), 영수증 트리(Receipt Tree) 3개의 머클 트리 구조에 기반한 루트 노드의 해싱값이 저장됩니다. 머클 투리 구조로 된 루트 노드들의 데이터는 단방향 해시 암호 기술을 사용하므로 보안 ID처럼 사용됩니다. 즉 이더리움 블록헤더에 담긴 상태, 트랜잭션, 영수증 루트 노드들은 네트워크 내의 노드들의 모든 상태를 저장하지 않더라도 상태를 점검할 수 있게 됩니다.
- 상태 트리(State Tree) : 트랜잭션과 연관된 계정 상태 정보
- 트랜잭션 트리(Transaction Tree) : 현재 블록의 트랜잭션 정보
- 영수증 트리(Receipt Tree) : 현재 블록의 거래 영수증 정보
이더리움 트랜잭션, 메시지(Message)
이더리움에서의 트랜잭션은 전역 상태를 다음 상태로 이동시키는 작업입니다. 이더리움은 트랜잭션 기반 상태 머신으로 항상 EOA에서 만들어지고 블록체인에 올라가게 됩니다. EOA에서 생성된 트랜잭션은 암호화 서명된 명령어 집합으로 구성되어 있고, 메시지 호출(Message Call)과 컨트랙트 생성(Contract Creations)로 구분됩니다. 이더리움에서의 트랜잭션은 CA라는 창구를 통해 외부 세계와 이더리움 세계를 연결해주는 브릿지 역할을 합니다.
이더리움 전역 상태의 CA는 메시지(Message)와 내부 트랜잭션(Internal Transaction)을 통해 다른 CA와 상호작용하게 됩니다. 메시지와 내부 트랜잭션은 EOA에서는 생성되지 않고, EVM에서만 존재하는 가상 객체입니다. 예를 들어 특정 CA가 다른 CA에게 내부 트랜잭션을 송신하면 수신 CA에서는 관련 코드를 실행시킵니다.
컨트랙트 생성(Contract Creation)
새로운 CA가 생성되기 위해서는 먼저 특수한 공식을 통해 새로운 계정 주소를 정의합니다. 이 후 논스를 0으로 지정하고 송신자가 CA 생성 트랜잭션에 이더를 보내는 경우 CA 잔액(Balance)에 설정합니다. 잔액에서 Value만큼을 제외하고 CA의 스토리지를 빈 값으로 초기화 합니다. 마지막으로 CA 코드를 빈문자열 해시값으로 초기화한 후 새로운 CA가 생성됩니다.
- 논스를 0으로 지정
- CA 생성 트랜잭션에 이더를 보낸 경우 CA 잔액으로 설정
- 잔액에서 Value만큼 제외
- CA의 스토리지 빈값으로 초기화
- CA 코드를 빈 문자열 해시값으로 초기화
계정이 초기화 되고 난 후 트잭잭션에서 보낸 init 코드를 통해 새로운 CA를 생성할 수 있게 됩니다. init 코드가 실행되는 동안 CA의 스토리지를 업데이트 하거나, 다른 CA를 새로 생성하거나, 다른 메시지 호출을 만들 수 있습니다. init코드를 실행하는데는 가스를 사용하게 됩니다.
트랜잭션을 수행할 때 마다 가스를 소비하게 되는데 남아있는 가스가 모두 소진된 경우 OOG(Out of Gas) 예외처리가 터지고 코드 실행이 강제로 종료되어 버립니다. 만약 OOG로 인해 트랜잭션이 종료되면 실행 이전 상태로 되돌아갑니다.
주의해야 할 점은 트랜잭션이 실패하는 경우에도 연산에 소모되었던 가스는 환불되지 않습니다. init코드가 성공적으로 실행되면 다음으로 CA 코드에 대한 스토리지 비용이 청구됩니다. 물론 CA 코드가 커질 수록 가스비도 비례하여 커집니다.
메시지 호출(Messae Call)
메세지 호출 시 새로운 계정이 생성되지 않았으므로 메시지 호출 실행에는 입력 데이터는 가지고 있을 수 있지만 init 코드를 포함하지 않습니다. 메시지 호출이 한번 실행되면 출력 데이터 등 추가적인 요소들을 가지게 되고 이후 이어지는 다른 실행에 사용하게 됩니다.
CA 생성과 마찬가지로 메시지 호출 할 때도 가스를 사용합니다. 가스가 부족한 경우 OOG 에러가 발생하거나, 트랜잭션 코드 오류(스택 오버플로우 에러, jump 가 잘못 실행된 경우 등)가 발생해도 사용된 가스는 환불되지 않습니다. 에러가 나는 경우 트랜잭션은 종료되고 이전 상태로 돌아갑니다.
이더리움 EVM
이더리움에서 트랜잭션을 처리하는 실제 프로토콜은 EVM입니다. EVM은 스택, 메모리, 스토리지로 구성됩니다.
- 스택(Stack) : EVM은 스택 기반 아키텍처를 가집니다. EVM내에는 1개의 스택이 존재하며 256bit~1024bit 크기를 가집니다.
- 메모리(Memory) : EVM에는 메모리가 존재하며 Word-Address 형식의 바이트 배열로 데이터를 저장합니다. 프로그램이 종료되면 메모리의 데이터는 사라집니다.
- 스토리지(Storage) : 스토리는 비휘발성입니다. 시스템 상태에 따라 데이터가 유지됩니다. EVM에서는 가상 ROM이라는 공간에 특정 명령어로만 접근하여 프로그램 코드를 분리/저장합니다.
EVM 은 솔리디티 코드를 컴파일한 바이트코드를 받으면서 시작됩니다. 최초 메모리/스택은 비어있으며 PC(프로그램 카운터)는 0으로 초기화 됩니다. 이후 트랜잭션을 반복적으로 실행하며 각 단계에서 시스템 상태(이더리움 전역 상태)와 머신 상태(사용 가능한 가스, PC, 메모리 값, 메모리에서 활성화된 단어 수, 스택의 값으로 구성)를 계산합니다. 코드가 실행되면 스택의 요소들은 왼쪽부터 처리되며 가스가 소진되면서 프로그램 카운터가 증가합니다.
PC(Program Counter) : 0
Stack : []
Memory : []
Storage : []
모든 사이클에서 만약 EVM이 예외상황을 만나는 경우 실행 중지되고 변경사항은 폐기됩니다. 정상적으로 종료되면 다음 사이클을 수행합니다. 정상적으로 머신 실행이 종료되면 결과값과 가스 잔액, 생성된 세부 상태등을 생성하게 됩니다.
Reference
'Blockchain' 카테고리의 다른 글
[Blockchain] 블록체인 오라클(Oracle) 문제란? (0) | 2022.07.11 |
---|---|
[Blockchain] 이더리움 프라이빗 네트워크 구축 방법 (0) | 2022.07.08 |
[Blockchain] 이더리움이란? (1) | 2022.07.07 |
[Blockchain] 비트코인 UTXO 뜻 원리 (0) | 2022.07.07 |
[Blockchain] 스마트 컨트랙트란? (0) | 2022.07.07 |
댓글