용어집 / 채굴과 합의
직렬화된 블록
- 직렬화된 블록이란 무엇입니까?
- 직렬화된 블록은 블록이 네트워크 선로나 디스크에서 가지는 정확한 바이트 문자열입니다. 즉 80바이트 헤더, 트랜잭션 수, 그리고 순서대로 나열된 모든 트랜잭션으로 이루어집니다.
BIP-144에 명시되어 있습니다.
직렬화는 추상적인 블록이 해시를 계산하고, 전송하고, 저장할 수 있는 대상으로 바뀌는 과정입니다. 제네시스 블록은 285바이트로 직렬화됩니다. 헤더에 80바이트, 트랜잭션 수에 1바이트, 단 하나의 코인베이스 트랜잭션에 204바이트가 쓰입니다. 블록 탐색기에 원시 16진수를 붙여 넣어 본 적이 있거나 verbosity를 0으로 두고 getblock을 실행해 본 적이 있다면, 바로 이 대상을 보고 있었던 것입니다.
작동 방식
직렬화된 블록에는 세 부분이 차례로 이어지며, 고정 길이를 가지는 부분은 첫 번째뿐입니다.
헤더는 항상 80바이트이며 순서는 다음과 같습니다. 4바이트 버전, 이전 헤더의 32바이트 해시, 32바이트 머클 루트, 4바이트 타임스탬프, 목표값을 인코딩한 4바이트 nBits, 4바이트 논스입니다. 다음에는 트랜잭션 수가 가변 길이 정수인 compactSize로 기록됩니다. 이는 253 미만의 개수에는 1바이트를 차지하고, 아주 큰 값에는 최대 9바이트를 차지합니다. 그다음에는 트랜잭션 자체가 각각 완전히 직렬화되어 이어지며, 코인베이스가 맨 앞에 옵니다.
BIP144 이후 같은 블록에는 두 가지 적법한 직렬화가 있습니다. 스트립트 형태는 위트니스를 완전히 빼며, 2017 이전 소프트웨어가 기대하는 형태입니다. 전체 형태는 위트니스를 포함하며, 위트니스를 담은 트랜잭션마다 입력 수가 들어갈 자리에 0x00 바이트와 0x01 플래그를 표시합니다. 두 형태는 동일한 블록을 인코딩하고 동일한 블록 해시를 만들어 냅니다. 해시는 헤더의 80바이트만 대상으로 하며, 그 안의 머클 루트가 트랜잭션 ID에 대한 약속을 담당하고, 트랜잭션 ID는 스트립트 인코딩으로 계산되기 때문입니다. 이러한 분리가 분리된 위트니스(segregated witness)의 문자 그대로의 의미입니다.
모두가 한 번쯤 걸리는 습관이 하나 있습니다. 여러 바이트 정수는 리틀 엔디언으로 기록되므로, 타임스탬프 0x495FAB29는 네트워크에서 29 ab 5f 49로 나타나며, 해시는 직렬화된 바이트 순서의 역순으로 표시됩니다. 블록 탐색기에서 복사한 블록 해시는 파일에 들어 있는 바이트 순서와 다릅니다.
확인할 수 있는 곳
직렬화된 블록은 P2P 네트워크에서 block 메시지 안에 담겨 이동합니다. 각 메시지에는 먼저 24바이트 봉투가 붙습니다. 4바이트 시작 문자열(메인넷에서는 f9beb4d9), 12바이트 명령 이름, 4바이트 페이로드 길이, 그리고 페이로드 전체에 대한 이중 SHA-256의 처음 4바이트에서 가져온 4바이트 체크섬입니다. Bitcoin Core는 메시지 페이로드 하나를 4,000,000바이트로 제한하는데, 이는 합의 규칙이 아니라 네트워크 한도입니다.
같은 바이트가 디스크에도 기록됩니다. Bitcoin Core는 블록을 blk00000.dat와 그다음 이름의 파일들에 추가하며, 각 파일은 128MiB로 제한됩니다. 파일마다 동일한 시작 문자열과 블록마다 길이 접두어가 붙어 파일을 순차적으로 훑어볼 수 있습니다. 제네시스는 예외입니다. 제네시스는 내려받지 않고 상수로 소프트웨어에 컴파일되어 들어가며, 그래서 동기화하는 노드가 다른 모든 것을 견주는 기준점이 됩니다.
일상적인 사용에서는 직렬화가 verbosity 0의 getblock RPC, 대부분의 블록 탐색기의 원시 또는 16진수 탭, 블록을 직접 해독할 수 있는 도구 안에서 드러납니다. 블록 탐색기가 진실을 말했는지 확인하려는 사람은 결국 여기에 도착합니다. 16진수가 아무도 형식을 바꾸지 않은 유일한 표현이기 때문입니다.
직렬화된 블록 vs 블록
블록은 객체이고, 직렬화된 블록은 그 객체의 한 가지 인코딩입니다. 이 구분은 2017년까지는 겉모습의 문제였습니다. SegWit이 모든 블록에 길이가 다른 두 가지 유효한 인코딩을 부여하면서 블록의 크기는 조건을 붙여야 하는 질문이 되었습니다. Bitcoin Core는 하나의 RPC 응답에서 이 질문에 세 가지로 답합니다. 전체 직렬화에는 size, 위트니스가 없는 형태에는 strippedsize, 규칙이 실제로 강제하는 수치에는 weight입니다.