논스를 찾을 때까지: 작업 증명이 블록을 지키는 법

회색 작은 칸이 가득한 가운데 단 한 칸만 노랗게 켜져 있다. 그 칸에서 나간 화살표가 닿은 블록에는 앞의 세 칸이 비어 있는 띠와 ✓ 가 있다.

앞 글에서 블록을 해시 값으로 이었습니다. 가운데를 고치면 드러나지만, 고친 사람이 뒤 블록을 모두 다시 써서 맞추는 계산은 순식간이었습니다. 비트코인은 블록을 만드는 일 자체에 큰 계산이 들게 했습니다 [S1]. 그 계산은 어디에서 생길까요?

해시 값으로 잇기만 하면 금방 고쳐 씁니다

블록 1
내용 +
앞 블록의 해시 값
→ SHA-256 →해시 값
8a3f…
→블록 2
앞 블록의 해시 값:
8a3f…
그림 1. 블록의 해시 값(SHA-256)이 다음 블록의 «앞 블록의 해시 값» 칸에 들어갑니다 [S2]. 이 글의 블록은 줄여 그린 교육용 모형입니다. 실제 비트코인은 블록 헤더를 SHA-256 에 두 번 넣습니다 [S2].

블록 1 의 내용을 바꾸면 해시 값이 달라집니다. 블록 2 의 «앞 블록의 해시 값» 칸을 새 값으로 고쳐 적으면 사슬은 다시 맞습니다. 해시 함수는 누구나 금방 계산할 수 있어서, 이 일은 순식간에 끝납니다.

조건을 붙입니다: 앞의 0

내용 + 논스 0→ SHA-256 →해시 값→0으로 시작?
아니면 논스 +1 ↺
그림 2. 조건에 맞을 때까지 논스를 바꿔 다시 계산합니다 [S1].

작업 증명은 블록의 해시 값에 조건을 붙입니다. 블록에는 논스라는 칸이 있습니다. 해시 값을 바꾸려고 마음대로 고쳐 넣는 수입니다 [S2]. 블록을 만드는 쪽은 조건에 맞는 해시 값이 나올 때까지 논스를 하나씩 올리며 다시 계산합니다 [S1]. 해시 값은 입력을 조금만 바꿔도 전혀 다른 값이 되므로(해시 함수 글), 맞는 논스를 미리 알 방법이 없어 하나씩 해 봐야 합니다.

실제 조건은 «해시 값이 목표 값보다 작거나 같아야 한다» 입니다 [S2]. 해시 값은 아주 큰 수 하나를 16진수 64자리로 적은 것이라, 앞자리에 0 이 많을수록 작은 수입니다. 00c1… 은 0100… 보다 작습니다. 그래서 «앞에 0 이 두 자리» 는 «0100… 보다 작다» 와 같은 말입니다. 백서도 조건을 «0 비트로 시작하는 해시 값» 으로 설명합니다 [S1]. 이 글의 시뮬레이터는 조건을 앞자리 0 의 개수로 줄였습니다. 진짜 블록의 목표 값과 견주는 일은 곁가지 글 «진짜 블록 열어 보기» 에서 합니다. 직접 짠 SHA-256 과 블록 모양은 교육용입니다 (실제로 쓰지 말 것).

0 하나에 평균 16배

해시 값의 자리마다 16진수 글자 16가지(0~9, a~f)가 고르게 나온다고 봅시다. 그러면 첫 자리가 0 인 해시 값은 16번에 한 번꼴입니다. 평균 16번은 해 봐야 하나를 찾습니다. 이렇게 여러 번 되풀이했을 때의 평균을 기댓값이라고 합니다. 두 자리가 모두 0 이려면 그 가운데 다시 16번에 한 번꼴이라 16 × 16 = 256번입니다. 한 자리를 더 요구할 때마다 평균 16배입니다 (이 글의 계산). 16진수 한 자리는 4비트라, 백서의 말로는 0 비트가 넷 늘어난 것입니다. 백서는 필요한 0 비트가 늘수록 평균 작업량이 지수적으로 는다고 적습니다 [S1]. 한 번의 결과는 운에 따라 들쑥날쑥합니다. 여러 번 찾아 평균을 보세요.

시뮬레이터 ① · 질문: 0을 한 자리 더 요구하면 몇 번이나 더 찾아야 할까요?

자릿수를 고르고 찾아 보세요. 누를 때마다 기록이 바뀌어 결과도 달라집니다.

10번으로는 평균이 아직 흔들립니다. 몇 번 더 누르면 기댓값에 가까워집니다.

    그림 3. 자릿수마다 지금까지 찾은 평균 시도 횟수와 기댓값(16을 자릿수만큼 거듭 곱한 값 — 한 자리 16, 두 자리 256, 세 자리 4,096)입니다. 막대는 평균을 로그 눈금으로 나타냅니다.

    고치면 뒤까지 다시

    네트워크의 컴퓨터들은 해시 값이 조건에 맞지 않는 블록을 받지 않습니다 [S4]. 블록 하나를 고치면 그 블록의 해시 값이 달라져 조건이 대개 깨집니다. 0 두 자리 모형에서 새 값이 우연히 맞을 확률은 256분의 1 입니다 (이 글의 계산). 깨지면 논스를 다시 찾아야 합니다. 우연히 맞았더라도 새 해시 값은 뒤 블록의 «앞 블록의 해시 값» 칸에 들어갑니다. 그러면 뒤 블록의 해시 값도 달라져 조건이 대개 깨지고, 그 논스도 다시 찾아야 합니다. 마지막 블록까지 이어집니다 [S1]. 고칠 블록을 바꿔 합계를 견줘 보세요. 블록마다 찾는 횟수가 운에 달려 있어 실제 합계는 들쑥날쑥합니다. 그래서 평균인 «다시 한 블록 수 × 256번» 을 나란히 적었습니다.

    시뮬레이터 ② · 질문: 가운데 블록을 고치면 다시 해야 하는 작업은 얼마나 될까요?

      그림 4. 0 두 자리 조건을 쓰는 다섯 블록짜리 교육용 사슬입니다. 블록마다 든 시도 횟수와 합계를 보세요.

      비싸지만 못 하는 것은 아닙니다

      고치는 사이에도 사슬에는 새 블록이 붙습니다. 고친 쪽은 뒤 블록의 작업을 모두 다시 하고, 정직한 쪽이 쌓는 작업까지 따라잡아 앞질러야 합니다 [S1]. 계산력이 나머지를 합친 것보다 많으면 그럴 수 있습니다 [S1]. 백서는 계산력이 더 적은 공격자가 따라잡을 확률도 따로 계산합니다 [S1]. 그래서 NIST 는 블록체인을 고치면 드러나고, 고치기 어려운 기록이라고 하고, 완전히 바꿀 수 없다고는 하지 않습니다 [S3].

      이 글의 0 두 자리는 평균 256번이면 끝나는 작은 모형입니다. 실제 비트코인은 80바이트 블록 헤더를 SHA-256 에 두 번 넣고 [S2] [S4], 조건이 훨씬 엄격합니다. 곁가지 글에서 여는 실제 블록은 해시 값이 0 열일곱 자리로 시작합니다 (그 글의 계산). 또 2,016블록마다 걸린 시간을 보고 조건을 다시 맞춥니다 [S4].

      출처

      1. [S1] Bitcoin: A Peer-to-Peer Electronic Cash System, §4·§11.
      2. [S2] Bitcoin Developer Reference — Block Chain, Block Headers.
      3. [S3] NIST IR 8202 — Blockchain Technology Overview, §7.1.
      4. [S4] Bitcoin Developer Guide — Block Chain.