티스토리 뷰
본 게시글에서는 저서 '밑바닥부터 시작하는 비트코인'의 Python으로 작성된 예제 코드를 Go로 컨버팅 하여 작성하였습니다.
📺시리즈
2023.08.25 - [블록체인/Bitcoin] - 밑바닥부터 시작하는 비트코인 - 1장 유한체
2023.08.27 - [블록체인/Bitcoin] - 밑바닥부터 시작하는 비트코인 - 2장 타원곡선
2023.08.30 - [블록체인/Bitcoin] - 밑바닥부터 시작하는 비트코인 - 3장 타원곡선 암호
2023.09.02 - [블록체인/Bitcoin] - 밑바닥부터 시작하는 비트코인 - 4장 직렬화
2023.09.05 - [블록체인/Bitcoin] - 밑바닥부터 시작하는 비트코인 - 5장 트랜잭션
2023.09.11 - [블록체인/Bitcoin] - 밑바닥부터 시작하는 비트코인 - 6장 스크립트
2023.09.16 - [블록체인/Bitcoin] - 밑바닥부터 시작하는 비트코인 - 7장 트랜잭션 검증과 생성
2023.09.20 - [블록체인/Bitcoin] - 밑바닥부터 시작하는 비트코인 - 8장 p2sh 스크립트
2023.09.21 - [블록체인/Bitcoin] - 밑바닥부터 시작하는 비트코인 - 9장 블록
2024.01.08 - [블록체인/Bitcoin] - 밑바닥부터 시작하는 비트코인 - 10장 네트워킹
2024.01.09 - [블록체인/Bitcoin] - 밑바닥부터 시작하는 비트코인 - 11장 단순 지급 검증
2024.01.10 - [블록체인/Bitcoin] - 밑바닥부터 시작하는 비트코인 - 12장 블룸 필터
🐲 전체 코드
🥅 학습 목표
1. 세그윗이 도입된 배경과 불러온 변화를 살펴봅니다.
2. p2wpkh 스크립트와 p2sh-p2wpkh 스크립트에 대해 알아봅니다.
🈹 1. 세그윗
세그윗(segregated witness)은 비트코인 네트워크에서 2017년 8월부터 활성화된 소프트포크(하위호환성을 보장하는 업그레이드)입니다.
1.1 도입 배경: 트랜잭션 가변성
비트코인의 모든 트랜잭션은 고유한 ID를 가지고 있습니다. 트랜잭션 가변성(Transaction Malleability)은 트랜잭션의 ID가 변할 수 있다는 것을 의미합니다.
트랜잭션의 대부분 필드는 변경되면 트랜잭션이 더 이상 유효하지 않게 되기 때문에 트랜잭션 가변성에 영향을 줄 수 없지만, 해제 스크립트는 변경이 가능합니다. 우선 트랜잭션의 검증은 서명해시를 구하는 과정에서 해제 스크립트를 제거하기 때문에 해제 스크립트의 영향을 받지 않습니다. 그리고 명령어나 원소를 추가하고 변경하여 유효한 해제 스크립트를 만들 수 있으므로 서명은 유일하지 않습니다. 예를 들어, OP_PUSHDATA2를 사용할 필요가 없는 데이터 크기임에도 임의로 길이를 늘여 해제 스크립트를 변경할 수 있습니다. 즉, 값이 다르지만 유효한 해제 스크립트를 생성할 수 있고, 동일한 거래내역에 대한 완전히 다른 트랜잭션 ID를 만들어 낼 수 있습니다.
일단 트랜잭션이 블록체인에 올라가게 되면 트랜잭션 ID가 변할 수 없기 때문에 문제가 되지 않지만, 블록체인에 올라가기 전의 트랜잭션을 참조하는 트랜잭션이 있는 결제 채널(payment channel) 등에서는 참조되는 트랜잭션이 블록체인에 올라가지 않고 대신 다른 ID를 가진 동일한 거래내역의 트랜잭션이 올라가는 혼란을 야기할 수 있습니다.
1.2 도입 배경: 속도와 확장성
비트코인을 실생활에서 결제 및 송금 시스템으로 사용하고자 하는 시도들이 꾸준히 존재해 왔지만, 다음과 같은 이유로 좌절되었습니다.
비트코인 네트워크에서 트랜잭션이 블록에 담겨서 마이닝이 될 때까지 최소 10분 이상이 필요하며, 블록체인의 완결성이 보장되려면 6개의 블록(60분 이상)이 뒤이어 블록체인에 추가되어야 합니다. 60분 이상이라는 소요 시간은 여타 중앙화된 결제 및 송금 시스템이 당연하다는 듯이 찰나의 시간으로 사용자에게 서비스를 제공하는 것과 비교하면 도저히 사용할 수 없는 수준입니다. (속도의 문제)
비트코인은 블록의 크기가 최대 1MB이기 때문에 블록에 담을 수 있는 트랜잭션의 수가 제한적입니다. 게다가 이마저도 블록을 구성하는 데이터의 75%가량이 디지털 서명 데이터이기 때문에 초당 트랜잭션 처리량(TPS)은 7 밖에 되지 않았습니다. 제한된 블록 용량은 시간이 지날수록 늘어나는 네트워크 사용량을 감당하기에도 어려움이 있었습니다. 네트워크에 트랜잭션은 계속해서 쌓이는데 적은 트랜잭션 비용으로 마이너들의 선택을 받지 못하는 트랜잭션은 언제쯤 처리될 수 있을지 알 수가 없었습니다. (확장성의 문제)
1.2 세그윗 업그레이드
세그윗은 디지털 서명 데이터를 블록으로부터 분리하여 트랜잭션 가변성 문제를 해결하고 블록의 가용 용량을 늘림으로써 속도와 확장성을 개선하는 소프트포크입니다. 구국의 결단을 내린 비트코인 코어 그룹은 세그윗 업데이트에 대한 찬반투표를 진행했고, 과반수의 찬성표를 얻어 2017년 8월 업데이트를 진행합니다.
개괄적으로 세그윗이 불러온 변화는 다음과 같습니다.
- 블록의 가용 용량 증가
- 트랜잭션 가변성 문제 해결
- 체계적인 업그레이드가 가능한 세그윗 버전 식별 방식
- 이차 해싱 문제 해결
- 오프라인 지갑 수수료 계산의 보안 강화
1.3 세그윗 트랜잭션
세그윗 노드가 세그윗 노드에 보내는 트랜잭션의 형식은 다음과 같습니다. 세그윗 노드가 이전 노드에 보내는 트랜잭션에는 세그윗 마커, 세그윗 플래그 그리고 증인이 포함되어 있지 않습니다. 트랜잭션 ID는 세그윗 관련 필드를 포함하지 않고 직렬화된 트랜잭션을 사용하므로 트랜잭션 ID는 세그윗 노드와 이전 노드 모두 동일합니다.
버전 |
세그윗 마커 |
세그윗 플래그 |
입력의 개수, (이전 트랜잭션 해시, 출력 인덱스) |
해제 스크립트 |
시퀀스 |
출력의 개수, (코인의 수량, 잠금 스크립트) |
증인(witness) |
록타임 |
📜 2. p2wpkh 스크립트
p2wpkh (Pay-to-witness-pubkey-hash) 스크립트는 BIP0141과 BIP0143에서 정의한 네 가지 유형의 스크립트 중 하나로, p2pkh 스크립트와 비슷하지만 해제 스크립트의 데이터가 증인(witness) 필드에 분리되어 있습니다. 이렇게 해제 스크립트를 분리함으로써 트랜잭션 가변성 문제를 해결하였습니다.
2.1 p2wpkh 스크립트 실행 순서
잠금 스크립트와 해제 스크립트를 결합하여 명령집합을 구성합니다. 이때 해제 스크립트가 비어있는 이유는 나중에 증인 필드에서 서명과 공개키를 가져오기 때문입니다.
OP_0 명령어는 0을 스택 위로 올립니다.
20 바이트 해시값은 원소이므로 스택 위로 올립니다.
세그윗 업데이트가 적용되지 않은 노드의 경우는 여기에서 스크립트 실행이 종료되고 스택의 맨 위의 원소가 0이 아니기 때문에 스크립트가 유효하다는 판단을 내리게 됩니다. 그러나 세그윗 업데이트가 적용된 노드는 p2sh 스크립트에서 리딤 스크립트를 파싱 하는 것과 유사하게 특별 규칙이 실행됩니다.
p2wpkh는 명령집합에서 OP_0 <20-byte hash> 패턴을 발견하면 증인 필드에 있는 공개키와 서명 그리고 20바이트 해시값을 사용해 p2pkh 스크립트를 구성하여 명령집합에 추가합니다.
p2wpkh의 나머지 스크립트를 실행하는 것은 p2pkh와 동일합니다. 모든 명령어를 실행한 후 스택에는 1 또는 0이 남습니다.
2.2 의문점
- 분리된 서명 데이터는 어디에 저장이 되는가?
- 각 트랜잭션에 들어가던 서명 데이터는 머클 트리로 한 데 모아 머클 루트 형태로 저장됩니다. 이를 witness merkle root라고 합니다.
- witness merkle root는 블록의 코인베이스 트랜잭션의 입력 필드에 저장됩니다.
- https://bitcoin.stackexchange.com/questions/58414/why-include-the-segregated-witness-merkle-root-in-the-input-field-of-the-coinbas
- 세그윗 이전 노드들은 서명을 검증하지 않고 스택에 0 <20-byte hash>가 남은 상태에서 스크립트가 유효하다고 판단하고 넘어가고 마는데 이것이 과연 안전한가?
- 결론적으로 블록체인의 무결성에 문제가 있을 수 있지만, 서명은 다른 노드들에 의해서 충분히 검증이 되었다고 생각할 수 있기 때문에 서명이 유효하다고 믿고 넘어갈 수 있습니다.
- 게다가 세그윗 트랜잭션 비율은 꾸준히 증가하여 현시점(2024년 1월)에는 96%에 육박하기 때문에 많은 노드들이 세그윗 업데이트를 적용한 것으로 보입니다.
- https://transactionfee.info/charts/payments-spending-segwit/
📜 3. p2sh-p2wpkh 스크립트
p2wpkh는 Bech32라고 새로운 주소 형식을 사용합니다. 이는 BIP0173에 정의되어 있는데 세그윗 이전에 생성된 지갑들은 이 형식의 주소를 지원하지 못합니다.
이에 세그윗 제안자들은 Bech32 주소 형식을 사용하지 않고도 트랜잭션을 생성할 수 있도록 p2sh 형식에 기반한 p2sh-p2wpkh 스크립트를 고안해 냈습니다. 세그윗 스크립트가 p2sh 리딤 스크립트 안에 들어가 있으므로 이를 nested 세그윗이라고 합니다.
3.1 p2sh-p2wpkh 스크립트 실행 순서
잠금 스크립트와 해제 스크립트를 결합하여 명령집합을 구성합니다. p2wpkh 스크립트와 달리 해제 스크립트가 비어있지 않으며, p2wpkh 스크립트의 잠금 스크립트가 리딤 스크립트로 들어가 있습니다.
먼저 리딤 스크립트를 스택에 올립니다. 명령집합에는 p2sh 특별 규칙을 발생시키는 패턴이 감지됩니다.
OP_HASH160 명령어는 스택 위의 리딤 스크립트를 가져와 hash160 해시값을 구해 스택 위에 올립니다.
이어서 명령집합의 해시값이 스택 위로 올라가고 OP_EQUAL 명령어가 스택 위의 두 개의 해시값이 같은지를 확인합니다.
여기서 스택 위의 두 개의 해시값이 동일하다면, BIP0016(p2sh)을 미지원하는 노드는 특별 규칙을 모르므로 스크립트가 유효하다고 판단합니다. 반면, BIP0016을 지원하는 노드는 리딤 스크립트를 파싱하여 명령집합에 추가합니다.
여기서부터는 p2wpkh 스크립트와 동일합니다. 세그윗을 지원하지 않는 노드는 스크립트가 유효하다고 판단할 것이고, 세그윗을 지원하는 노드는 세그윗 특별 규칙을 실행합니다.
나머지는 p2pkh 스크립트와 동일합니다. 공개키의 서명이 유효하다면 1, 유효하지 않다면 0이 스택에 들어있는 상태로 스크립트 실행이 완료됩니다.
p2sh-p2wpkh 스크립트의 실행 과정을 정리하면 다음과 같습니다.
- p2sh 특별 규칙이 감지됩니다.
- BIP0016을 지원하지 않는 노드는 실행을 종료, 지원하는 노드는 리딤 스크립트를 파싱하여 명령집합에 추가합니다.
- p2wpkh 특별 규칙이 감지됩니다.
- 세그윗을 지원하지 않는 노드는 실행을 종료, 지원하는 노드는 증인 필드의 값들을 사용하여 p2pkh 스크립트를 구성하여 명령집합에 추가합니다.
- p2pkh 스크립트와 동일한 실행 과정을 거친 뒤, 스택에 1 또는 0이 남은 상태로 완료됩니다.
📖 참고자료
'블록체인 > Bitcoin' 카테고리의 다른 글
밑바닥부터 시작하는 비트코인 - 외전1 네트워크 요청 및 응답 개선 (0) | 2024.01.17 |
---|---|
밑바닥부터 시작하는 비트코인 - 13장 세그윗 2 (1) | 2024.01.14 |
밑바닥부터 시작하는 비트코인 - 12장 블룸 필터 (1) | 2024.01.10 |
밑바닥부터 시작하는 비트코인 - 11장 단순 지급 검증 (1) | 2024.01.09 |
밑바닥부터 시작하는 비트코인 - 10장 네트워킹 (1) | 2024.01.08 |