비트코인 백서읽기(하)
올해로 비트코인은 탄생 14주년을 맞았다. 2008년 그날 사토시 나카모토가 작성한 백서를 읽어보자.
이번 글은 비트코인 백서 읽기 (상)에 이어 (하)편이다.
목차
1. 보상 체계
2. 거래기록 저장과 라이트 노드
3. UTXO 개념 및 보안
4. 결론
1. 보상 체계
이번 비트코인 백서 읽기(하)에서는 거래가 어떻게 블록체인에 기록되는지 단계별로 다시 짚어보고,
이 과정에서 인센티브 제공을 통해 노드들의 악행을 어떻게 방지하는지부터 다뤄보겠습니다.
거래가 블록체인에 기록되는 과정은 다음과 같습니다:
-
새로운 거래가 모든 노드들에게 전파된다.
-
각 노드는 해당 거래를 묶어 블록을 만든다.
-
각 노드는 논스를 대입하여, 특정 해시를 만들어내는 과정을 수행한다(PoW).
-
특정 해시를 만들어내는 논스를 찾아낸 노드는 해당 블록을 모든 노드들에게 전달한다.
-
노드들은 해당 블록에 포함된 거래들에 이상이 없는지(이중지불이 없는지) 체크한다.
-
노드들은 다음 블록 PoW를 진행함으로써 생성된 블록에 대해 동의한 것으로 갈음한다.
지금까지 잘 따라오셨다면 이해가 쉽게 되실 것 같습니다.
6번의 경우, 다음에 생성되는 블록의 PoW 작업엔 이전 블록의 해시가 포함되기 때문에,
다음 블록을 만드는 행위 자체가 이전 블록에 대한 동의로 연결된다는 것만 이해하시면 될 것 같습니다.
노드들은 항상 가장 긴 체인이 맞는 것으로 가정하고(=가장 많은 컴퓨팅 파워가 소모=가장 많은 사람이 투표), 해당 체인을 계속 연장해나갑니다.
이 과정에서 블록이 동시에 생성되기도 합니다. 이는 PoW에서 제시하는 특정 해시가 ‘값’이 아니라 ‘조건’이기 때문인데요.
이를테면 ‘앞에 10자리가 0으로 시작하는 해시’라는 식인 겁니다.
그렇다면, 0000000000abedefg도, 0000000000eed3e도 모두 조건을 만족합니다.
각 해시를 만드는 논스들은 여러 개가 될 수 있기 때문에, 블록도 동시에 생성될 수 있는 거죠.
만약 이처럼 두 개의 블록이 발생하면, 노드들은 가장 먼저 들어온 블록을 기준으로
다음 PoW 작업을 실시하되, 다른 블록도 보존합니다.
다른 블록이 더 길어질 가능성도 있기 때문이죠. 둘 중 길어진 쪽으로
PoW 작업이 이뤄질 것이고 자연스럽게 짧아진 체인은 파기됩니다.
근데 만약 노드 일부가 온라인 접속이 끊겨 새로운 거래 내역이나 새로운 블록 정보를 못 받으면 어떨까요?
특정 노드가 오프라인이 되어도 거래내역을 받은 다른 노드는 PoW를 진행하여 블록을 생성할 것이고,
오프라인이 되었던 노드는 이후 누락된 블록의 정보만 받아와 다시 PoW에 참여하면 그만입니다
(삭제된 메시지에 대한 내성)
블록체인에 기여한 대가로 노드들은 보상을 받을 수 있는데요.
보상은 채굴 보상과 채굴 수수료로 이뤄져 있습니다.
블록 안에는 여러 거래 내역들이 포함되어 있습니다.
그중 첫 번째 거래 내역은 새롭게 발행되어 해당 블록을 채굴한 노드에게 일정량의 비트코인을 전달한다는 내용이 담겨있습니다.
특정 블록의 첫 번째 거래내역 예시
이런 보상(및 제공 방식)은 두 가지 기능을 수행하는데요.
먼저 네트워크를 유지하는데 기여한 노드에 대한 보상(an incentive for nodes to support the network)입니다.
장부에 기록하기 위한 PoW에 컴퓨팅 파워를 사용했으니, 이에 대한 보상이 필요한 거죠.
두 번째는 코인 발행 역할을 수행합니다(provides a way to initially distribute coins into circulation).
블록체인엔 중앙화된 주체가 없어 애초에 보상으로 코인을 지급함으로써 유통량을 늘립니다.
거래 수수료(transaction fee)는 블록체인의 혼잡도에 따라 계산되어 노드에게 제공되는 소량의 보상입니다.
채굴 보상이 종료되어 더 이상 비트코인이 발행되지 않을 경우, 거래 수수료가 블록체인을 유지하는 보상이 될 수 있습니다.
이러한 보상 체계는 노드들이 정직한 행동을 하도록 유도할 수 있습니다.
악의를 가진 노드가 다른 노드들보다 더 많은 컴퓨팅 파워를 갖고 있다고 가정해 보겠습니다.
악한 노드에겐 컴퓨팅 파워를 활용할 두 가지 방법이 있을 겁니다:
본인의 거래를 되돌리는 블록을 만들거나(defraud people by stealing back his payments),
정상적인 방법으로 채굴을 하거나(using it to generate new coins)
악한 노드 예시
악한 노드가 본인의 거래를 되돌리기로 결정했다고 가정하면 다음과 같은 일이 발생합니다:
-
악의를 가진 A가 1 BTC를 B에게 보내고 대가로 USD를 받기로 함
-
‘1 BTC를 B에게 보낸다’라는 거래를 포함한 블록이 생성(이하 ‘정상 블록’)되고 B로부터 USD를 수령함
-
USD를 수령하자마자 1 BTC를 사용하지 않은 새로운 블록(이하 ‘비정상 블록’)을 생성함
-
이후 비정상 블록에 블록을 붙여 더 긴 체인을 만듦
-
해당 체인은 가장 긴 체인이 되므로, 다른 노드들도 해당 체인에 블록을 이어 붙임
-
정상 블록이 포함된 체인은 짧은 체인으로 버려짐(이에 1 BTC 지출에 대한 거래내역도 버려짐)
그런데 이게 현실적으로 가능할까요? 먼저 51%에 해당되는 컴퓨팅 파워를 확보하는 것 자체가 불가능합니다.
가능하다고 하더라도, 본인이 소유권을 갖고 있는 비트코인에 대해서만 조작이 가능하므로
51%를 확보하기 위해 지출한 비용만큼의 수익을 얻긴 힘듭니다.
51% 공격이 일어났다는 사실이 퍼지는 순간, 악한 노드가 보유한 비트코인 역시 가치가 떨어지기 때문이죠.
이런 수고스러운 악행을 저지르느니, 정상적인 방법으로 채굴해서 보상을 얻는 것이
수지타산에 맞다는 겁니다(more profitable to play by the rules).
그야말로 ‘Can’t be evil’인 셈이죠.
보상 체계를 통해 장부를 기록하는 사람들은 악행을 방지하고,
PoW를 통해 참여자들의 대다수가 단일한 장부에 동의하는 과정을 살펴보았습니다.
합쳐서 말하면 ‘선의를 가진 대다수가 단일한 장부에 동의를 했다’라고 할 수 있겠네요.
이렇게 만들어진 장부는 누구나 볼 수 있는 공간, 온체인에 기록됩니다.
수정이 사실상 불가능하다는 얘기입니다. 이제 장부가 무결하다는 것에 동의하시나요?
2. 거래기록 저장과 라이트 노드
이러한 장부는 모든 노드들이 공유하게 되는데요, 기록이 오랫동안 쌓이며 용량이 커지면 노드들에게 부담이 될 겁니다.
이번에는 비트코인 블록체인에서 어떻게 거래기록이 저장되며, 이를 통해 지불이 효율적으로 이뤄지는 과정을 살펴보겠습니다.
새롭게 생성된 거래가 새로운 블록에 포함되고 체인에 연결됩니다. 그리고 해당 블록을 포함한 체인 뒤로는 계속해서 블록이 붙습니다.
이렇게 충분히 체인이 길어지면, 특정 거래를 뒤집긴 불가능에 가깝습니다.
그렇다면, 지불이 된 거래들(the spent transcations before)은 삭제해도 되지 않을까요?
(지불이 된 거래라는 개념은 ‘쓸모가 없어진 거래기록’ 정도로 해석하시면 될 것 같습니다.)
그런데 블록 해시를 만드는 데이터엔 거래 기록이 포함되어 있습니다.
이런 거래 기록을 삭제하게 되면, 블록의 해시가 변할 거고(기억나시죠? 데이터가 변하면 해시는 무작위로 변합니다.),
그럼 다음 블록도, 그다음 블록도 엉망진창이 될 겁니다.
블록의 해시를 깨지 않으면서, 필요가 없어진 거래 기록을 삭제할 수 있도록 비트코인은 머클트리(Merkle Tree)라는 구조를 활용합니다.
그리고 이런 시스템을 통해 블록 헤더(블록 해시를 만드는 주요 데이터의 모음)엔 모든 거래 기록 대신 Root Hash(이하 ‘루트해시’)만 들어가게 됩니다.
루트해시가 만들어지는 원리
루트해시가 만들어지는 원리를 순서대로 설명드리자면:
-
블록에 거래기록(Tx0, Tx1, Tx2, Tx3)이 있다.
-
각 거래기록은 해싱을 통해 각각의 해시값을 구한다(Tx0 → Hash0, Tx1 → Hash0…).
-
인접한 거래의 해시(Hash0, Hash1)끼리 짝을 지어 다시 해싱하여 해시값(Hash01)을 구한다.
-
해시값이 하나만 남을 때까지 반복한다.
-
이렇게 남은 최종 해시값이 루트해시가 된다.
이렇게 루트해시만 남게 되면, 루트해시를 산출하기 위해 있었던 이전 데이터들은 삭제가 되어도 문제가 되지 않습니다.
쉽게 표현하자면 만약 루트해시 값이 3이라면(실제로는 긴 문자열입니다.),
3을 구하는 과정이 1+2=3 이었든 0+3=3 이었든 상관없다는 겁니다.
블록 해시를 구성하기 위해 쓰는 데이터는 3이라는 결과값 뿐이거든요.
거래 기록이 없는 블록(루트해시만 있는 블록)의 용량은 80bytes쯤 됩니다.
블록이 매 10분마다 만들어지는 것을 가정했을 때, 1년에 4.2MB의 저장 공간만 필요한 셈입니다.
무어의 법칙(Moore’s Law)에 따라 매년 1.2GB의 용량 증가가 예상되므로, 용량은 문제가 되지 않을 겁니다.
아마 ‘풀 노드’, ‘라이트 노드’에 대한 얘기를 많이 들어보셨을 겁니다.
풀 노드는 장부 구성에 필요한 모든 정보를,
라이트 노드는 그 요약본-블록 전체의 요약본인 블록헤더 사본(a copy of block headers)-을 들고 있는 노드라고
간략하게 설명할 수 있을 것 같습니다.
아시다시피 노드들은 블록체인 기록을 보유하고, 블록을 생성하고, 블록에 포함된 거래를 검증하는 역할을 수행합니다.
라이트 노드는 여기서 블록에 포함된 거래를 검증(verify payments)하는 역할만을 수행합니다.
새로운 거래가 발생하기 위해선 이전에 발생한 거래를 참조해야 합니다.
이전에 누군가가 나에게 보낸 비트코인을 내가 사용하는 것이기 때문이죠.
이를 염두에 두고 라이트 노드가 거래를 검증하는 방식을 살펴보겠습니다:
라이트 노드 거래 검증하는 방식
-
새롭게 생성된 거래가 사용하고자 하는 이전 거래(그림의 Tx3)의 정보를 받아온다.
-
풀 노드로부터 이전 거래가 포함된 블록의 머클루트 해시를 구하는데 필요한 머클트리의 해시들(Hash2, Hash23, Hash01)을 받아온다.
-
이전 거래의 해시를 받아 온 해시들과 해싱을 반복하여 머클루트 해시까지 도달한다.
-
(풀 노드의 도움으로) 계산한 머클루트의 해시와, (라이트 노드가 보유하고 있는) 블록 헤더에 있는 머클루트 해시를 비교해서 일치하면 검증을 끝낸다.
이처럼 블록 헤더만 보유하고 있는 라이트 노드가 거래를 검증하는 과정을 Simplified Payment Verification(SPV)라 부르며,
해당 기술을 통해 누구라도 용량이나 연산력에 대한 부담 없이 블록체인 유지에 기여할 수 있습니다.
이처럼 라이트 노드는 SPV를 위해 풀 노드로부터 머클 트리의 정보를 받아오는데요.
만약에 그 풀 노드가 악의를 갖고 잘못된 정보를 보낸다면 어떻게 될까요?
라이트 노드는 자체적으로 거래를 검증할 수는 없기 때문에 악의를 가진 풀 노드에 의해 영향을 받을 수 있습니다.
이를 방지하기 위해, 네트워크 노드(노드의 모든 기능을 갖춘 노드)는 비정상 블록(an invalid block)을 감지할 경우
라이트 노드가 정상적인 블록 전체를 다운 받도록 하고, 문제가 생긴 거래에 대해 검증을 하도록 합니다(confirm the inconsistency).
3. UTXO 개념 및 보안
앞에서 우리는 거래가 생성되어 노드에 전파되고, PoW를 통해 블록이 생성되면 체인에 연결된다는 큰 흐름을 이해했습니다.
이번엔 이러한 과정의 시작이 되는 거래(transaction)의 특징에 대해 설명드리도록 하겠습니다.
잔고는 수많은 거래들의 결과(transaction’s history)입니다.
은행에선 이 ‘잔고’를 이용해 거래를 수행합니다.
거래 발생 시 잔고를 가감하여 그 결과를 기록하게 되는 것이죠.
은행의 장부는 단일 주체에 의해 기록되고 작성된 것이기 때문에 거래 내역을 검증할 필요도 없고,
필요하더라도 신속하게 처리할 수 있습니다.
내가 기록한 가계부를 내가 의심하면서 들여볼 필요는 없다는 거죠.
그런데 블록체인이 만약 ‘잔고’를 블록으로 생성한다면 어떻게 될까요?
잔고는 계좌 당 하나씩 존재하기 때문에 계좌가 많아질수록 블록에 기록해야 할 정보가 지나치게 많아질 겁니다.
그러면 장부의 크기는 기하급수적으로 커질 것이고, 노드들은 비용을 감당하기 위해 수수료를 올리고, 결국 네트워크는 파국을 맞이하겠죠.
그래서 비트코인 네트워크는 잔고가 아닌 ‘거래’에 집중합니다.
비트코인에서 지불이란 거래 기록에 소유권의 상태를 기록하는 것을 의미합니다.
여기서 사용되지 않은 거래, UTXO(Unspent Transactions Outputs)라는 개념이 등장합니다.
UTXO란
비트코인 거래 기록은 입력값과 출력값들(multiple inputs and outputs)로 구성되어 있습니다. A가 B에게 1 BTC를 보내려는 상황을 예시로 들어 설명하겠습니다:
-
A는 체인 상에 본인에게 소유권이 있는 입력값들(=잔고)을 확인합니다.
-
거래 기록에 사용하려는 입력값과 출력값 1 BTC를 기재하여 노드에게 발송합니다.
-
채굴자는 입력값과 출력값의 차액을 송금 수수료로 가져갑니다.
-
입력값은 모두 소모했으므로 더 이상 활용할 수 없어 삭제됩니다.
여기서, A가 출력값으로 보낸 1 BTC는 B입장에선 입력값으로 사용하기 전까지는 소모되지 않은 값입니다.
다시 말해, 사용되지 않은 거래, UTXO로 기록되는 거죠.
만약 B가 1 BTC를 사용하기로 한다면, 해당 UTXO도 삭제가 되고, 누군가에겐 새로운 UTXO가 만들어집니다.
만약 A가 입력값으로 받은 UTXO가 5 BTC라면요?
출력값에 B에게 보내는 1 BTC와 스스로에게 보내는 4 BTC를 입력하면 됩니다.
이처럼 합치기와 나누기(Combining and Splitting)를 반복하면서 만들어지는 UTXO를 통해
효율적으로 거래 기록을 관리하면서 지불을 이행할 수 있습니다.
잔고가 없이도 거래의 상태만으로 잔고처럼 활용할 수 있기 때문입니다.
은행과 비트코인의 개인정보 구조
전통 은행에선 ‘개인정보-제 3자-개인정보’라는 구조가 연결되어 있는 대신,
해당 정보에 대한 접근 권한을 제한함으로써 개인정보 보안을 달성합니다.
비트코인 네트워크의 경우 거래 기록이 공개되어 있는 대신,
개인정보와는 분리된 공개키(by keeping public keys anonymous)를 통해 거래를 수행함으로써
비슷한 수준의 개인정보 보안을 달성할 수 있습니다.
추가적인 보안 방법으로 여러 키(다중계정)를 만들어 거래를 진행하는 방식이 있긴 하지만,
모두 체인에 기록되기 때문에 결국 하나의 공개키로 연결되므로,
하나의 공개키를 사용하는 것과 같은 리스크에 노출되긴 합니다.
해당 챕터는 수학적인 공식이 대부분인데, 결론만 말씀드리자면:
-
q=악의를 가진 노드가 다음 블록을 찾을 확률
-
z=컨펌 수(악의를 가진 노드가 따라잡아야 할 블록의 갯수)
위와 같은 전제하에, 계산을 하면 다음과 같은 결과가 나온다는 겁니다.
위 표시한 부분의 의미하는 바는, 악의를 가진 노드가 20%의 확률로 논스를 발굴한다고 할 때,
바꾸려는 블록 이후로 11 블록 이상이 생성된 상황이라면, 공격이 성공할 가능성은 0.1% 미만이라는 겁니다.
보시다시피 가장 높은 해시를 차지하는 단일 풀은 18.92%인데, 저 풀은 수많은 채굴자들로 쪼개져 있어 사실상 단합이 불가능합니다.
만약 가능하더라도 블록이 이어지면 이어질수록 성공 확률은 낮아집니다.
만약에 공격에 성공하더라도, 본인이 갖고 있는 코인에 대해서만 조작이 가능하기 때문에 네트워크 붕괴로 겪는 손실이 더 클 것이므로,
공격 시도 자체에 대한 동기가 거의 없다고 봐야 합니다.
4. 결론
기존 전자거래는 중앙기구가 거래 당사자들의 개인정보 및 담보(신뢰)를 수집하여 당사자 간의 간접적인 신뢰를 만들었습니다.
이로 인해 전자거래 비용이 증가하고, 중앙기구의 권력이 비대해지는 결과를 낳았습니다.
전자 서명을 기반으로 한 전자 화폐는 필연적으로 이중지불 문제(double-spending)에 봉착합니다.
이를 해결하기 위해 위와 같은 중앙기구의 개입이 강제되는데,
비트코인 네트워크는 P2P 네트워크 (peer-to-peer network) 위에 작업증명(proof-of-work)을 도입하여
중앙기구 없이(without relying on trust) 이중지불 문제 해결이 가능한 솔루션을 내놨습니다.
또한, 보상체계를 통해 정직한 노드들이 대다수를 차지하도록 유도하여
악의를 가진 노드들이 장부를 악용할 수 없는 단단하고, 심플한 구조를 만들어냈다고 생각합니다.
이번 (하)편을 마지막으로 비트코인 백서 읽기를 마칩니다.