3장 · 트랜잭션
주소가 생겼다. 개인키로 서명도 할 수 있다. 이제 "철수가 영희에게 1 ETH 보낸다"는 메시지를 네트워크에 뿌리면 끝일까? 막상 구현해보니 그렇지 않았다. 유효한 서명이 담긴 메시지를 복사해서 반복 전송하면, 노드는 이게 중복 요청인지 알 방법이 없어 여러 번 처리할 수 있다. 중간에 누군가 금액만 바꿔치기할 수 있다. 노드마다 메시지를 다르게 해석하면 합의가 깨진다.
❓ 이 챕터의 질문
🔍 비트코인(UTXO) vs 이더리움(계정 모델) 비교
비트코인은 "계좌 잔액"이라는 개념이 없어요. 이전 거래에서 받은 사용되지 않은 출력(UTXO, Unspent Transaction Output) 을 통째로 입력에 넣고, 새 출력으로 쪼개는 방식이에요. 현금에 비유하면, 이더리움이 통장 잔액에서 차감하는 방식이라면, 비트코인은 5만원권을 내고 거스름돈을 받는 방식이에요.
| 비트코인 (UTXO) | 이더리움 (계정 모델) | |
|---|---|---|
| 기본 단위 | 사용되지 않은 출력(UTXO)을 입력으로 소비 | 계좌 잔액에서 차감 |
| 재사용 방지 | 한 번 쓴 UTXO는 소멸 → 구조적으로 재사용 불가 | Nonce 카운터 |
| 수수료 | 입력 합 − 출력 합 | Gas 사용량 × 단가(Base Fee + 팁) |
| Data 필드 | 없음 (제한적인 스크립트만 지원) | 있음 → 4장 스마트 컨트랙트의 기반 |
| 직렬화 | 비트코인 고유 포맷 | RLP |
이 챕터가 제기하는 세 가지 문제(복사 공격, 바꿔치기, 파싱 불일치)는 어느 블록체인이든 풀어야 하는 보편적인 문제예요. 비트코인도 같은 문제를 풀었고, 푸는 방식이 다를 뿐이에요. 재사용은 UTXO 소멸로, 바꿔치기는 전체 서명으로, 파싱은 고유 직렬화 포맷으로요.
트랜잭션: 세 문제를 한 번에 해결하는 표준 묶음
블록체인은 이 세가지 문제를 트랜잭션이라는 표준 데이터 구조로 한 번에 해결했어요. 모든 필드를 하나의 바이트 덩어리로 포장해서 묶고, 그 전체에 서명을 씌우는 거예요.
각 데이터 앞에 "이 데이터는 몇 바이트짜리"라는 길이 정보(RLP, Recursive Length Prefix)를 붙이면 포장 방식을 표준화시킬 수 있어서, 어떤 노드든 동일하게 해석해요. 그리고 포장된 전체에 서명을 씌우기 때문에, 내용이 한 바이트라도 바뀌면 서명 검증이 즉시 실패해요.
| 필드 | 역할 | 막는 공격 |
|---|---|---|
| From / To / Value | 보내는 주소, 받는 주소, 금액 | RLP 인코딩으로 파싱 통일 |
| Nonce | 내 지갑의 N번째 요청 | 동일 Nonce 재사용 불가 → 복사 공격 차단 |
| Gas Limit / Max Fee | 실행 한도 + 낼 수수료의 상한 | 다음 섹션에서 설명 |
| Data | 스마트 컨트랙트 호출 데이터 | 단순 송금이면 비어 있음 |
| Signature (v, r, s) | 전체 필드에 개인키로 서명 | 한 글자라도 바뀌면 서명 실패 → 바꿔치기 차단 |
트랜잭션 처리 과정
서명된 트랜잭션이 네트워크에 들어오면 어떤 일이 벌어질까요?
1단계: 수집 블록 생성 노드가 네트워크에 떠돌아다니는 트랜잭션들을 Mempool(메모리 풀)에 수집해요. Mempool은 아직 블록에 포함되지 않은 트랜잭션들의 대기실이에요.
2단계: 수수료 정렬 검증자에게 주는 팁(Priority Fee)이 높은 순서로 처리 우선순위를 정해요. 빨리 처리받고 싶으면 팁을 더 내는 구조예요. (수수료가 어떻게 구성되는지는 5장에서 자세히 설명해요.)
3단계: 선언 트랜잭션을 실행하기 전에 Gas fee를 확인하고 송신 계정의 Gas를 확보해요.
4단계: 실행 트랜잭션 내용에 따라 자산을 이동하거나 스마트 컨트랙트를 실행해요. 이 과정에서 Gas를 소모해요.
5단계: 잔여 반환 실행 후 남은 Gas는 송신자에게 돌려줘요. Gas가 부족하면 실행이 취소(revert)되고 상태는 원래대로 돌아가요. 단, 소모된 Gas는 돌려주지 않아요.
6단계: 블록 추가 이상 없는 트랜잭션을 블록에 담아요. 1블록 안에 담을 수 있는 총 Gas 한도(Block Gas Limit)를 초과할 수 없어요.
그래서 왜 "블록체인"인가
방금 6단계에서 트랜잭션이 "블록"에 담겼어요. 1장부터 미뤄온 질문을 여기서 풀게요. 블록이 뭐고, 왜 이름이 블록체인일까요?
블록은 트랜잭션 묶음이에요. 일정 시간(이더리움은 약 12초)마다 그동안 모인 트랜잭션들을 한 묶음으로 포장한 게 블록 하나예요. 그리고 모든 블록의 머리에는 바로 앞 블록 전체를 해시한 값이 들어가요.
이 연결이 핵심이에요. 누군가 과거 블록의 내용을 한 글자라도 바꾸면 그 블록의 해시가 달라져요. 그러면 그 해시를 품고 있는 다음 블록과 안 맞고, 다음 블록을 고치면 그다음 블록과 안 맞고, 결국 그 뒤의 모든 블록을 다시 만들어야 해요. 블록이 쌓일수록 과거 조작은 기하급수적으로 어려워져요.
1장의 "장부"가 무엇을 기록하는지였다면, 블록체인이라는 이름은 어떻게 기록하는지예요. 트랜잭션을 블록으로 묶고, 블록을 해시로 사슬(chain)처럼 이어서 과거를 사실상 불변으로 만든 구조.
합의 프로토콜: 누가 다음 블록을 쓸 자격이 있는가
블록에 트랜잭션을 담을 자격을 어떻게 결정할까요? 아무나 블록을 만들 수 있다면 누가 만든 게 맞는 건지 알 수 없어요.
블록체인은 이 자격을 얻으려면 큰 비용을 치르도록 설계했어요. 공격해서 얻는 이득보다 공격 비용이 더 크면 아무도 공격하지 않거든요.
PoW (Proof of Work): 비트코인
해시 퍼즐 경쟁이에요. SHA-256 해시를 반복 계산해서 특정 조건을 만족하는 값을 가장 먼저 찾은 노드가 블록을 작성해요. 전기와 하드웨어가 비용이에요.
- 특징: 확률적 Finality, 최장 체인 규칙
- 단점: 에너지 소비가 막대하고, Finality까지 시간이 걸려요
PoS (Proof of Stake): 이더리움
ETH를 예치(Staking)하면 검증자 자격이 생기고, 무작위로 블록 제안자를 선출해요. 부정행위 시 예치금을 몰수(Slashing)해요. 예치금이 비용이에요.
- 특징: 2 Epoch(≈12.8분) 후 결정론적 Finality. 한번 확정된 블록은 사실상 뒤집을 수 없어요. 경제적 보안
- 개선: 에너지 소비를 PoW 대비 99.95% 절감
BFT (Byzantine Fault Tolerance): Hyperledger Besu
허가된 노드(Validator)들만 참여해요. Pre-Prepare → Prepare → Commit 3단계 투표로 2/3 이상 동의해야 블록이 확정돼요.
- 특징: 결정론적 즉시 Finality (1~4초), Fork 불가
- 적합: 금융 인프라, 컨소시엄 블록체인
🛠 시스템을 운영해봤다면: 익숙한 개념과의 대응표
분산 시스템을 다뤄본 개발자라면 이 챕터의 개념들이 낯설지 않을 거예요. 비슷한 점과 결정적 차이를 정리하면:
| 블록체인 | 비슷한 것 | 결정적 차이 |
|---|---|---|
| 노드 | DB 레플리카 (전 노드가 같은 데이터) | 마스터가 없고, 서로를 신뢰하지 않음 |
| Mempool | 메시지 큐의 대기열 | 전 세계가 공유하는 하나의 큐, 수수료 순 처리 |
| 합의 (PoW/PoS/BFT) | Raft·Paxos 같은 분산 합의 | 참여자가 악의적일 수 있다는 가정(비잔틴 장애)에서 출발 |
| Block Finality | DB 트랜잭션의 커밋 | 한번 확정되면 롤백이라는 개념 자체가 없음 |
| 스마트 컨트랙트 (4장) | 저장 프로시저(Stored Procedure) | 배포 후 누구도(만든 사람도) 수정할 수 없음 |
요약하면, 블록체인은 "참여자를 믿을 수 없는 환경에서 돌아가는 분산 DB"예요. 기존 분산 시스템이 장애(crash)를 견디도록 설계됐다면, 블록체인은 거짓말(byzantine fault)을 견디도록 설계됐어요.
그런데 새로운 문제가 생겼어요
트랜잭션으로 숫자를 옮기는 건 해결했어요. 그런데 비트코인을 쓰면서 사람들이 깨달았어요. 블록체인이 결국 "장부에 숫자 옮기기"밖에 안 된다는 걸요.
에스크로, 대출, 보험 등 현실의 금융 계약은 거의 다 조건부예요. "집 등기가 넘어오면 대금을 지급", "담보 가치가 기준 이하로 떨어지면 자동 청산". 이걸 지금은 전부 사람이 중간에서 판단하고 실행해요. 은행, 변호사, 공증인이 그 역할을 하고요.
❓ 다음 챕터의 질문
→ 4장에서 이 문제를 어떻게 해결했는지 알아볼게요.
핵심 요약
| 개념 | 역할 |
|---|---|
| Nonce | 재사용 방지. 복사 공격 차단 |
| Signature | 전체 필드 서명. 바꿔치기 차단 |
| RLP | 표준 직렬화. 파싱 불일치 차단 |
| Mempool | 블록 포함 전 트랜잭션 대기실 |
| 블록 | 트랜잭션 묶음 + 이전 블록 해시. 해시 연결로 과거 불변 |
| Gas | 처리 수수료 + 실행 한도 |
| Block Finality | 블록 확정 = 결제 완결성 |
| PoW | 해시 퍼즐 경쟁. 확률적 Finality |
| PoS | ETH 예치 + Slashing. ≈12.8분 후 결정론적 Finality |
| BFT | 허가 노드 투표. 결정론적 즉시 Finality |
📚 참고자료 보기
- 이더리움 공식 문서: Transactions: 트랜잭션 구조 상세
- 이더리움 공식 문서: Gas and Fees: Gas 메커니즘
- Bitcoin Whitepaper: PoW 합의 원문
- 이더리움 공식 문서: Consensus Mechanisms: PoW/PoS/BFT 비교
- BIS: Payment Finality: 결제 완결성 공식 정의
- Hyperledger Besu: QBFT: BFT 합의 상세