블록 구조 (2편)
이 글은 성균관대학교 블록체인 네트워크 Skkrypto 브런치에도 연재가 되어 있습니다.
이어서 나머지 헤더의 구조를 살펴보자
‘어려운 수학 문제를 푼다’라는 채굴의 설명은 많이 접해봤을 것이다. 필자는 해당 설명을 처음 접했을 때 좀 더 정확한 설명을 찾기 위해 노력했고 원리를 알게 되었을 때, 결코 어렵지 않고 재밌는 원리를 이용했다고 생각이 들어 정확한 작동 원리를 적어보았다.
어려운 수학 문제를 푸는 것은, 해시를 통해 특정 목푯값 보다 낮은 값을 찾는 일
즉, 난이도가 높다면 ‘특정 목푯값’은 낮고, 난이도가 낮다면 ‘특정 목푯값’은 높다. 주사위로 예를 들자면, 주사위로 2보다 작은 수가 나오는 확률이, 5보다 작은 수가 나올 확률보다 작은 원리랑 같다고 보면 된다. 이 원리를 염두하여 좀 더 깊이 이해해 보자.
위 사진에 나온 Difficulty(난이도)와 Bits (난이도 비트)에 대해 살펴보자. 해당 내용은 약간의 수학적인 계산이 들어가므로 기본적인 개념을 살펴본 이후로 계산 과정은 스킵해도 좋다. 계산 부분은 붉은 글씨로 표기해 두겠다.
먼저 사진 속 Difficulty는 위에서 말한 난이도를 표기한 형태이다. 해당 블록을 채굴할 때의 난이도를 의미하며, 이 수는 블록의 높이에 따라 자동 설정이 된다. 왜 자동 설정이 되는지, 어떠한 방식으로 설정이 이루어지는지는 후반부에 설명이 이어질 예정이다.
해당 난이도에 맞는 목푯값이 존재하며 그 목푯값을 'Bits'로 표기한다. 이 수는 계수와 지수로 이루어져 있다.
해당 숫자에 대한 의문이 드는 분들을 위해 수학적인 계산을 이어나갈 것이다. 16진법 계산기를 이용하여 직접 계산해보며 비교해보면 더욱 좋을 것이다.
먼저 난이도와 목푯값의 관계에 대해 의문이 들 것이다. 공식은 다음과 같다.
Difficulty = MAX_TARGET / current_target
MAX_TARGET은 '첫 난이도'로서 비트코인 블록체인이 처음 구동될 때 설정된 난이도 값으로 값 '1'을 의미하며, 4바이트로 '1d00ffff'라고 표기되었다.
목푯값보다 낮은 해시값을 찾는 과정이 채굴이라고 설명했다. 그렇다면 current_target(목표값), 즉 bits는 해시값과의 비교를 위해 어떻게 계산될까?
위 사진을 예로 들어보자.
'bits'값인 388618029를 16진법으로 변환하면 0x1729d72d의 값이 나온다. bits는 지수와 계수로 표기된다고 설명하였다. 첫 1바이트는 지수, 이후 3바이트는 계수가 된다. 즉, 해당 bits는 0x17는 지수, 0x29d72d 계수가 된다. (0x는 16진법을 의미한다.)
이는 다음과 같은 특정 식을 통해 해시값과 비교가 가능한 목푯값 형태가 나온다.
목푯값 (target) = 계수 * 2 ^( 8 * (지수 - 3) )
해당 값을 대입하면
0x29d72d * 2 ^ (0x08 * (0x17 - 0x03) )
이를 10진법으로 변환하면
2742061 * 2 ^( 8 * (23 - 3) ) = 4.0075266411612129867925142360828 e+54
의 값이 나온다.
해당 결괏값을 다시 16진법으로 변환할 경우 비교 가능한 묙표 해시값이 나온다.
0x0000 0000 0000 0000 0029 d72d 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000
여기서 블록 538695의 실제 해시값을 보았을때
0x0000 0000 0000 0000 000d 8b40 25c6 3560 88d7 5a7f 3e68 1841 1bab 2b74 8947 dcda 인 값은
0x0000 0000 0000 0000 0029 d72d 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 인 목표값보다 작음을 확인할 수 있다.
난이도의 상승 또한 다른 블록을 통해 확인할 수 있다.
실제 277316번째 블록의 목푯값은 다음과 같다.
0x0000 0000 0000 003A 30C0 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000
0x0000 0000 0000 0000 0029 d72d 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000
의 목푯값을 가지는 538695번째와 비교를 했을 때, 최근 블록인 538695번째 목푯값의 앞자리 0의 숫자가 더 긴 것을 확인할 수 있다. 이는 목표값이 더 낮아졌음을 의미하며, 목표값보다 낮은 값을 찾는 '난이도'가 높아졌음을 의미한다.
특정 길이의 공간에서 앞자리의 0의 숫자(Leading Zeros)가 길수록 난이도는 높다고 표현할 수 있다. 0의 숫자를 1비트 증가시킬 때마다 검색 공간은 반으로 줄어든다. 즉, 해시를 통해 나올 수 있는 결괏값이 무수히 많은 경우의 수를 가지지만, 난이도가 높을수록 작은 숫자(목푯값) 보다 작은 값을 찾는 과정이다. 비유를 하자면, 방 안(256비트의 해시 결괏값 공간)에서 ‘침대보다 작은 물건 찾기’(난이도가 낮은, 목푯값이 높은 값)보다 ‘양말보다 작은 물건 찾기’(난이도가 높은, 목푯값이 낮은)가 어렵다. 주사위를 예시로 든 것과 같은 개념이다.
‘난이도’가 높아질수록, ‘목푯값’은 낮아지고, 결국 채굴은 ‘목푯값’보다 낮은 ‘현재 블록 헤더 해시값’을 찾는 과정이다. ‘블록 헤더 해시’는 해시값이기 때문에 점진적으로 증가하거나 낮아지는 형태가 아닌 무작위로 결괏값을 띈다는 사실을 인지하면, 채굴이 왜 어려운지에 대해서 그리고 왜 무작위인지에 대해 알 수 있을 것이다.
이 모든 랜덤한 과정에 있어서 유일하게 변하는 값은 넌스(nonce)다. number + once라고 이해하면 더 쉽게 다가올 것이다. 즉, 한번 쓰이는 숫자이다. nonce는 0부터 시작하여 무수히 많은 숫자까지 증가시키며 목푯값 보다 낮은 해시 결괏값을 찾도록 쓰인다. 결국 모든 채굴의 과정은 nonce로 인해 좌지우지되게 된다.
nonce를 제외한 헤더의 구조를 살펴봤을 때, 모든 것은 주어져 있다고 볼 수 있다. ‘버전’과 ‘타임스탬프’는 채굴하는 순간의 값이며, ‘난이도 비트’는 자동 설정되어있으며, ‘이전 블록 헤더 해시’과 ‘머클 루트’는 단순 계산으로 구할 수 있다.
채굴자들은 채굴하고자 하는 블록을 위해 바디를 준비해 놓는다. 어떠한 노드에 의해 이전 블록이 완성되어 전달받자마자 해당 블록 헤더 해시를 계산하여 nonce를 제외한 모든 헤더의 모든 값을 준비해 놓는다. 이후 nonce값을 바꿔가며 현재 블록의 헤더를 해시함으로써 채굴을 시도한다. nonce만 바꿔주면 되는데 채굴이 간단한 것 아닌가라고 생각할 수 있지만 한 글자의 차이도 완전 다른 결괏값을 만들어내는 해시의 특성을 생각한다면 nonce의 중요성을 알 수 있을 것이다.
또한 난이도와 상관없이, 매우 높은 난이도이더라도 특정 목푯값 이하를 만족시키는 해시를 찾기 위한 nonce가 단 두 번 만에 ‘2’와 같은 매우 낮은 숫자에도 채굴이 성공할 수 있다는 것을 알 수 있을 것이다. 하지만 확률이 매우 낮다는 사실을 인지했다면 채굴을 정확히 이해했다고 할 수 있을 것이다.
지금까지 블록의 구조를 살펴볼 수 있었고 그에 따라 채굴의 원리를 좀 더 정확히 이해할 수 있었다.
채굴의 원리를 이해하며 다음과 같은 의문사항이 들 수 있을 것이다.
난이도는 항상 일정한가?.. 그러면 해시 파워(채굴 능력)가 세질수록 블록이 점점 빠르게 생성될 수 있고 결국 1초 만에 블록이 형성될 수 있는 것 아닌가?
그러한 우려로 사토시 나카모토는 난이도가 자동 조절이 가능하도록 설계하였다.
사토시 나카모토는 ‘10분에 블록 1개’가 적정한 난이도가 되어야 한다고 생각을 하였고, 그에 맞춰 난이도 조절이 자동적으로 진행된다. ‘10분’의 이유는 밝히지 않았지만, 그보다 작은 시간에 블록이 형성된다면 거래
정산 시간은 짧아지지만 포크(fork)가 자주 발생할 것이고, 그보다 긴 시간이 소요된다면 분기는 줄어들지만 거래가 블록에 담길 때까지 시간이 오래 걸리게 되어 거래 정산 시간이 길어질 것이다. 이에 적당한 시간을 10분으로 설정하였고 그를 위한 난이도 조절 방법은 다음과 같다.
Next Difficulty = current difficulty * 2 weeks / T ( Time in which previous 2016 blocks found)
2016개의 블록을 주기로, 이전 주기에서 2016개의 블록이 형성될 때까지의 시간을 체크하여 새로운 난이도를 조정한다. 예를 들면 2016개의 블록이 형성될 때까지 블록 1개 생성당 평균 5분이 걸렸다면 난이도가 높아지고, 15분이 걸렸다면 난이도가 낮아진다. 즉, 각각의 목푯값이 낮아지고, 높아지게 형성된다.
사진 속 '난이도'는 해당 블록에 맞게 설정된 난이도로서, 이전 블록과 이후 생기 블록에도 같은 난이도 값이 들어가 있음을 확인할 수 있다. 즉, 새로 난이도가 조정되기 전까지 같은 값으로 유지가 되고 있음을 확인할 수 있다.
채굴을 하면 얻는 이익은 무엇인가?
채굴자들은 아무 이유 없이 어마어마한 전기세를 내며 블록을 만들어나가고 블록체인을 유지시켜 줄 수 없다. 비트코인은 블록체인이 활성화될 수 있도록 채굴자들에게 인센티브를 설계하였다.
채굴자들은 블록을 채굴하면서 ‘수수료’와 ‘보상’을 얻어간다.
‘수수료’는 블록에 담는 거래의 수수료를 합산한 것을 의미하며 ‘보상’은 비트코인 프로토콜 상 채굴자에게 주어지는 인센티브이다. 프로토콜 상 발행으로서 통화 발행량이라고도 칭한다.
그렇다면 보상은 어떻게 설계되어 있을까?
첫 블록 채굴자에게 주어지는 보상은 50 BTC였으나, 인플레이션을 막기 위해 반감기를 두어 21만 블록(약 4년)마다 절반으로 통화 발행량이 줄어든다. 이는 대략적인 계산으로 2140년에 통화 발행량이 0이 된다고 한다. 그 이후에는 블록체인이 멈춘다기 보단, 보상 없이 수수료를 받기 위해 채굴자들이 블록을 형성하게 된다고 보면 된다.
중요한 사실은, 처음부터 통화량이 정해져있지는 않다는 것이다. 50BTC를 시작으로 계산을 통해 총 발행량을 구해 정해져있다고 할 수 있지 않나라고 의문이 들 수 있지만, 그렇지 않다. 실제로는 예상 발행량(2100만개) 보다 적은 BTC가 생성되게 된다. 이유는 이어지는 다음글을 통해 설명하도록 하겠다.
그렇다면 그 보상은 어떤 방식으로 채굴자에게 주어지는가?
이는 매우 중요한 질문이다. 비트코인 블록체인은 p2p기반의 UTXO 모델로, 모든 utxo들의 거래로 이루어져 있다고 볼 수 있었다. 또한 utxo들은 소유권 이전의 개념으로서 누군가가 나에게 utxo를 넘겨줬을 때 소비할 수 있었다. 그렇다면 이러한 utxo의 개념을 생각해 봤을 때, 최초의 utxo는 무엇인가에 대한 의문이 들것이다. 즉, 닭과 달걀의 문제에서 무엇이 먼저인가? 그리고 탈중앙화된 환경에서 어떻게 생성되는가?
그렇다. 최초의 utxo는 채굴자가 얻는 보상과 수수료로서 '생성 거래'(Coinbase transaction)라고 부른다.
그렇다면 coinbase란 무엇일까?
다음 챕터에서 Coinbase의 개념과 Genesis Block에 대한 개념을 살펴보겠다.
참고
Antonopoulos, Andreas M. Mastering Bitcoin: Unlocking Digital Crypto-Currencies. OReilly, 2016.
손동하/ sohn@skkrypto.io