비트코인 블록을 열어 보면: 헤더 여섯 칸과 머클 트리
줄기의 앞선 세 글은 블록체인을 차례로 풀었습니다. 같은 돈을 두 번 쓰지 못하게 하려면 거래의 차례를 적은 장부가 필요합니다. 그 장부는 블록을 해시 값으로 이은 것이고, 고쳐 쓰려면 큰 계산을 다시 해야 합니다. 이 글은 진짜 블록체인의 블록 하나를 열어 봅니다. 블록 하나 안에는 무엇이 들어 있을까요?
블록 하나를 내려받았다
비트코인은 거래를 모두에게 알립니다 [S1]. 블록체인은 그 거래를 차례대로 적은 공개 장부입니다 [S3]. 누구나 블록을 받아 볼 수 있습니다. 여기서는 328,734번 블록을 골랐습니다. 이 블록은 2014년 11월에 만들어졌고 거래 49건이 들어 있습니다 [S5].
블록은 맨 앞의 80바이트 블록 헤더와 거래 건수, 그 뒤에 실린 거래들로 이루어져 있습니다 [S2]. 헤더에는 여섯 칸이 있습니다(그림 1).
02 00 00 00 b6 ff 0b 1b 16 80 a2 86 2a 30 ca 44 d3 46 d9 e8 91 0d 33 4b eb 48 ca 0c 00 00 00 00 00 00 00 00 9d 10 aa 52 ee 94 93 86 ca 93 85 69 5f 04 ed e2 70 dd a2 08 10 de cd 12 bc 9b 04 8a aa b3 14 71 24 d9 5a 54 30 c3 1b 18 fe 9f 08 64
| 칸 | 바이트 | 읽은 값 |
|---|---|---|
| version | 4 | 2 |
| 앞 블록 헤더의 해시 값 | 32 | 00000000000000000cca48eb4b330d91e8d946d344ca302a86a280161b0bffb6 |
| 머클 루트 | 32 | 7114b3aa8a049bbc12cdde1008a2dd70e2ed045f698593ca869394ee52aa109d |
| 시각 | 4 | 2014-11-06 02:12:52 (협정 세계시) |
| nBits | 4 | 목표 값을 줄여 적은 것 — 0x1bc330 × 25621 |
| 논스 | 4 | 1,678,286,846 |
이 글은 이 가운데 세 칸을 따라갑니다. 파란 머클 루트, 맨 끝의 논스, 노란 «앞 블록 헤더의 해시 값» 입니다.
이 80바이트의 해시 값
헤더 80바이트를 SHA-256 에 넣습니다. 나온 값을 한 번 더 넣습니다 [S2]. 블록은 보통 이 해시 값의 바이트 순서를 뒤집어 16진수로 적은 것으로 부릅니다 [S3].
328,734번 블록의 헤더 (그림 1 과 같은 80바이트)
여기서 견줍니다: 1≤ 2인가?
두 값은 모두 16진수 64자리입니다. 앞에 이어진 0 은 굵게 적었습니다.
0 이 17개나 이어집니다. 헤더의 해시 값은 nBits 칸에 줄여 적힌 목표 값보다 작거나 같아야 하기 때문입니다 [S2]. 두 값을 같은 자릿수의 수로 보면 앞의 0 이 많은 쪽이 작습니다. 목표 값은 0 이 16개로 시작합니다.
거래가 아무리 많아도 이 계산에는 헤더 80바이트만 넣습니다 [S3]. 그러면 거래 49건은 헤더와 어떻게 묶여 있을까요?
머클 루트 칸은 어디서 오나
거래마다 해시 값이 하나씩 있습니다 [S3]. 헤더의 머클 루트는 이 값 49개1로 만듭니다(그림 2).
거래의 해시 값을 블록에 실린 차례대로 놓고 둘씩 묶습니다. 한 쌍을 이어 붙여 SHA-256 에 두 번 넣으면 값 하나가 나옵니다. 짝이 없는 마지막 값은 자기 자신과 묶습니다2. 그렇게 나온 25개를 다시 둘씩 묶고, 하나가 남을 때까지 되풀이합니다 [S2]. 이렇게 해시 값을 묶어 올라가는 구조가 머클 트리이고 [S4], 마지막에 남은 하나가 머클 루트입니다. 이 블록에서는 49개가 25, 13, 7, 4, 2개를 거쳐 여섯 번 만에 하나가 됩니다.
| 줄 | 이 거래에서 올라온 값 | 묶는 짝 |
|---|
여기서 견줍니다: 1과 2가 같은가?
계산에는 거래 49건을 모두 씁니다. 표와 흐름 띠에는 고른 거래에서 루트까지 가는 길만 보입니다. 해시 값은 바이트 순서를 뒤집어 읽은 것의 앞 8자리와 끝 4자리만 적었습니다. 바뀐 값은 형광으로 칠합니다. 거래 자체가 아니라 거래의 해시 값 한 비트를 뒤집습니다. 진짜로 거래를 고치면 그 해시 값은 통째로 달라집니다.
거래를 고치면 그 거래의 해시 값이 달라지고, 그 값에서 루트까지 가는 길의 값이 모두 달라집니다. 머클 루트도 헤더에 적힌 값과 어긋납니다. 헤더의 머클 루트 칸을 새 값으로 고치면 이번에는 헤더의 해시 값이 달라집니다. 그래서 거래 하나를 고치려면 헤더까지 고쳐야 합니다 [S2].
길 밖의 값은 그대로입니다. 표의 오른쪽 칸(묶는 짝) 여섯 줄만 있으면 나머지 거래 48건을 몰라도 같은 머클 루트가 나옵니다. 49개를 한꺼번에 해시했다면 거래 하나를 확인하는 데도 49개가 모두 있어야 합니다. 둘씩 묶어 두면 줄마다 개수가 반쯤으로 줄어, 49건도 여섯 줄이면 됩니다. 비트코인 백서는 가장 긴 사슬의 헤더를 가진 쪽이 이 짝 값들로 거래 하나가 블록에 들어 있는지 확인하는 방법을 적습니다 [S1].
논스를 1 만 바꾸면
논스는 블록을 만드는 쪽(채굴자)이 바꿔 가며 해 보는 칸입니다. 조건에 맞는 해시 값이 나올 때까지 논스를 올리며 헤더를 다시 해시합니다 [S1] [S2]. 논스 4바이트(약 43억 가지)를 다 해 봐도 못 찾으면 시각을 고치거나 블록의 첫 거래를 바꿔 머클 루트를 새로 만든 뒤 다시 시도합니다 [S2]. 이 블록에서 찾은 논스는 1,678,286,846 입니다.
다른 칸의 한 비트 뒤집기
여기서 견줍니다: 1≤ 2인가?
논스가 1 만 달라도 해시 값은 통째로 바뀌고 조건을 벗어납니다. 이 목표 값에서는 헤더 하나가 통과할 확률이 약 1.7해(1.7 × 1020) 분의 1 입니다 (목표 값에서 계산한 값). 찾기는 어렵지만, 맞는지는 시뮬레이터 ① 의 계산을 한 번만 해 보면 압니다 [S1]. 이것이 작업 증명입니다. 왜 그만큼 드는지는 작업 증명 글에서 다룹니다.
앞 블록 칸
마지막은 노란 칸입니다. 여기에는 바로 앞 328,733번 블록 헤더의 해시 값이 적혀 있습니다 [S2]. 앞 블록의 헤더로 시뮬레이터 ① 과 같이 계산하면 그 값이 나옵니다(그림 3).
이 칸으로 블록은 사슬처럼 이어집니다 [S3]. 앞 블록을 고치면 그 해시 값이 달라져 이 칸에 적힌 값과 어긋납니다. 어긋남이 뒤로 번지는 모습은 해시로 이은 장부 글에서 직접 만져 볼 수 있습니다.
블록 하나에 든 것
| 든 것 | 하는 일 | 이 글에서 본 곳 |
|---|---|---|
| version | 어느 검증 규칙을 따를지 알린다 | 그림 1 |
| 앞 블록 헤더의 해시 값 | 블록을 앞 블록에 잇는다 | 그림 3 |
| 머클 루트 | 거래 전부를 헤더에 묶는다 | 그림 2 · 시뮬레이터 ② |
| 시각 | 블록을 만드는 쪽이 적은, 만들기 시작한 때 | 그림 1 |
| nBits | 목표 값을 줄여 적은 것 | 시뮬레이터 ① |
| 논스 | 조건에 맞는 해시 값을 찾을 때 바꾼다 | 시뮬레이터 ③ |
| 거래 건수 | 뒤에 실린 거래가 몇 건인지 적는다 (이 블록은 49) | 곁질문 1 |
| 거래들 | 헤더 뒤에 차례로 실린다 (이 블록은 49건) | 그림 2 |
칸들은 서로 물려 있습니다. 거래를 고치면 머클 루트가 달라집니다. 그러면 헤더의 해시 값도 달라져 뒤 블록의 앞 블록 칸과 어긋납니다. 시뮬레이터 ② 에서 달라진 머클 루트는 시뮬레이터 ③ 의 «머클 루트» 단추처럼 헤더의 해시 값을 바꾸고, 그 값은 그림 3 의 다음 블록 노란 칸과 맞지 않게 됩니다.
이 글의 계산과 확인
그림 1 의 헤더는 개발자 참고서에 실린 예시 80바이트를 한 바이트씩 옮긴 것입니다 [S2]. 이 헤더가 328,734번 블록이라는 정보와 거래 49건의 해시 값, 앞뒤 블록의 헤더는 공개 블록 탐색기에서 받았습니다 [S5]. 받은 값은 서로 맞는지 검증할 수 있습니다. 거래 49건의 해시 값으로 계산한 머클 루트는 예시 헤더의 머클 루트 칸과 같습니다. 328,733번 헤더를 해시하면 예시 헤더의 앞 블록 칸 값이 나옵니다. 예시 헤더를 해시하면 328,735번 헤더의 앞 블록 칸 값이 나옵니다.
목표 값은 참고서의 식 0x1bc330 * 256**(0x18-3) 으로 풀었습니다 [S2]. «약 1.7해 분의 1» 은 2256 을 «목표 값 + 1» 로 나눈 이 글의 계산입니다 (해시 값이 고르게 나온다고 보았습니다). 시뮬레이터 ③ 에서는 nBits 칸의 가장 낮은 비트만 뒤집습니다. 높은 비트를 뒤집으면 목표 값 자체가 달라지기 때문입니다.
같은 계산을 Node 의 crypto 로 교차 확인했습니다. 세 블록의 해시 값은 블록 탐색기의 값과 같습니다. 머클 트리는 거래 49건 가운데 어느 것의 한 비트를 뒤집어도 루트가 달라집니다. 거래마다 짝 값 여섯 개만으로 같은 루트도 다시 나옵니다. 논스 ±1 은 조건을 만족하지 않습니다. 헤더 640비트 중 어느 한 비트를 뒤집어도 해시 값이 원래 목표 값보다 큽니다 (verify.mjs 92개 통과). 이 글이 직접 짠 것은 칸 나누기·바이트 순서 뒤집기·목표 값 풀기·머클 트리의 짝 짓기뿐이고, 해시는 브라우저의 SHA-256(Web Crypto)입니다.
출처
- [S1] Nakamoto, Bitcoin: A Peer-to-Peer Electronic Cash System (2008) — §2, §4, §7, §8
- [S2] Bitcoin Developer Reference — Block Chain — Block Headers, Merkle Trees, Target nBits, Serialized Blocks
- [S3] Bitcoin Developer Guide — Block Chain
- [S4] NIST IR 8202, Blockchain Technology Overview (2018) — 용어집 «Merkle tree»
- [S5] Blockstream Explorer — 블록 328,734 (헤더·거래 49건의 해시 값·앞뒤 블록 328,733 · 328,735 의 헤더는 같은 곳의 API 로 2026-10-05 받음)