합의 알고리즘: 분산 네트워크가 동의에 이르는 방법
수천 개의 노드가 각자 다른 트랜잭션을 받고, 각자 다른 블록을 만들려고 할 때, 어떻게 모두가 동일한 블록체인에 동의할 수 있을까? 이것이 합의(Consensus) 문제다.
1. 비잔틴 장군 문제
합의 알고리즘을 이해하려면 먼저 **비잔틴 장군 문제(Byzantine Generals Problem)**를 알아야 한다.
시나리오: 비잔틴 제국의 군대가 적의 도시를 포위하고 있다.
여러 장군이 각기 다른 위치에 있으며 전령을 통해 소통한다.
장군 A
/ \
전령 전령
/ \
장군 B ─────전령──── 장군 C
(배신자)
- 장군들은 "공격" 또는 "후퇴"를 투표해야 함
- 과반수가 같은 행동을 해야 성공
- 문제: 일부 장군(또는 전령)이 배신자일 수 있음
- 배신자는 거짓 메시지를 보내거나,
어떤 장군에게는 "공격", 다른 장군에게는 "후퇴"를 전달할 수 있음
블록체인에서의 대응:
- 장군 = 네트워크 노드
- 메시지 = 블록, 트랜잭션
- 배신자 = 악의적인 노드 (해커, 버그가 있는 노드)
- 합의 = 모든 정직한 노드가 같은 블록체인 상태에 동의
이론적으로 비잔틴 내결함성(BFT)을 달성하려면 전체 노드 중 최대 1/3만이 악의적이어야 한다 (3f+1 규칙).
2. Proof of Work (PoW) — 작업 증명
2.1 핵심 아이디어
“계산 작업을 많이 한 사람이 블록을 추가할 권리를 얻는다.”
CPU/GPU 연산 능력을 소모해야 블록을 생성할 수 있으므로, 공격하려면 엄청난 실제 자원(전기, 하드웨어)이 필요하다.
2.2 채굴 과정 상세
채굴자의 목표:
SHA256(블록 헤더) 값이 특정 목표값보다 작아야 한다
목표값 (난이도에 따라 달라짐):
00000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
(앞에 0이 8개)
채굴 루프:
nonce = 0
반복:
hash = SHA256(SHA256(헤더 + nonce))
if hash < target:
블록 발견! 네트워크에 전파
else:
nonce += 1
왜 어려운가? SHA-256의 출력은 완전히 예측 불가능하다. 올바른 nonce를 찾는 유일한 방법은 일일이 시도해보는 것(무차별 대입)뿐이다.
확률 예시:
- 해시 앞에 0이 10개 필요: 1/16^10 = 1/1,099,511,627,776 확률
- 즉 평균 1조 번 이상의 계산이 필요
2.3 난이도 조절
비트코인은 2,016블록(약 2주)마다 난이도를 자동 조절한다:
실제 소요 시간 < 2주: 난이도 상승 (더 어렵게)
실제 소요 시간 > 2주: 난이도 하락 (더 쉽게)
목표: 항상 평균 10분당 1블록
예시:
이전 2주간 블록 생성: 1,500개 (목표의 74.4%)
→ 10분이 걸릴 것들이 평균 8.1분에 생성됨
→ 난이도를 10/8.1 = 1.23배 상승
2.4 Rust로 PoW 시뮬레이션
use sha2::{Sha256, Digest};
use std::time::Instant;
fn mine_block(data: &str, difficulty: usize) -> (u64, String) {
let target = "0".repeat(difficulty);
let start = Instant::now();
let mut nonce: u64 = 0;
loop {
let input = format!("{}{}", data, nonce);
let mut hasher = Sha256::new();
hasher.update(input.as_bytes());
let hash = hex::encode(hasher.finalize());
if hash.starts_with(&target) {
let elapsed = start.elapsed();
println!("채굴 완료!");
println!(" nonce: {}", nonce);
println!(" hash: {}", hash);
println!(" 시간: {:.3}초", elapsed.as_secs_f64());
println!(" 시도 수: {}", nonce + 1);
return (nonce, hash);
}
nonce += 1;
// 진행 상황 표시 (100만 번마다)
if nonce % 1_000_000 == 0 {
println!("{}백만 번 시도 중...", nonce / 1_000_000);
}
}
}
fn main() {
let block_data = "블록 #1: Alice→Bob 1ETH, Bob→Carol 0.5ETH";
for difficulty in [2, 3, 4, 5] {
println!("\n=== 난이도 {} ===", difficulty);
mine_block(block_data, difficulty);
}
}
실행 결과 예시:
=== 난이도 2 ===
채굴 완료!
nonce: 138
hash: 003a7f1c...
시간: 0.001초
시도 수: 139
=== 난이도 4 ===
채굴 완료!
nonce: 52,847
hash: 0000d3c1...
시간: 0.045초
시도 수: 52,848
=== 난이도 5 ===
채굴 완료!
nonce: 1,245,832
hash: 00000b7a...
시간: 1.073초
시도 수: 1,245,833
난이도가 1 증가할 때마다 평균 시도 횟수가 16배 증가한다 (16진수 한 자리 = 4비트).
2.5 PoW의 문제점
에너지 소비:
비트코인 네트워크 연간 전력 소비
≈ 아르헨티나 전체 전력 소비량 (약 130 TWh)
이는 모든 채굴자가 의도적으로 비효율적인
작업(nonce 탐색)에 자원을 낭비하기 때문
3. Proof of Stake (PoS) — 지분 증명
3.1 핵심 아이디어
“코인을 많이 담보로 맡긴 사람이 블록 생성 권한을 얻는다.”
계산 능력 대신 **경제적 담보(Stake)**를 사용한다.
PoW:
블록 생성권 = f(해시파워)
공격 비용 = 하드웨어 + 전기세
PoS:
블록 생성권 = f(스테이킹한 ETH 양)
공격 비용 = 코인 자체 (공격하면 내 코인 가치가 떨어짐)
3.2 이더리움 PoS 구성 요소
검증자 (Validator)
- 최소 32 ETH를 스테이킹(잠금)한 노드
- 블록 제안 및 투표 권한 획득
- 현재 이더리움에 약 900,000명 이상의 검증자
슬래싱 (Slashing)
- 악의적인 행동(이중 투표, 연속 오프라인 등)에 대한 처벌
- 스테이킹한 ETH의 일부 또는 전부가 소각됨
- 경제적 패널티가 정직한 행동을 유도
검증자의 보상과 처벌:
정직하게 행동 시:
+ 블록 제안 보상 (~0.1-0.2 ETH)
+ 증명(Attestation) 보상
+ MEV(최대 추출 가능 가치) 보상
악의적 행동 시:
- 슬래싱: 최소 1/32 스테이크 즉시 삭감
- 강제 퇴출 (검증자 자격 박탈)
- 최대 전체 스테이크 손실 가능
3.3 블록 생성 과정
1. 에포크(Epoch, 32슬롯 = ~6.4분) 시작 시
검증자들이 무작위로 위원회에 배정됨
2. 각 슬롯(12초)마다:
- RANDAO 알고리즘으로 무작위 블록 제안자 선택
- 제안자가 새 블록 생성 및 전파
3. 위원회 검증자들이 블록에 투표(Attestation)
4. 2/3 이상 투표 획득 시 블록 확정
5. 체크포인트(매 64슬롯)가 최종 확정(Finality) 됨
→ 이후 절대 변경 불가
3.4 The Merge — 이더리움의 PoW → PoS 전환
타임라인:
2015년 - 이더리움 메인넷 출시 (PoW)
2020년 - 비콘 체인(Beacon Chain) 출시 (PoS 테스트)
2022년 9월 15일 - The Merge 완료!
결과:
- 에너지 소비 99.95% 감소
- 발행량 ~90% 감소 (채굴 보상 없어짐)
- 블록 시간: 평균 13초 → 정확히 12초
4. Proof of History (PoH) — 역사 증명 (Solana)
4.1 문제: PoS의 시간 동기화 한계
분산 네트워크에서 “지금이 몇 시인가“는 합의가 필요한 문제다. 각 노드의 시계가 조금씩 다를 수 있기 때문이다. 이 때문에 PoS 시스템은 슬롯 시간을 길게 잡아야 했다.
4.2 PoH: 시간을 해시로 증명
Solana는 시간 자체를 블록체인에 기록한다.
PoH 순서:
hash_0 = SHA256("초기값")
hash_1 = SHA256(hash_0) ← 1회 반복
hash_2 = SHA256(hash_1) ← 2회 반복
hash_3 = SHA256(hash_2)
hash_4 = SHA256(hash_3)
hash_5 = SHA256(hash_4)
hash_N = SHA256(hash_{N-1}) ← N회 반복
각 hash_N이 "N번의 계산이 일어났다"는 증거가 됨
= 시간이 흘렀다는 증거
VDF (Verifiable Delay Function, 검증 가능한 지연 함수)
- 순차적으로만 계산 가능 (병렬화 불가)
- 계산은 오래 걸리지만, 검증은 빠름
- “이 해시를 만들려면 최소 X시간이 걸렸을 것“을 수학적으로 증명
4.3 PoH의 효과
기존 PoS:
각 블록마다 "이게 맞는 순서야?" 투표 → 느림
Solana PoH:
해시 체인 자체가 시간순서를 증명
→ 투표 없이도 순서가 명백함
→ 초당 65,000 트랜잭션 처리 가능 (이론값)
5. PBFT와 IBFT 2.0
5.1 PBFT (Practical Byzantine Fault Tolerance)
1999년에 제안된 고전적인 BFT 알고리즘.
PBFT 라운드:
1. Pre-prepare: 리더가 요청 브로드캐스트
2. Prepare: 각 노드가 "나도 봤어" 응답
3. Commit: 2f+1 응답 수집 후 "확정" 메시지
4. Reply: 클라이언트에게 결과 전달
f = 결함 허용 노드 수
총 노드 수 = 3f + 1 필요
예: f=1이면 최소 4개 노드 필요
특징:
- 최종성(Finality)이 즉각적: 블록이 한 번 확정되면 절대 변경 안 됨
- 노드 수가 많아지면 메시지가 O(n²)로 급증 → 확장성 한계
- 허가된(Permissioned) 네트워크에 적합
5.2 IBFT 2.0 (Istanbul Byzantine Fault Tolerance 2.0)
이 가이드의 실습 플랫폼인 Hyperledger Besu가 사용하는 합의 알고리즘이다.
PBFT를 블록체인에 맞게 개선한 버전:
IBFT 2.0 블록 생성 과정:
라운드 시작
│
▼
ProposerSelection: 라운드 로빈으로 제안자 선택
│
▼
Propose: 제안자가 블록 전파
│
▼
Prepare: 검증자들이 블록 검증 후 PREPARE 메시지 전송
│ (2f+1 PREPARE 수신 대기)
▼
Commit: COMMIT 메시지 전송
│ (2f+1 COMMIT 수신 시 블록 확정)
▼
블록 추가 완료 (즉각 최종성!)
│
└─ 만약 제한 시간 내 합의 실패 시:
라운드 변경 (Round Change) → 다음 제안자 선택
IBFT 2.0의 특징:
- 즉각적 최종성: 블록 확정 후 재조직(Reorg) 없음
- 에너지 효율적: PoW 불필요
- 허가형 네트워크: 검증자 집합이 알려져 있음
- 결함 허용: 전체 검증자의 1/3 미만이 악의적이어도 동작
- Besu 지원: Hyperledger Besu의 기본 엔터프라이즈 합의
Besu 네트워크 설정 예시 (genesis.json):
{
"config": {
"chainId": 1337,
"ibft2": {
"blockperiodseconds": 2, // 2초마다 블록
"epochlength": 30000, // 검증자 투표 주기
"requesttimeoutseconds": 4 // 타임아웃
}
}
}
6. 합의 알고리즘 비교
| 항목 | PoW | PoS | PoH (Solana) | IBFT 2.0 |
|---|---|---|---|---|
| 블록 시간 | ~10분 (BTC) | ~12초 (ETH) | ~400ms | ~2초 |
| 최종성 | 확률적 (6블록) | ~15분 | ~1초 | 즉각적 |
| 에너지 | 매우 높음 | 낮음 | 낮음 | 낮음 |
| 탈중앙화 | 높음 | 높음 | 중간 | 낮음 |
| 확장성 | 낮음 | 중간 | 높음 | 중간 |
| 결함 허용 | 51% 해시파워 | 33% 지분 | - | 33% 검증자 |
| 허가 필요 | 불필요 | 불필요 | 불필요 | 필요 |
| 주요 사용 | 비트코인 | 이더리움 | Solana | Besu 엔터프라이즈 |
| 공격 비용 | 하드웨어+전기 | 코인 자체 | - | 기관 신뢰 |
7. 핵심 정리
- 비잔틴 장군 문제: 악의적 참여자가 있는 분산 환경에서 합의를 달성하는 고전적 문제
- PoW: 계산 작업으로 권한 증명. 안전하지만 에너지 소비가 큼
- PoS: 경제적 담보로 권한 증명. 에너지 효율적이며 이더리움의 현재 방식
- PoH: 해시 체인으로 시간을 증명. Solana의 고속 처리를 가능하게 함
- IBFT 2.0: PBFT 기반의 즉각 최종성. 우리가 사용할 Besu의 합의 알고리즘
다음 파트(Chapter 10)에서는 이 모든 기초 위에 세워진 이더리움 플랫폼을 깊이 파고든다.