블록체인/레벨 IV · 프로토콜 심화/4.1 Script/수업 2
표준 스크립트: P2PKH 및 P2SH
코인을 키에, 나아가 임의의 스크립트 해시에 잠그기
준비물블록 탐색기 인터페이스(예: Blockstream.info 또는 mempool.space)SHA-256 및 RIPEMD-160 해싱 도구16진수 참조표원시 트랜잭션 16진수(hex)를 볼 수 있는 블록 탐색기
호기심
- 비트코인은 왜 키 자체가 아니라 해시에 코인을 잠글까요?
- 4줄짜리 스크립트는 단 한 번의 실행으로 소유권과 권한을 어떻게 모두 확인할 수 있나요?
- P2PKH가 이 네트워크의 8년이 넘는 역사 동안 기본 주소 형식으로 자리 잡게 된 이유는 무엇인가요?
탐구
- 제네시스 블록에는 Pay-to-Public-Key(P2PK) 형태의 아웃풋만 포함되어 있었습니다. 이 스크립트들은 전체 공개 키(2009년 기준, 65바이트 크기의 압축되지 않은 키)를 아웃풋에 직접 저장하여 코인이 사용되기 전부터 확인할 수 있게 했으며, 이로 인해 아웃풋의 크기가 커졌습니다. 원래 2009년 버전의 소프트웨어에도 존재했으며 일반 주소로의 지불에 사용되는 P2PKH 형식은 대신 20바이트 크기의 해시 값을 저장함으로써 코인이 사용될 때까지 키를 숨겨줍니다.
- 잠금 스크립트는 `OP_DUP OP_HASH160 <hash> OP_EQUALVERIFY OP_CHECKSIG`입니다. 실행은 스택에 있는 지출자의 데이터부터 시작되며, 먼저 서명이 있고 그 위에 공개 키가 있습니다. 엔진은 해당 키를 복제한 다음 RIPEMD-160(SHA256(key))을 사용해 해시 값을 계산하고, 이 결과를 저장된 해시 값과 비교합니다. 두 값이 일치하면 `OP_EQUALVERIFY`가 성공하지만, 그렇지 않으면 실행이 즉시 중단됩니다.
- 해시 검사가 성공하면 `OP_CHECKSIG`가 드러난 공개 키와 트랜잭션 데이터를 바탕으로 ECDSA 서명을 검증합니다. 이 이중 메커니즘 덕분에 해당 개인 키를 가진 사람만 자금을 해제할 수 있습니다. 출력 스크립트는 총 25바이트의 간결한 구조로, ‘1’로 시작하는 레거시 주소의 기반이 되었습니다.
- 비트코인 역사의 대부분 동안 일반 결제에 가장 많이 쓰인 출력 유형은 P2PKH였고, 2017년 8월 블록 481,824에서 SegWit이 활성화된 뒤에도 수년간 그 자리를 지켰습니다. 네이티브 SegWit의 채택이 점진적으로 이루어졌기 때문입니다. P2PKH의 성공 비결은 단순성과 호환성이었습니다. 원래의 프로토콜 규칙 외에 어떤 합의 업그레이드도 필요하지 않았습니다. 모든 노드가 복잡한 상태 추적 없이 이러한 스크립트를 독립적으로 검증할 수 있었기에, P2PKH는 비트코인 초기 성장기에 범용 송금에서 가장 견고한 출력 유형이 되었습니다.
- 주소 형식은 오타를 감지하기 위한 4바이트짜리 체크섬을 포함하는 Base58Check 인코딩을 사용합니다. 단 한 자만 잘못 입력되어도 거의 확실하게 체크섬 검증에 실패하여 지갑은 해당 주소를 거부합니다. 이러한 중복 구조 덕분에 기술적으로 복잡함에도 불구하고 P2PKH는 사용자 친화적이었으며, 암호학적 보안성과 인간의 사용 편의성 사이의 격차를 좁혀주었습니다.
- 블록 탐색기를 열고 ‘1’ 주소를 참조하는 입력이 있는 트랜잭션을 찾아보세요. `scriptSig` 필드를 살펴보면 서명 뒤에 공개 키의 16진수 문자열이 들어 있습니다. 이 공개 키를 참조된 출력의 `scriptPubKey`에 있는 20바이트 해시와 비교해 보세요. 그 키에 SHA-256을 적용한 뒤 RIPEMD-160을 적용하면 저장된 해시가 그대로 재현되어, 둘의 연결이 확인됩니다.
- 2012년 이전에는 5-of-5 멀티시그니처와 같은 복잡한 스크립트를 사용할 경우 전체 잠금 코드를 직접 아웃풋에 넣어야 했습니다. 이로 인해 아웃풋의 크기가 커졌으며, 보내는 측은 그에 따른 수수료를 지불해야 했습니다. 또한 모든 참여자의 공개 키와 구체적인 서명 요구 사항도 체인을 관찰하는 누구에게나 노출되었습니다. 보내는 측은 전송하기 전에 목적지의 정확한 구조를 알아야 했기 때문에, 유연한 보안 설정이 필요한 기업 재무팀이나 거래소들에게는 불편함을 초래했습니다.
- 이 문제를 해결하기 위해 개빈 안드레센은 2012년 초에 BIP16을 제안했습니다. 이 방식에서는 출력에 스크립트 자체가 아니라 그 스크립트의 HASH160 다이제스트만 담을 수 있었습니다. 출력 스크립트는 23바이트로 줄어 P2PKH의 25바이트보다 약간 작아졌습니다. 송신자는 더 이상 지출 조건을 알 필요 없이 해시에 지불하기만 하면 되었습니다. 복잡성은 전적으로 코인을 지출하는 사람에게로 넘어갔습니다.
- 2012년 4월 BIP16의 활성화는 논란이 많았습니다. 루크 대시주니어는 다른 옵코드와 인코딩 방식을 사용하는 대안인 BIP17을 제안했습니다. 어느 제안을 채택할지를 둘러싼 논쟁은 개발자 커뮤니티 안에서 크게 격화되었습니다. BIP16은 채굴자들이 지지 신호를 보낸 뒤 2012년 4월에 활성화되었고, 복잡한 스크립트를 감싸는 표준 방식이 되었습니다.
- Pay-to-Script-Hash 출력을 지출하는 과정은 두 단계로 이루어집니다. 먼저 지출자는 전체 리딤 스크립트를 스택에 푸시합니다. 노드는 그 스크립트의 HASH160이 출력에 있는 해시와 일치하는지 확인합니다. 일치하지 않으면 실행은 즉시 실패합니다. 일치하면 노드는 공개된 리딤 스크립트를 스택에 남은 데이터와 함께 실행하여 실제 지출 조건을 검증합니다.
- 이 설계에는 위험한 함정이 있습니다. 온체인에는 리딤 스크립트의 해시만 있으므로 결제 전에 누구도 그 스크립트를 확인할 수 없습니다. 수신자의 소프트웨어가 잘못된 스크립트를 만들었거나 스크립트를 분실하면, 그 주소로 보낸 코인은 영원히 지출할 수 없게 될 수 있습니다.
- 2017년 8월 SegWit이 활성화되었을 때 P2SH는 호환성을 위한 가교 역할을 했습니다. 사용자는 새로운 위트니스 스크립트를 P2SH라는 봉투 안에 감싸, 여전히 ‘3’으로 시작하는 ‘중첩(nested)’ 주소를 만들 수 있었습니다. 새로운 bech32 주소를 처리하지 못하는 구형 지갑도 SegWit 사용자에게 계속 송금할 수 있었고, SegWit을 지원하는 수신자는 지출할 때 수수료 할인을 받았습니다. 오늘날 효율성 면에서는 네이티브 SegWit이 선호되지만, P2SH는 복잡한 계약과 레거시 호환성을 위한 핵심 메커니즘으로 남아 있습니다.
파트 I페이-투-퍼블릭-키-해시(P2PKH)
파트 IIPay-to-Script-Hash(P2SH)
핵심 사실
- P2PKH 출력은 전체 공개키 대신 공개키의 20바이트짜리 HASH160을 저장합니다.
- 잠금 스크립트 `OP_DUP OP_HASH160 <hash> OP_EQUALVERIFY OP_CHECKSIG`는 정확히 25바이트 길이입니다.
- 지출하려면 유효한 ECDSA 서명과 저장된 해시와 일치하는 공개 키를 모두 제공해야 합니다.
- 레거시 P2PKH 주소는 ‘1’로 시작하며, 체크섬이 포함된 Base58Check 인코딩을 사용합니다.
- SegWit 이전과 이후를 막론하고 P2PKH는 수년간 일반 결제에서 지배적인 출력 유형이었습니다.
- `OP_EQUALVERIFY`가 해시된 키와 저장된 해시 간에 불일치를 감지하면 즉시 실행이 실패합니다.
- BIP16은 개빈 안드레센이 제안했으며 2012년 4월에 활성화되었습니다.
- P2SH 출력 스크립트는 리딤 스크립트의 HASH160만을 포함하며 길이는 23바이트입니다.
- 2012년 1월부터 3월까지 벌어진 치열한 논쟁 속에서 루크 대시주니어의 BIP17은 BIP16과 경쟁했습니다.
- 합의 규칙에 따라 리딤 스크립트는 520바이트로 제한되며, 이는 한 번에 푸시되는 단일 요소의 최대 크기입니다.
- P2SH 주소는 Base58Check 인코딩을 사용하며 항상 ‘3’이라는 숫자로 시작합니다.
- 네스티드 SegWit(보통 P2SH-P2WPKH) 덕분에 2017년 이후 구형 지갑도 SegWit 사용자에게 송금할 수 있었습니다.
연습 아홉, 여섯, 셋, 하나
9모으기비트코인 블록체인에서 P2PKH 주소의 자금을 지출하는 실제 트랜잭션 입력 9개를 찾으세요. 각 입력의 블록 높이, scriptSig에 드러난 공개 키, 그리고 출력에 있는 해당 해시를 기록하세요.
6묶기9개를 시기별로 6개 그룹으로 묶으세요: 2009-2011, 2012-2013, 2014-2015, 2016-2017, 2018-2021, 2022년 이후. 압축 키인지 비압축 키인지도 표시하세요.
3추리기이 그룹들을 2017년 이후 더 효율적인 출력 유형이 등장했는데도 P2PKH가 계속 우위를 지킨 서로 다른 이유 3가지로 줄이세요.
1결정화서명 검증이 이루어지기 전에 `OP_EQUALVERIFY`가 공개 키를 어떻게 구속력 있는 커밋먼트로 바꾸는지 한 문장으로 설명하세요.
팩트 체크
날짜, 수치 및 주장은 아래에 명시된 출처들을 통해 확인되었습니다.
- A. M. Antonopoulos & D. A. Harding, Mastering Bitcoin, 3rd ed. (2023), ch. 7
- Bitcoin Developer Guide, 'Transactions' documentation (bitcoin.org)
- Satoshi Nakamoto, original Bitcoin client source code (2009-2010 commits)
- Gavin Andresen, BIP16: Pay to Script Hash (2012)
- Luke Dashjr, BIP17: OP_CHECKHASHVERIFY (CHV) (2012)
- Bitcoin Developer Guide: Transactions and Scripts