이더리움
블록체인이 화폐에서 실행 환경으로 확장되는 과정을 이해한다.
이더리움
이더리움의 핵심은 단순히 “ETH라는 코인”이 아니다.
비트코인이 탈중앙화된 장부 위의 화폐 시스템이라면 이더리움은 그 장부 위에서 프로그램을 실행할 수 있는 범용 실행 환경
즉, 비트코인이 다음 단계로 확장
1
2
3
4
5
비트코인
= 누가 얼마를 보냈는가를 검증하는 시스템
이더리움
= 누가 어떤 상태를 바꾸는 코드를 실행했는가를 검증하는 시스템
1. Account Model
- 비트코인은 계좌 잔액을 직접 저장하지 않는다. 대신 아직 쓰이지 않은 출력값, 즉 UTXO를 추적한다.
- 이더리움은 비트코인보다 은행 계좌 모델에 가깝다.(계정(Account)의 잔액을 직접 수정)
각 계정는 다음과 같은 상태를 가진다.
1
2
3
4
5
6
Account {
nonce
balance
storageRoot
codeHash
}
1.1 UTXO와의 차이
1. 비트코인은 사용 가능한 UTXO 집합을 소유
UTXO는 소비되면 영원히 사라지고 새로운 UTXO가 생성되는 방식으로 송금(거래)가 진행된다. 반면 이더리움의 Account Model은 은행 계좌와 같이 잔액만 변경하며 새로운 코인이 생성(confirm 하면서 거래가 확정)되거나 소멸되는 개념이 아니다.
2. 상태 저장 방식
비트코인은 현재 사용 가능한 모든 UTXO를 저장하며 잔액은 UTXO 계산 결과에서 산출된다. 반면 이더리움은 잔액 그 자체가 상태이다.
3. 스마트 컨트랙트 구현 난이도
예를 들어 게임 점수를 101로 바꾼다면 기존 UTXO를 소비하고 새 UTXO를 생성하고 confirm하며 매번 새로운 상태를 만들어야한다. 하지만 이더는 컨트랙트 저장소에 update 하면 끝난다.(직관적)
4. 병렬 처리 관점
비트코인은 하나의 UTXO를 동시에 사용하는 서로 다른 거래에 있어서도 충돌범위가 작다. UTXO 모델은 거래가 사용할 입력을 명시하기 때문이다. 즉 의존성 그래프를 만들기 쉽다. 하지만 Account Model은 아래와 같은 solidity 코드만 보고는 어떤 storage slot을 읽는지 쓰는지를 알기 어렵기 때문에 병렬 스케줄링이 어렵다.
contract.call(...)
5. Double Spending 방지 방식
비트코인은 같은 UTXO를 두번 소비할 수 없기 때문에 이미 사용된 UTXO를 재사용하면 무효가 되거나 아예 재사용이 불가해 진다. 이더는 Account마다 nonce를 사용하여 같은 nonce의 거래는 한번만 처리한다.
여기서 nonce는 거래를 할때마다 증가하는 카운터와 비슷한 개념
2. EVM의 개념
이더리움 블록체인 위에서 스마트 컨트랙트를 실행하는 가상 컴퓨터
쉽게 말하자면
- 이더리움 = 운영체제
- EVM = CPU + 실행환경(virtual machine)
- 스마트 컨트랙트 = 프로그램
이더리움 네트워크의 모든 노드는 동일한 EVM을 실행하며, 같은 입력이 들어오면 반드시 같은 결과를 내야 합니다. 이것이 블록체인의 결정성(Determinism) 입니다.
2.1 EVM의 동작 구조
아래의 방식으로 실행되는데
1
2
3
4
5
6
7
8
9
Solidity 코드
↓
컴파일
↓
Bytecode
↓
EVM 실행
↓
State 변경
예를 들어 Solidity 코드가 다음과 같다면
contract Counter {
uint256 public count;
function increase() public {
count++;
}
}
이를 컴파일하여 EVM이 이해할 수 있는 바이트코드로 변환됩니다.
1
2
3
4
5
PUSH1
SLOAD
ADD
SSTORE
...
EVM이 블록체인 위에서 이 명령어 들을 하나씩 실행하여 계좌의 상태를 변경해 나갑니다.
2.2 EVM은 스택 머신이다.
언뜻보면 JVM과 굉장히 유사한 기능을 가지고 있는 것을 확인할 수 있다. 하지만 EVM은 JVM처럼 레지스터 기반이 아니라 Stack Based VM 입니다.
그리고 핵심적으로 EVM은 단순 실행기가 아니라 네트워크 전체의 상태를 일관되게 유지하는 분산 상태 머신이라는 점이 가장 큰 차이이다
2.2.1 레지스터 기반
가상의 레지스터가 있다고 가정합니다.
1
2
3
R1 = 2
R2 = 3
R3 = R1 + R2
명령어가 어느 저장소의 값을 쓸지 직접 지정한다.
ADD R3, R1, R2
2.2.2 스택 기반
레지스터 이름이 없다. 대신 스택 맨 위 값을 사용한다.
1
2
3
PUSH 2
PUSH 3
ADD
실행 흐름
1
2
3
4
5
6
7
초기: []
PUSH 2: [2]
PUSH 3: [2, 3]
ADD: [5]
ADD는 자동으로 스택 최상단 2개 값을 꺼낸다.
1
2
3
a = pop()
b = pop()
push(a + b)
solidity에선 실제로 uint256 x = 2 + 3; 이런 명령어가 있으면 EVM 관점에서는 아래와 같이 컴파일 된다.
1
2
3
PUSH1 0x02
PUSH1 0x03
ADD
3. Smart Contract
이더리움 스마트 컨트랙트(Ethereum Smart Contract)는 블록체인 위에서 실행되는 프로그램이다. 특정 조건이 충족되면 자동으로 정해진 동작을 수행하도록 작성된 코드라고 보면 된다.
은행 없이도 다음과 같은 계약을 구현할 수 있다.
- A가 1 ETH를 입금
- B가 상품을 배송
- 배송 완료가 확인되면
- 스마트 컨트랙트가 자동으로 B에게 1 ETH 지급
3.1 특징
1. 자동 실행
미리 작성된 조건에 따라 자동으로 실행한다.
1
2
3
4
5
6
IF 조건 충족
THEN 실행
=>
if (balance >= 1 ether) {
transfer(receiver, 1 ether);
}
2. 변경 불가능성(Immutability)
- 버그가 있으면 큰 문제가 될 수 있음
- 배포 전 철저한 테스트 필요
3. 투명성
컨트랙트 코드는 누구나 확인할 수 있다. 예를 들어 Ethereum 블록체인에 배포된 컨트랙트는 공개적으로 조회 가능하다.
4. 탈중앙화
특정 서버에서 실행되는 것이 아니라 전 세계 수천 개 노드가 동일한 코드를 실행한다. 따라서,
- 서버 장애에 강함
- 검열 저항성 존재