📦챕터 3

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)전체 필드에 개인키로 서명한 글자라도 바뀌면 서명 실패 → 바꿔치기 차단
Signature (v, r, s): 전체 필드에 서명트랜잭션: RLP 인코딩From / To보내는 주소 · 받는 주소Value보낼 금액Nonce내 지갑의 N번째 요청Gas Limit / Max Fee실행 한도 · 수수료 상한Data컨트랙트 호출 데이터RLP: 파싱 통일어떤 노드든 동일하게 해석재사용 불가복사해서 100번 뿌려도 1번만 처리단순 송금이면 비어 있음4장에서 이 자리가 주인공이 된다바꿔치기 차단1바이트만 바뀌어도 검증 실패
트랜잭션: RLP로 포장을 표준화하고, 전체에 서명을 씌워 세 가지 공격을 한 번에 막는다

트랜잭션 처리 과정

서명된 트랜잭션이 네트워크에 들어오면 어떤 일이 벌어질까요?

1단계: 수집 블록 생성 노드가 네트워크에 떠돌아다니는 트랜잭션들을 Mempool(메모리 풀)에 수집해요. Mempool은 아직 블록에 포함되지 않은 트랜잭션들의 대기실이에요.

2단계: 수수료 정렬 검증자에게 주는 팁(Priority Fee)이 높은 순서로 처리 우선순위를 정해요. 빨리 처리받고 싶으면 팁을 더 내는 구조예요. (수수료가 어떻게 구성되는지는 5장에서 자세히 설명해요.)

3단계: 선언 트랜잭션을 실행하기 전에 Gas fee를 확인하고 송신 계정의 Gas를 확보해요.

4단계: 실행 트랜잭션 내용에 따라 자산을 이동하거나 스마트 컨트랙트를 실행해요. 이 과정에서 Gas를 소모해요.

5단계: 잔여 반환 실행 후 남은 Gas는 송신자에게 돌려줘요. Gas가 부족하면 실행이 취소(revert)되고 상태는 원래대로 돌아가요. 단, 소모된 Gas는 돌려주지 않아요.

6단계: 블록 추가 이상 없는 트랜잭션을 블록에 담아요. 1블록 안에 담을 수 있는 총 Gas 한도(Block Gas Limit)를 초과할 수 없어요.

① 수집Mempool 대기실에 모음② 수수료 정렬팁(Priority Fee) 높은 순③ 선언송신 계정의 Gas 확보④ 실행자산 이동 · 컨트랙트 실행⑤ 잔여 반환남은 Gas 돌려줌⑥ 블록 추가Block Gas Limit 이내Gas 부족 → revert (상태 원복, 소모된 Gas는 미반환)블록 확정 = 결제 완결성(Finality)
서명된 트랜잭션이 블록에 담기기까지: 6단계 처리 과정

그래서 왜 "블록체인"인가

방금 6단계에서 트랜잭션이 "블록"에 담겼어요. 1장부터 미뤄온 질문을 여기서 풀게요. 블록이 뭐고, 왜 이름이 블록체인일까요?

블록은 트랜잭션 묶음이에요. 일정 시간(이더리움은 약 12초)마다 그동안 모인 트랜잭션들을 한 묶음으로 포장한 게 블록 하나예요. 그리고 모든 블록의 머리에는 바로 앞 블록 전체를 해시한 값이 들어가요.

이 연결이 핵심이에요. 누군가 과거 블록의 내용을 한 글자라도 바꾸면 그 블록의 해시가 달라져요. 그러면 그 해시를 품고 있는 다음 블록과 안 맞고, 다음 블록을 고치면 그다음 블록과 안 맞고, 결국 그 뒤의 모든 블록을 다시 만들어야 해요. 블록이 쌓일수록 과거 조작은 기하급수적으로 어려워져요.

1장의 "장부"가 무엇을 기록하는지였다면, 블록체인이라는 이름은 어떻게 기록하는지예요. 트랜잭션을 블록으로 묶고, 블록을 해시로 사슬(chain)처럼 이어서 과거를 사실상 불변으로 만든 구조.

약 12초마다 트랜잭션 묶음이 블록 하나로, 그리고 해시로 연결제네시스블록까지블록 N−1트랜잭션 묶음이전 블록의 해시블록 N트랜잭션 묶음이전 블록의 해시블록 N+1트랜잭션 묶음이전 블록의 해시✗ 이 블록을 조작하면?해시가 달라져 다음 블록과 안 맞는다 → 그 뒤 블록 전부를 다시 만들어야 한다블록이 쌓일수록 과거 조작은 사실상 불가능. 그래서 이름이 블록“체인”
모든 블록은 이전 블록의 해시를 품고 있다. 과거를 바꾸면 그 뒤 전부가 어긋난다

합의 프로토콜: 누가 다음 블록을 쓸 자격이 있는가

블록에 트랜잭션을 담을 자격을 어떻게 결정할까요? 아무나 블록을 만들 수 있다면 누가 만든 게 맞는 건지 알 수 없어요.

블록체인은 이 자격을 얻으려면 큰 비용을 치르도록 설계했어요. 공격해서 얻는 이득보다 공격 비용이 더 크면 아무도 공격하지 않거든요.

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 불가
  • 적합: 금융 인프라, 컨소시엄 블록체인
⛏️ PoW비트코인참여 자격누구나치르는 비용전기 · 하드웨어선출 방식해시 퍼즐 경쟁Finality확률적 (~6블록, 1시간)🪙 PoS이더리움참여 자격ETH 예치자치르는 비용예치금 (부정 시 몰수)선출 방식무작위 제안자 선출Finality결정론적 (≈12.8분 후 확정)🗳️ BFTHyperledger Besu참여 자격허가된 노드만치르는 비용허가 · 신원 공개선출 방식3단계 투표 (2/3 동의)Finality즉시 확정 (1~4초)공통 설계: 공격 비용 > 공격 이득
세 방식 모두 원리는 하나. 블록을 쓸 자격에 비용을 매겨, 공격 비용이 이득보다 크게 만든다
🛠 시스템을 운영해봤다면: 익숙한 개념과의 대응표

분산 시스템을 다뤄본 개발자라면 이 챕터의 개념들이 낯설지 않을 거예요. 비슷한 점과 결정적 차이를 정리하면:

블록체인비슷한 것결정적 차이
노드DB 레플리카 (전 노드가 같은 데이터)마스터가 없고, 서로를 신뢰하지 않음
Mempool메시지 큐의 대기열전 세계가 공유하는 하나의 큐, 수수료 순 처리
합의 (PoW/PoS/BFT)Raft·Paxos 같은 분산 합의참여자가 악의적일 수 있다는 가정(비잔틴 장애)에서 출발
Block FinalityDB 트랜잭션의 커밋한번 확정되면 롤백이라는 개념 자체가 없음
스마트 컨트랙트 (4장)저장 프로시저(Stored Procedure)배포 후 누구도(만든 사람도) 수정할 수 없음

요약하면, 블록체인은 "참여자를 믿을 수 없는 환경에서 돌아가는 분산 DB"예요. 기존 분산 시스템이 장애(crash)를 견디도록 설계됐다면, 블록체인은 거짓말(byzantine fault)을 견디도록 설계됐어요.

그런데 새로운 문제가 생겼어요

트랜잭션으로 숫자를 옮기는 건 해결했어요. 그런데 비트코인을 쓰면서 사람들이 깨달았어요. 블록체인이 결국 "장부에 숫자 옮기기"밖에 안 된다는 걸요.

에스크로, 대출, 보험 등 현실의 금융 계약은 거의 다 조건부예요. "집 등기가 넘어오면 대금을 지급", "담보 가치가 기준 이하로 떨어지면 자동 청산". 이걸 지금은 전부 사람이 중간에서 판단하고 실행해요. 은행, 변호사, 공증인이 그 역할을 하고요.

다음 챕터의 질문

조건부 계약을 은행도, 변호사도, 공증인도 없이 자동으로 실행할 수는 없을까?

4장에서 이 문제를 어떻게 해결했는지 알아볼게요.

핵심 요약

개념역할
Nonce재사용 방지. 복사 공격 차단
Signature전체 필드 서명. 바꿔치기 차단
RLP표준 직렬화. 파싱 불일치 차단
Mempool블록 포함 전 트랜잭션 대기실
블록트랜잭션 묶음 + 이전 블록 해시. 해시 연결로 과거 불변
Gas처리 수수료 + 실행 한도
Block Finality블록 확정 = 결제 완결성
PoW해시 퍼즐 경쟁. 확률적 Finality
PoSETH 예치 + Slashing. ≈12.8분 후 결정론적 Finality
BFT허가 노드 투표. 결정론적 즉시 Finality
📚 참고자료 보기