sayu.day

비트코인 트랜잭션 해부: 주소, HD 지갑, Script, SegWit, 그리고 BRC-20

비트코인 트랜잭션 하나에는 키 관리, 주소 인코딩, 스크립트 검증, 서명 구조가 모두 압축되어 있습니다. 각 계층을 따로 보면 단편적인 지식에 그치지만, 키에서 자산 실험까지 이어지는 하나의 흐름으로 보면 설계 의도가 분명해집니다. 이 글은 HD 지갑의 키 파생에서 출발해 주소 형식, Script 실행 모델, SegWit, SPV 경량 검증, 그리고 Ordinals/BRC-20까지 순서대로 짚어갑니다.

HD 지갑: 하나의 시드에서 모든 키가 나옵니다

HD(Hierarchical Deterministic) 지갑은 하나의 시드에서 수많은 키를 계층적으로 파생합니다. 현대 지갑의 기본 구조이며, 시드 하나만 안전하게 보관하면 전체 키를 복구할 수 있어 백업과 복구가 단순해집니다.

세 가지 표준이 축을 이룹니다.

  • BIP-39: 12~24개 단어의 니모닉으로 시드를 표현합니다.
  • BIP-32: 시드에서 마스터 키, 마스터 키에서 자식 키를 결정론적으로 파생합니다. 일반 파생은 xpub(확장 공개키) 기반으로 가능하지만, 강화 파생(hardened)에는 부모 개인키가 필요합니다.
  • BIP-44: 다중 코인과 계정을 위한 경로 규약을 정의합니다.
m / purpose' / coin_type' / account' / change / address_index

대표적인 파생 경로는 다음과 같습니다.

  • BTC: m/44'/0'/0'/0/0
  • ETH: m/44'/60'/0'/0/0
  • Aptos: m/44'/637'/0'/0'/0' (지갑 구현별 변형 존재)

운영에서는 다음 네 가지가 중요합니다.

  1. 니모닉은 오프라인에서 생성하고 보관합니다.
  2. purpose, coin_type, account 구간은 hardened 파생을 유지합니다.
  3. 지갑별 경로 차이를 문서화하지 않으면 복구 사고로 이어집니다.
  4. xpub 노출 범위를 최소화합니다. 일반 파생 주소는 xpub만으로 계산할 수 있기 때문입니다.

자주 보이는 실수는 니모닉을 클라우드 메모나 스크린샷으로 보관하는 것, 경로 규약을 정하지 않은 채 멀티체인으로 확장하는 것, 테스트넷과 메인넷 경로를 혼용하는 것입니다. HD 지갑의 핵심 가치는 키 생성이 아니라 복구 가능성과 운영 일관성입니다. 팀 단위 서비스라면 경로, 백업 절차, 키 권한 경계를 문서로 고정해 두어야 합니다.

주소: 접두사로 구분되는 네 가지 형식

파생된 키는 주소로 인코딩되어 수신에 사용됩니다. 비트코인 주소는 26~35자의 영숫자 식별자이며, 형식마다 고유한 접두사가 있어 어떤 사양을 따르는지 바로 구분할 수 있습니다.

형식 접두사 대소문자 특징
P2PKH (Legacy) 1 구분함 최초의 주소 형식, 상대적으로 높은 수수료
P2SH (Script) 3 구분함 스크립트 해시, 멀티시그에 주로 사용
P2WPKH (Native SegWit) bc1q 구분 안 함 오류 수정 코드, 수수료 절감
P2TR (Taproot) bc1p 구분 안 함 슈노르 서명, 프라이버시·유연성 향상

**P2PKH(Legacy)**는 가장 오래된 원형입니다. 트랜잭션 비용이 높아 지금은 널리 쓰이지 않지만, 새 주소 체계를 적용하지 않은 레거시 애플리케이션이 남아 있어 호환성 유지가 권장됩니다. 예: 1BvBMSEYstWetqTFn5Au4m4GFg7xJaNVN2

**P2SH(Script)**는 주소에 추가 규칙과 기능을 붙일 수 있는 형식입니다. 트랜잭션 승인에 여러 키의 서명을 요구하는 다중 서명 주소에 흔히 사용됩니다. 예: 3J98t1WpEZ73CNmQviecrnyiWrnqRhWNLy

**P2WPKH(Native SegWit)**는 Bech32 인코딩을 사용하는 현대적인 형식입니다. 대소문자를 구분하지 않고 오류 수정 코드를 사용해 입력 실수에 강하며, 일반적인 자금 이체 기준으로 수수료를 30~40% 절감할 수 있습니다. 옵트인 방식이지만 오늘날 대부분의 애플리케이션이 지원합니다. 예: bc1qar0srrr7xfkvy5l643lydnw9re59gtzzwf5mdq

**P2TR(Taproot)**은 Bech32m 인코딩을 사용하는 가장 최신 형식입니다. 슈노르 서명(Schnorr Signature)을 사용할 수 있고, 다중 키 주소가 단일 키 주소와 동일하게 보여 프라이버시가 향상되며, 더 고급 스크립팅으로 복잡한 계약 구성이 가능합니다. 다만 아직 지원 폭이 넓지 않습니다. 예: bc1pmzfrwwndsqmk5yh69yjr5lfgfg4ev8c0tsc06e

호환성 관점에서는 방향이 중요합니다. 오래된 송신 측 애플리케이션은 SegWit 주소를 유효한 주소로 인식하지 못할 수 있습니다. 그래서 수신자는 기본적으로 SegWit 주소를 쓰더라도, 상대방의 호환성을 맞춰 주기 위해 P2SH 같은 다른 형식으로 전환해 줄 수 있어야 합니다.

Script: 잠금과 해제의 실행 모델

주소 뒤에는 스크립트가 있습니다. Bitcoin Script는 스택 기반의 비튜링완전 언어로, 표현력보다 검증 단순성과 예측 가능성을 우선합니다.

한 입력의 소비는 보통 두 스크립트의 조합으로 검증됩니다.

  • scriptSig 또는 witness: 해제 데이터를 제공합니다.
  • scriptPubKey: 잠금 조건을 정의합니다.

두 스크립트를 평가한 결과가 true이면 해당 UTXO의 소비가 허용됩니다.

대표 패턴은 네 가지입니다.

  1. P2PKH: 가장 기본적인 서명 검증입니다. 공개키 해시 일치와 서명 유효성을 확인합니다.
  2. P2WPKH(SegWit): 서명 데이터를 witness로 분리해 가변성 문제를 줄이고 효율을 개선합니다.
  3. P2SH: 복잡한 redeem script를 해시로 감춰 주소 표현을 단순화합니다. 멀티시그 정책 배포에 자주 쓰였습니다.
  4. Timelock(OP_CHECKLOCKTIMEVERIFY): 특정 시간 또는 블록 높이 이전에는 소비를 막는 정책을 구현합니다.

스크립트를 설계할 때는 다음을 점검합니다.

  1. 조건 실패 시나리오를 우선 설계합니다.
  2. 지갑과 노드의 SegWit/Taproot 호환성을 먼저 확인합니다.
  3. 멀티시그와 타임락은 키 분실 시 복구 경로까지 포함해 설계합니다.
  4. 주소 형태(P2WPKH, P2SH 등)와 수수료 영향을 함께 검토합니다.

SegWit: witness를 분리한 이유

원래 비트코인 프로토콜에서는 디지털 서명(witness 데이터)이 트랜잭션 입력 안에 포함되었습니다. 서명이 입력에 실리면 트랜잭션이 커져 네트워크 처리량이 줄고, 서명 데이터의 인코딩 변화가 트랜잭션 식별자에 영향을 주는 가변성(malleability) 문제도 있었습니다. 2017년 도입된 SegWit(Segregated Witness)은 이름 그대로 witness 데이터를 입력에서 분리해, 트랜잭션의 별도 섹션에 배치하는 새로운 트랜잭션 형식입니다.

SegWit 트랜잭션의 script_pubkey에는 자금 사용 조건을 지정하는 witness program이 들어가며, 이것이 SegWit 주소를 만드는 데 사용됩니다. SegWit 주소로 받은 자금을 쓸 때는 소유권을 증명하는 witness를 트랜잭션에 포함합니다.

트랜잭션 생성과 서명 흐름을 의사코드 수준으로 요약하면 다음과 같습니다.

1. 입력(TxIn) 구성: 소비할 UTXO의 outpoint 지정, scriptSig는 비워 둠
2. 출력(TxOut) 구성: 금액(satoshi)과 잠금 스크립트(script_pubkey) 지정
3. 서명 해시 계산: BIP-143 방식으로 입력별 서명 대상 다이제스트 생성
4. 개인키로 서명 생성
5. witness 스택에 [서명, 공개키]를 순서대로 push
6. 완성된 트랜잭션을 직렬화해 브로드캐스트

레거시 트랜잭션과의 결정적 차이는 서명이 scriptSig가 아니라 witness 영역에 들어간다는 점입니다. 검증 데이터가 트랜잭션 본체와 분리되므로 블록 공간을 더 효율적으로 쓸 수 있고, 서명 인코딩 변화가 트랜잭션 본체를 흔드는 문제를 구조적으로 완화합니다.

SPV: 머클 증명으로 가볍게 검증하기

모든 참여자가 전체 체인을 저장할 수는 없습니다. SPV(Simplified Payment Verification)는 블록체인 전체를 저장하지 않고도 트랜잭션을 검증하는 방법이며, 이를 사용하는 노드를 라이트 노드 또는 경량 노드라고 부릅니다.

경량 검증이 가능한 이유는 블록 헤더만 받아도 되기 때문입니다. 블록 헤더는 총 80바이트로 구성됩니다.

  • 버전: 4바이트
  • 이전 블록 해시: 32바이트
  • 머클루트 해시: 32바이트
  • 블록 시간: 4바이트
  • 비츠: 4바이트
  • 논스: 4바이트

1년 동안 생성되는 약 52,560개의 블록 헤더가 4MB 정도이므로, 150GB를 넘긴 풀 노드 데이터에 비하면 매우 가볍습니다.

검증 원리는 머클 증명입니다. 블록의 모든 트랜잭션은 머클 트리로 요약되고, 루트 해시만 헤더에 기록됩니다. 특정 거래가 블록에 실렸는지 확인하려면 그 거래의 해시에서 머클루트까지 올라가는 경로에 필요한 형제 해시들만 받아 루트를 재계산한 뒤, 헤더의 머클루트와 일치하는지 대조하면 됩니다. 예를 들어 거래 3의 포함 여부를 확인하고 싶다면 블록 전체가 아니라 머클루트 재계산에 필요한 해시 몇 개만 가져오면 충분합니다.

한계도 분명합니다. SPV 노드는 체인 사본을 보관하지 않고 트랜잭션 검증 과정에도 참여하지 않으므로 네트워크 보안에 기여하지 않으며, 결국 다른 풀 노드의 정보에 의존해 거래를 진행합니다.

Ordinals와 BRC-20: 데이터 계층의 자산 실험

Ordinals 이후 비트코인에서도 NFT 유사 자산과 FT 실험(BRC-20)이 가능해졌습니다. 다만 이 구조는 "비트코인 L1에 애플리케이션 메타데이터를 어떻게 싣는가"의 문제이지, EVM 토큰 표준과 동일한 모델이 아닙니다.

Ordinals의 핵심은 세 가지입니다.

  • 사토시에 순번(ordinal)을 부여합니다.
  • inscription으로 데이터를 특정 사토시와 연결합니다.
  • 그 결과 NFT와 유사한 식별과 추적이 가능해집니다.

별도의 사이드체인 토큰 없이, 지금까지 살펴본 비트코인 트랜잭션의 데이터 계층을 그대로 활용한다는 점이 중요합니다.

BRC-20은 inscription 기반의 실험 규약입니다.

  • 배포/민트/전송 상태를 JSON inscription 관례로 표현합니다.
  • 상태 전이는 인덱서가 해석해 계산합니다.
  • 체인 자체가 ERC-20처럼 상태 머신을 강제하는 구조가 아닙니다.

즉 인덱싱 규칙에 대한 합의에 강하게 의존합니다. 비트코인 생태계의 실험 폭 확대, 새로운 수수료 수요 창출, 인덱서·지갑·마켓 등 애플리케이션 레이어의 성장이라는 순기능이 있는 반면, 네트워크 혼잡과 수수료 급등, 표준 해석 불일치 시 상태 분기 가능성, 투기 수요에 과도하게 종속될 위험도 함께 갑니다. 사용자 자산 UX를 제공하려면 인덱싱 규칙의 명확성과 호환성 관리가 핵심입니다.

정리

  • HD 지갑(BIP-32/39/44)의 가치는 키 생성이 아니라 복구 가능성과 운영 일관성입니다. 파생 경로, 백업 절차, 키 권한 경계를 문서로 고정합니다.
  • 주소는 접두사 1(P2PKH), 3(P2SH), bc1q(P2WPKH), bc1p(P2TR)로 구분되며, 수신자는 송신 측 호환성을 위해 형식을 전환할 수 있어야 합니다.
  • Script는 검증 단순성을 우선한 스택 기반 비튜링완전 언어이며, 조건 실패 시나리오를 먼저 설계해야 합니다.
  • SegWit은 witness를 트랜잭션 본체에서 분리해 가변성 문제를 완화하고 공간 효율을 높였습니다.
  • SPV는 80바이트 블록 헤더와 머클 증명만으로 포함 여부를 검증하지만, 풀 노드 의존이라는 한계가 있습니다.
  • Ordinals/BRC-20은 프로토콜이 강제하는 표준이 아니라 인덱서 관례입니다. 인덱싱 규칙의 명확성과 호환성 관리가 서비스 품질을 좌우합니다.