비트코인 White Paper 정독 해보기
나카모토 사토시(Satoshi Nakamoto)의 "Bitcoin : A Peer-to-Peer Electronic Cash System" 을 읽고 이를 정리해보았습니다.
아직은 영문논문을 그대로 번역하며 읽기는 무리여서 한글 번역본을 읽었습니다. 한글 번역본 링크는 아래에 적어두었습니다.
또한 저도 비트코인의 원리와 작동방식은 이전에 공부하여 알고는 있었지만 이렇게 White Paper를 직접 읽고 무슨 말인지 해석하는데 어려움이 있어서 Steem에서 저보다 먼저 White Paper를 읽고 해설해주신 분의 글을 같이 읽으며 참고하여 작성하였고 많은 도움을 얻을 수 있었습니다. 링크납깁니다.
https://steemit.com/kr/@feyee95/4grqyf
아래의 글은 White Paper를 한 문단씩 정독하며 제가 생각하는 중요한 내용을 문단 아래에 기술하였습니다.
그럼 지금부터 정독답게 서론부터 읽도록 하겠습니다.
1. 서론
인터넷 기반 상거래는 전자 결제를 처리할 신뢰받는 제3자 역할을 거의 전적으로 금융기관에 의존해 왔다. 이 시스템은 대다수 거래에 충분히 잘 동작하지만, 여전히 신뢰 기반 모델의 태생적 약점을 극복하지 못한다. 금융 기관은 분쟁 중재를 피할 수 없기에, 완전한 철회불가 거래는 실제로 가능하지 않다. 중재 비용은 거래 비용을 높이고, 실거래 최소 규모를 제한하며 소소한 일상적 거래 가능성을 가로막고, 철회불가 서비스를 위한 철회불가 결제 능력의 상실에서 더 큰 비용이 발생한다. 철회가능성을 위해 신뢰 확산이 요구된다. 상거래자 (Merchants)는 필요 수준보다 더 많은 정보를 위해 그들을 괴롭히는 고객을 경계해야 한다. 사기의 일정 비율은 불가피한 것으로 간주된다. 이런 비용과 결제 불확실성은 직접 물리적 통화(currency)를 사용시 회피될 수 있지만, 신뢰(받는 제3)자 없이 통신채널로 결제를 수행할 방법은 존재하지 않는다.
여기서는 기존의 전자결제의 문제점을 기술하고 있는데 그 내용은 "신뢰받는 제 3자 기반" 입니다. 주로 신뢰받는 제 3자의 역할을 담당하고 있는 곳은 금융기관입니다. 여기서 말하는 분쟁 중재는 거래를 진행하면서 거래자들 사이에 발생할 수 있는 분쟁들을 금융기관이 중재 해주어야 하고 중재 비용은 가령 내 계좌에서 돈을 송금하거나 인출할 때 수수료가 발생하는 내용으로 해석하였습니다. 이러한 중재 비용이 불가피 하다는 문제점 때문에 거래 비용이 증가하고 100원, 200원 같은 작은 금액은 거래하기 어렵고 불필요한 비용까지 발생할 수 있습니다.
필요한 것은 신뢰 대신 암호학적 증명(cryptographic proof)에 기반해, 거래 의사가 있는 두 당사자가 신뢰받는 제3자를 필요로 하지 않고 서로 직접 거래하게 해주는 전자 화폐 시스템이다. 전산적으로 철회가 불가능한 거래는 사기로부터 판매자를 보호하고, 통상적인 제3자 예치(escrow) 방법은 구매자를 보호하기 위해 쉽게 구현될 수 있다. 이 논문에서, 우리는 시간순으로 거래의 전산적 증거를 생성하는 개인 대 개인간 분산 타임스탬프 서버를 사용한 이중지불 문제의 솔루션을 제안한다. 이 시스템은 정직한 노드가 공격을 하려고 협력하는 노드 그룹보다 총체적으로 더 많은 CPU 파워를 통제하는 한 보안상 안전하다.
이 내용은 블록체인 기반 가상화폐(이 논문에서는 비트코인)의 필요성과 안정성 부분을 얘기하고 있습니다. 몇가지 용어에 대한 설명이 필요할 것 같아 작성합니다.
1) 에스크로
에스크로(escrow)는 상거래 시에, 판매자와 구매자의 사이에 신뢰할 수 있는 중립적인 제삼자가 중개하여 금전 또는 물품을 거래를 하도록 하는 것, 또는 그러한 서비스를 말한다. 거래의 안전성을 확보하기 위해 이용된다.
구체적으로는 판매자·구매자·제삼자의 사이에서 다음과 같은 절차로 진행된다.
1. 구매자는 제3자에게 대금을 맡긴다.
2. 판매자는 제3자에게의 입금을 확인하고 구매자에게 상품을 발송한다.
3. 구매자는 송부된 상품을 확인하고 제3자에게 상품이 도착했음을 알린다. 당초의 거래 내용과 다른 경우는, 상품을 반송하거나 거래를 파기할 수 있다.
4. 제3자는 판매자에게 대금을 송금한다.
5. 판매자는 대금을 수령한다(거래의 종료).
6. 중개하는 제3자는 일정한 수수료를 받는 것으로 수익을 얻는다.
2) P2P(Peer to Peer) 분산 네트워크 기반 타임스탬프 서버
P2P 네트워크는 중앙서버 없이 Peer들 끼리 서로 서로 데이터를 전송하는 네트워크입니다.
타임스탬프 (Timestamp)란 전자문서의 생성시점확인(존재증명) 및 진본성 확인(내용증명)을 위한 공개키 기반(PKI : Public Key Infra Structure)의 국제표준 기술이며, 전자문서가 어느 특정 시각에 존재하고 있었다는 것을 증명하는 것과 동시에, 그 시각 이후에 데이터가 변경되지 않았음을 증명하는 전자적 기술입니다.(출처 : 타임스탬프솔루션)
따라서 이 2가지를 결합한 것이 바로 P2P 분산 네트워크 서버라고 이해하면 될 것 같습니다. 즉 거래의 타임스탬프를 중앙서버 없이 P2P 네트워크에서 공유하여 이중 지불 문제를 해결하고자 한다는 내용으로 해석하였습니다.
3) 노드
노드는 이 네트워크에 참여하고 있는 Peer로 해석하였는데 자세하게는 설명하기 어려워 노드에 관한 설명을 가져왔습니다.
노드에는 풀노드와 라이트노드가 있습니다. 풀노드는 블록에 포함된 트랜잭션들과 블록전체의 정합성을 검증합니다. 이것을 통과한 블럭만 정당한 블록으로 인정하고, 로컬 데이타베이스를 업데이트하고 다른 노드로 전파시킵니다. 라이트노드는 전체 블록데이타를 검증하지도 않고, 모든 데이타를 저장하지도 않습니다. 필요한 트랜잭션 검증에 필요한 블럭헤드만 다른 외부 풀노드로 부터 받아와서 검증합니다.
풀노드 중의 일부가 블록을 생성합니다. 블록을 생성하는 풀노드는 풀노드가 하는 모든 기능 더하기, 블럭자체를 생성해서 전파하는 역할까지 하는 것입니다.
그런데 채굴풀에서 물려서 돌리는 채굴자들은 자체적인 블록검증을 하지 않기 때문에, 풀노드나 라이트노드를 돌리지 않습니다. 따라서 노드라고 부를 수 없습니다. 이 경우 채굴풀에서 돌리는 풀노드만 노드역할을 한다고 볼 수 있습니다.
출처 : http://www.chaintalk.io/archive/qna/812
2. 거래
우리는 디지털 서명의 사슬로써 전자적 화폐(electronic coin)를 정의했다. 각 소유자는 화폐를 송금할 때 먼젓번 거래 내역 및 다음 소유자 공개키의 해시값에 전자적으로 서명을 하고 이 정보를 이 화폐의 끝에 첨가한다. 수금자(payee)는 소유권(ownership)의 사슬을 검증하기 위해 해당 서명을 검증할 수 있다.
이 과정상 문제는 수금자가 소유자 가운데 누군가가 화폐를 이중지불하지 않았는지 검증할 수 없다는 점이다. 통상적인 솔루션은 신뢰받는 중앙통제기관(trusted central authority)이나 조폐국(mint)을 두고 모든 거래에서 이중지불 여부를 점검하는 것이다. 거래를 마칠 때마다 이 화폐는 조폐국으로 회수돼 새로운 화폐로 발행돼야 하고, 조폐국에서 직접 발행된 화폐만이 이중지불되지 않았다고 신뢰받는다. 이 솔루션의 문제는 전체 통화체계(the entire money system)의 운명이 은행처럼 모든 거래가 거쳐가야하는 조폐국 운영 회사에 달려 있다는 점이다.
기존 디지털 서명의 시슬로써 정의된 전자적 화폐(electronic coin)의 문제점을 담은 내용입니다. 각 화폐마다 위의 그림과 같이 소유권이 체인처럼 연결되어 있어 소유자의 개인키와 받는사람의 공개키로 거래를 만들어 소유권을 전달하는 방식으로 이해하였습니다.
이 과정에 문제가 이중 지불(Double Spending)문제인데 이를 방지하기 위해 화폐의 거래가 이루어지면 다시 중앙통제기관으로 회수되어 다시 발급되어 방지한다고 하는데 이러한 시스템은 중앙통제기관이 올바르게 존재해야 시스템이 유지되는 문제가 있습니다.
우리에게는 먼젓번 소유자가 이전에 어떤 거래에도 서명하지 않았음을 수금자에게 알릴 수단이 필요하다. 이런 목적에서 우리는 가장 앞선 거래 하나를 인정하고, 이후 이중지불 시도에는 신경쓰지 않는다. 그런 (이중 지불된) 거래가 없음을 확인할 유일한 방법은 모든 거래를 인식하고 있는 것뿐이다. 조폐국 기반 모델에서, 조폐국은 모든 거래를 인식했고 최초로 받은 거래를 (승인 대상으로) 결정했다. 신뢰받는 (제3)자 없이 이 방식을 실현하려면, 거래는 공개적으로 알려져야 하고[1], 노드들이 거래를 받는 순서의 단일 이력에 합의하는 시스템이 필요하다. 수금자는 매 거래시 그게 첫 수금이라는 것에 노드 다수가 동의했음을 증명해야 한다.
따라서 신뢰받는 제 3자(조폐국) 없이 이중 지불 문제를 해결하려면 거래는 공개적으로 알려져야 하고 노드들이 거래를 받는 순서를 단일 이력에 합의하는 시스템을 거쳐서 노드들의 동의에 의해 이력에 기록되 이중 지불 문제를 해결해야 한다고 합니다.
3. 타임스탬프(Timestamp) 서버
우리가 제안하는 솔루션은 타임스탬프 서버로 시작한다. 타임스탬프 서버는 타임스탬프가 찍힌 항목 블록의 해시를 가져가 그 해시를 신문이나 유즈넷 게시물[2-5]처럼 널리 배포하는 식으로 작동한다. 이 타임스탬프는 그 데이터가, 명백히, 해시(과정)에 들어가기 위해 해당 시각부터 존재했음을 증명한다. 각 타임스탬프는 그 해시 안에 먼젓번 타임스탬프를 포함하고, 그에 앞선 것들을 하나씩 연장하는(reinforcing the ones) 타임스탬프가 찍힌 사슬을 생성한다.
이전 타임스탬프는 이전 타임스탬프와 블록의 내용들의 해시값으로 이루어지고 계속해서 연장되어 나가는 체인으로 구성되어 있습니다. 또한, 이 내용을 모두에게 Broadcast해줍니다. 따라서 블록의 시간과 내용이 그 시간에 존재함을 말해줄 수 있고 그 값이 변경될 경우 다른 해시값이 나오기 때문에 그 값이 변경되지 않도록 Integrity을 제공해줄 수 있습니다.
4. 작업증명
개인 대 개인 기반으로 분산 타임스탬프 서버를 구현하기 위해 우리는 신문이나 유즈넷 게시물 대신 애덤 백의 해시캐시(Adam Back's Hashcash)와 유사한 작업증명 시스템[6]을 사용할 필요가 있다. 작업증명은 0비트(zero bits) 여러 개로 시작하는, SHA-256같은 해시된 값 스캐닝을 수반한다. 이에 필요한 평균 작업은 요구되는 0비트 수에 따라 지수적이며 단일 해시를 실행함으로써 확인될 수 있다. 타임스탬프 네트워크용으로, 우리는 블록의 해시에 필요한 0비트를 주는 값이 발견될 때까지 블록 안에 임시값을 증분(incrementing a nonce)하는 것으로 작업증명을 구현했다. 작업증명을 만족하는 데 한 번 CPU 동작(CPU effort)이 쓰였으면, 그 블록은 그 작업을 재수행하지 않고는 변경될 수 없다. 거기에 나중 블록이 연결되는 만큼, 블록을 변경하기 위한 재수행 작업은 그 뒤 모든 블록까지 포함한다.
작업 증명 시스템이란 Nonce(본문 내용에는 '임시값'이라고 말하였다.)값을 찾아 새로운 블록을 생성하는 작업, 즉 Mining 개념이라 생각합니다. 블록안에 담을 Transaction과 Prev Hash를 넣고 Nonce를 넣고 SHA-256 해시로 해시 값을 구하였을 때 이 값이 정해진 0bit의 수로 시작해야 합니다. 이 과정에서 CPU 자원이 소모되며 이렇게 이전 블록의 Nonce값이 포함된 블록의 내용을 계속 해시화 하여 다음 블록의 Prev Hash에 포함되고 또 다시 Nonce값을 계산하기 때문에 서로 내용이 연결되는 체인형태로 구성됩니다. 때문에 만약에 이 체인을 공격하기 위해 즉, 새로운 체인으로 교체해버리기 위해서는 공격하고자 하는 블록부터 가장 마지막 블록까지의 길이보다 1개 이상 더 긴 블록 체인을 생성하여야 합니다. 따라서 공격자는 마지막 블록까지 Nonce값을 구해 체인으로 구성하여야 하므로 정직한 Chain을 생성하는데 소요된 CPU 자원만큼 CPU 자원을 투자해야 하고 결국 정직한 체인의 길이가 길수록 체인을 공격하기 어렵습니다.
자세하게 블록이 어떠한 내용으로 구성되고 어떻게 해시화 하여 체인으로 구성되는지 쉽게 이해 하실 수 있는 참고 링크를 달아두겠습니다.
https://steemit.com/kr/@hanmomhanda/blockchain
작업증명은 다수결(majority decision making)의 대표성 문제도 해결한다. IP주소당 1표에 기반한 다수 조건이라면 누구든지 많은 IP를 할당할 수 있는 이에 의해 장악될(subverted) 수 있다. 작업증명은 기본적으로 CPU당 1표다. 다수의사는 최다 작업증명 동작이 투입된 가장 긴 사슬로 대표된다. 만일 다수 CPU 파워가 정직한 노드에 의해 통제된다면, 가장 정직한 사슬이 가장 빠르게 늘어나 다른 경쟁 사슬을 압도(outpace)할 것이다. 과거 블록을 변경하려면 공격자는 그 블록과 그 뒤를 잇는 모든 블록의 작업증명을 재수행해야 하고 그러면서 가장 정직한 노드들의 작업을 따라잡아 앞질러야 한다. 뒤에서 우리는 이어지는 블록이 추가될수록 더 느린 공격자가 따라잡을 확률이 지수적으로 감소함을 보이겠다.
시간이 지날수록 노드를 구동하는 하드웨어의 속도 증가와 변화하는 관여도(interest)를 보상하기 위해, 작업증명 난도(difficulty)는 시간당 평균 블록 수에 따른 평균 목표치를 조정해 결정된다. 그것들(블록)이 너무 빨리 생성되면 난도가 증가한다.
이 작업증명은 이 P2P 네트워크의 가장 긴 체인을 구성하고 참여하고 있는 노드들의 CPU들의 과반수에 의해 인정받게 되면 새로운 블록으로 인정받아 이 체인 네트워크에 등록되게 됩니다. IP 주소에 기반하지 않고 CPU에 기반한 것은 IP는 공격자가 여러 IP를 보유하거나 가짜 IP를 생성하여 과반수의 표를 가져갈 수 있기 때문에 위험합니다. 또한 작업증명 난이도는 블록의 생성시간과 연관되어 노드에 참여하는 하드웨어가 많아지거나 하드웨어를 제작하는 기술이 발전하여 이전 블록 생성시간이 짧으면 평균 목표치를 조정하기 위해 난이도가 증가하여 발행 속도를 조절하고 있습니다. 실제로 비트코인에서 블록 생성(새로운 비트코인 1개 발행) 시간의 평균 목표치는 10분으로 설정되어 있다고 알고 있습니다.
5. 네트워크
네트워크를 실행하는 단계는 다음과 같다:
1) 새로운 거래가 모든 노드에 브로드캐스트된다.
2) 각 노드가 새로운 거래를 블록에 수집한다.
3) 각 노드가 그 블록에 맞는 난도의 작업증명 찾기에 나선다.
4) 노드가 작업증명을 찾은 시점에, 그는 모든 노드에게 그 블록을 브로드캐스트한다.
5) 노드는 모든 거래가 유효하며 아직 지불되지 않았다는 조건에 맞을 경우에만 그 블록을 승인한다.
6) 노드는 블록 승인을 표현하기 위해 먼젓번 해시로 승인된 블록의 해시를 사용해 사슬 안에 다음 블록을
생성한다.
노드는 항상 가장 긴 사슬을 정확한 것으로 간주하고 그걸 잇는 작업을 지속한다. 만일 두 노드가 동시에 다음 블록의 상이한 버전을 브로드캐스트하면, 어떤 노드는 그 중 하나 또는 다른 것을 먼저 받을 수 있다. 이 경우 그들이 먼저 받은 것을 작업하지만, 다른 분기(branch)도 저장해 그게 더 길어질 경우에 대비한다. 이 동점(tie)은 다음 작업증명이 발견되면서 깨지고 한쪽 분기가 더 길어지며; 다른 분기를 작업하던 노드는 그 뒤 (작업 대상을) 더 긴 것으로 전환한다.
이 내용은 비트코인 네트워크에서 블록을 생성하고 체인을 잇는 작업에 대해 설명하는 내용입니다. 단계 부분의 내용을 간단하게 설명하면 새로운 거래들을 블록에 수집하고 Nonce값을 찾는 POW 과정을 거쳐 블록을 생성하면 모든 노드에게 Broadcast하여 과반수에 의해 유효한 블록으로 인정을 받게 되면 체인에 등록되고 Mining에 참가하는 다른 Node들은 만들어진 이 블록의 Hash값이 Prev Hash로 구성되는 새로운 블록을 찾는 POW과정을 진행하게 됩니다.
만약 P2P 네트워크에서 네트워크 상 가까운 주변 Node들에게 먼저 전파되고 전파 받은 Node는 또 주변에 전파하기 때문에 이 과정에서 Delay가 생겨 새롭게 등록된 블록을 인지하지 못하거나 동시에 블록이 만들어져서 Branch가 생긴 경우는 이 2개가 모두 체인에 연결됩니다. 이 후에 한 Branch의 길이가 더 길어지게 되면 다른 Branch는 사라지며 이 Branch가 정직한 체인으로 결정되어 뒤의 POW는 이 체인의 마지막 블록으로 수행되도록 진행됩니다.
새로운 거래 브로드캐스트가 반드시 모든 노드에게 도달할 필요는 없다. 브로드캐스트는 많은 노드에 도달하는만큼 곧 한 블록 안에 들어간다. 블록 브로드캐스트는 또한 누락된 메시지에 내성을 갖는다. 만일 노드가 블록을 받지 못하면 그는 다음 블록을 받을 때 누락된 것을 알아차리고 그걸 요청한다.
따라서 새로운 거래는 많은 Node에 전파될 수록 더 빠르게 블록에 등록될 수 있습니다. 또한 블록이 중간에 누락되면 다음 블록을 받을 때 누락된 부분을 요청하도록 되어있습니다.
6. 보상
관례상 블록 안의 첫 거래는 블록을 만든 이의 몫이 될 새 화폐로 시작하는 특별한 거래다. 이는 화폐를 발행하는 중앙기관 없이, 노드가 네트워크를 지원할 인센티브를 더해 주며 초기에 발행한 화폐를 유통할 방법을 제공한다. 새 화폐 일정량을 꾸준히 추가하는 것은 금 채굴자가 유통하는 금을 추가하기 위해 자원을 소비하는 것과 유사하다. 우리의 경우 소비되는 것은 CPU 시간과 전기다.
CPU resource와 전기를 투자하여 Block을 생성하는 Node들 즉, 비트코인의 채굴자(Miner)들은 블록을 성공적으로 생성할 경우 1비트코인을 보상으로 받을 수 있습니다. 생성된 비트코인은 채굴자가 등록한 지갑의 주소로 들어가게 됩니다.
이 인센티브는 또 거래 수수료(transaction fees) 재원이 될 수 있다. 만일 거래에서 도출된 가치가 투입된 가치보다 작다면, 그 차이가 거래를 포함한 블록의 인센티브 가치에 더해질 거래 수수료다. 한 번 선결된 화폐 수가 유통되면, 이 인센티브는 모두 거래 수수료로 전환돼 인플레이션에서 완전히 자유로워질 수 있다.
비트코인을 전송하기 위해서는 거래 수수료(Transaction fee)를 지불해야 합니다. 이 지불된 fee는 블록을 생성한 노드가 가져가게 됩니다. 헷갈리는 부분이 모든 Transaction들의 fee를 전부 합하여 1BTC가 Miner의 보상으로 들어가는 건지 아니면 1BTC에 추가로 fee들이 주어지는 것인지는 더 공부를 해봐야 알것 같습니다.
또 이 부분에서 중요한 내용이 2100만개의 BTC가 다 발행되고 나면 POW가 끝나는 것이 아니라 계속해서 새로운 블록은 생성되고 체인에 등록되지만 이때는 만들어 질 때마다
이 인센티브 노드들이 계속 정직하길 유도하는 데 도움을 줄 수 있다. 만일 탐욕스러운 공격자가 모든 정직한 노드보다 더 많은 CPU 파워를 모을 수 있다면, 그는 그걸 자신의 결제를 도로 훔쳐 사람들을 속이는 데 쓰는 것, 또는 새로운 화폐를 만들어내는 데 쓰는 것 사이에서 선택해야 한다. 그는 규칙대로 움직이는 게 더 이득임을 알게 돼 있는데, 규칙은 그에게 다른 모두의 몫을 합친 것보다, 시스템과 그가 보유한 부의 유효성을 해치는 것보다 더 많은 새 화폐를 베푼다.
비트코인에서 51% 공격이라는 것을 짧게 설명하는 부분인데 51% 공격이란 비트코인에서 유효한 블록의 생성은 과반수의 동의를 얻으면 유효한 블록으로 인정된다고 하였습니다. 따라서 전체 모든 노드의 컴퓨팅 자원의 51%가 조작된 거래를 옹호하는 장부를 작성하게 된다면 정당한 거래를 했던 블록이 사라지게 되는 것입니다. 따라서 장부에 기록이 남지 않으므로 그 거래는 없던 거래가 되버리는 것입니다.
하지만 이 공격은 천문학적인 비용이 요구되므로 결국 얻어지는 이익보다 투자되는 비용이 더 커지기 때문에 정직하게 채굴을 하는 것이 더 이익이라고 논문에 적혀있습니다.
51% 공격의 자세한 내용은 해당 링크에 들어가셔서 보시면 이해하시는데 많은 도움이 되리라 생각됩니다.
https://steemit.com/kr/@easyblockchain/51
7. 디스크 공간 회수
화폐 안의 최종 거래가 충분한 블록에 묻히면, 그 전에 지불된 거래는 디스크 공간을 절약하기 위해 폐기될 수 있다. 블록의 해시를 깨지 않고 이걸 촉진하기 위해, 거래는 머클트리(Merkle Tree)[7][2][5]로 해시되며, 그 루트(root)만 블록의 해시 안에 포함된다. 그러면 오래된 블록은 트리의 분기를 쳐냄으로써 작아질 수 있다. 내부 해시는 저장될 필요가 없다.
1) 머클트리(Merkle Tree)란?
https://steemit.com/kr/@twinbraid/7mxgzy-01
https://steemit.com/kr/@twinbraid/5uzvbu-02
https://steemit.com/kr/@easyblockchain/merkle-trees
위의 링크는 머클트리(Merkle Tree)를 잘 설명한 내용을 보실 수 있는 링크입니다.
머클트리(Merkle Tree)는 간단하게 설명하면 Leaf Node에서는 생성된 Transaction을 Hash화 하고 이 Hash값 2개를 1개의 Hash로 Hash화 하고 이렇게 만들어진 Hash를 2개묶어서 Hash화 하는 "역 2진트리"입니다. 이렇게 만들어진 Root를 Merkle Root라고 부르는데 이 Merkle Root는 모든 Transaction이 들어가있는 Hash값이므로 이 블록의 모든 Transaction이 변조되지 않았는지 검증할 수 있습니다. 또 특정 거래를 검증하고 싶은 경우 라이트 노드일 경우에는 전체의 거래내역을 다 검증할 필요 없이 중간 단계에 대한 단서를 요청하여 그 갈래에 대한 검색만으로 검증할 수 있게 해줍니다.
거래가 없는 블록 헤더는 약 80바이트가 된다. 블록이 10분마다 만들어진다고 가정하면, 80바이트 * 6 * 24 * 365 = 연간 4.2MB다. 2008년부터 통상적으로 판매되는 RAM 2GB짜리 컴퓨터 시스템, 그리고 현재 연간 1.2GB씩 성장을 예측하는 무어의 법칙으로 보면, 만일 블록 헤더가 메모리에 보존돼야 한다더라도 저장공간은 문제가 되지 않는다.
거래가 없는 블록 헤더라는 의미는 즉 모든 Transaction에 대한 모든 정보를 가지고 있지 않고 전체 트랜잭션의 Merkle Root만 가지고 있는 Light Node에 대한 내용으로 해석하였습니다. 이 용량은 연간 4.2MB씩 증가할 것으로 예상되므로 시스템 용량이 부족하여 발생하는 문제점은 없다고 설명합니다.
8. 간소화한 결제 검증
결제 검증은 전체 네트워크 노드를 구동하지 않고도 가능하다. 사용자는 그가 최장 작업증명 사슬을 가졌다고 확신할 때까지 네트워크 노드를 조회해, 얻을 수 있는 가장 긴 사슬의 블록 헤더 사본을 유지하면서, 해당 거래를 타임스탬프가 찍힌 블록에 연결한 머클 분기를 얻기만 하면 된다. 그는 자신의 거래를 검사할 수는 없지만 그걸 사슬 내 장소에 연결함으로써, 네트워크 노드가 그걸 받아들인 것과, 이후 그게 받아들여졌음을 확인한 뒤 추가된 블록을 볼 수 있다.
일반적으로 결제를 검증하기위해 풀노드를 전부 사용하여 검증하는 것은 많은 리소스를 필요로 하기 때문에 Mining을 하지 않는 일반 사용자들은 Lightweight Node를 주로 사용합니다. 이 Lightweight Node에서 특정 거래를 검증한다고 하였을 때 이 거래는 해싱되어 머클트리의 루트 안에 담겨져 있을 것입니다. 그럼 Lightweight Node는 현재 자신이 가지고 있는 블록 헤더의 사본이 가장 긴 체인에 연결되어 있는 것인지 확인하여 해당 블록이 문제가 없는지 확인합니다. 또 그 거래 내역이 기록된 블록의 Merkle Tree의 Branch를 풀노드에 요청하여 이 거래가 맞는 것인지, 전체 네트워크에서 승인된 것인지 확인할 수 있다는 내용입니다.
이처럼, 네트워크를 제어하는 노드가 정직한 한 검증은 믿을만하지만, 만일 네트워크가 공격자에 의해 과점 된다면 더 취약해진다. 네트워크 노드가 거래를 자체 검증할 수 있긴 하지만, 간소화한 방법은 공격자가 네트워크를 계속 과점할 수 있는 한 그가 조작한 거래에 의해 기만당할 수 있다. 이를 방어하기 위한 한가지 전략은 네트워크 노드가 유효하지 않은 블록을 탐지시 그로부터 경고를 받아, 사용자의 소프트웨어가 그 온전한 블록을 내려받게 하고 경고된 거래에 그 불일치(inconsistency)를 확인하도록 하는 것이다. 수금이 빈번한 비즈니스는 아마도 여전히 더 독립적인 보안과 더 빠른 검증을 위해 그들의 자체 노드를 구동하길 원할 것이다.
이 내용은 다시 51% 공격에 관한 내용입니다. 경고 알림 시스템은 자세하게 알지는 못하지만 아마 삭제되었다는 얘기도 본것 같습니다.
9. 가치 합치기와 나누기
화폐를 독립적으로 다루는 것은 가능하더라도, 송금에 모든 푼돈(every cent)을 별도 거래로 만드는 건 무리한 일이다. 가치를 나누고 합칠 수 있도록, 거래는 복수의 입출금을 포함한다. 일반적으로 입금은 더 큰 먼젓번 거래의 단수 입금 또는 더 작은 양을 결합한 복수 입금이며, 출금은 지불용 출금 하나와 만일 있다면 송금인(sender)에게 돌려줄 거스름돈 출금 하나, 이렇게 많아야 둘이다.
펼친 부채꼴(fan-out)처럼, 거래가 여러 거래에 의존하고 그 여러 거래가 더 많은 거래에 의존하는 것은 문제가 되지 않는다는 것에 주목해야 한다. 완전 독립된(standalone) 거래 내역 사본을 추출해야 할 필요는 전혀 없다.
푼돈을 거래로 만드는 것은 무리한 일이라는 부분은 어떤 사람에게 3BTC를 보내야 할때 1BTC씩 거래를 만들어 보내는 것이 아니라 거래 한번에 3BTC를 보낼 수 있도록 여러 입금을 한번에 담고 출금은 많아야 둘이라는 의미는 내가 3BTC를 보내야 하는 상대방의 주소와 혹시 입금된 금액이 3.5 BTC라면 0.5BTC 만큼 거슬러 받아야하기 때문에 상대방의 주소로 3BTC를 보낸다는 출금 이외에 현재 거래를 보내고 있는 내 자신의 지갑주소로 0.5 BTC를 이 거래의 출금에 추가하여야 나에게 0.5 BTC가 들어오게 됩니다.
이 부분은 비트코인이 장부를 기록하는 방식과 크게 연관되어 있는 부분이라 생각합니다. 비트코인의 특징은 UTXO 검증인데 이것에 대한 내용은 아래의 링크를 읽어보시면 이해에 많은 도움이 될 것 같아 첨부합니다.
https://steemit.com/coinkorea/@goldenman/utxo
UTXO를 정리하면 UTXO란 Unspent Transaction Output의 약어입니다. UTXO란 간단하게 설명하면 특정 Address를 소유주로 하는 기록된 금액 만큼의 한장짜리 수표라고 이해하였습니다. 하나의 지갑 안에 여러개의 Address를 가질 수 있는데 각각의 Address에는 하나 이상의 UTXO가 논리적으로 연결되어 있습니다. 따라서 지갑안에 총 잔액을 계산하면 여러개의 Address마다 이 Address를 소유주로 하는 UTXO에 기록된 코인의 합이 지갑의 총 잔액입니다.
앞서 예로든 3BTC 송금에서는 현재 Sender의 지갑에 총 3.5 BTC가 있고 이 3.5 BTC는 2개의 UTXO로 이루어져 있다고 가정하고 이 2개의 UTXO는 2BTC의 UTXO와 1.5 BTC의 UTXO가 있다고 가정할 경우 거래를 진행하면 저 2개의 UTXO는 사라지게 됩니다.
송금이 완료되면 Receiver의 지갑의 특정 Address에는 이 Address를 소유주로 하는 3 BTC의 UTXO가 연결되어 총 지갑 잔고가 3 BTC만큼 추가되고 Sebder는 0.5 BTC의 출력을 본인의 지갑의 Address로 하여 Sender의 지갑의 특정 Address에는 (0.5 - Transaction fee) BTC의 UTXO가 연결되게 됩니다. 이렇게 사실은 약간 복잡하게 하는 이유는 추적을 어느정도 피하기 위해서입니다.
10. 프라이버시
전통적인 은행 모델은 참여 당사자(the parties involved)와 신뢰받는 제3자에게 정보 접근을 제한함으로써 일정 수준 프라이버시를 달성한다. 이 방법은 모든 거래를 공개할 필요성에 따라 배제되지만, 공개키 익명성을 보존해 다른 장소에서 정보의 흐름을 끊는 걸로 여전히 프라이버시가 보장될 수 있다. 대중은 누군가가 다른 누군가에게 보내는 금액을 볼 수 있지만, 그 거래에 연결된 누군가에 대한 정보는 볼 수 없다. 이는 증권거래소에서 공개되는 정보 수준과 비슷하게, 개별 거래 시각과 규모를 나타내는 "테이프(tape)"는 공개되지만, 그 당사자가 누구인지 알지는 못하는 것이다.
전통적으로는 신뢰받는 제 3자와 거래 당사자들 이외에는 정보 접근을 제한하여 일정 수준의 프라이버시를 제공합니다. 또한 증권거래소 처럼 거래 규모와 시간은 공개하지만 거래 당사자들은 공개하지 않는 방식
비트코인 지갑도 지갑을 생성하는 과정에서 개인정보를 요구하지 않습니다. 그냥 지갑 생성 프로그램을 사용하여 Address만들고 사용하며 Address를 공개하여도 그 Address를 보고서는 누구인지 알 수 없습니다.
추가 방화벽으로, 새로운 키 쌍이 각 거래마다 공통된 소유자와 연결을 유지하도록 사용돼야 한다. 어떤 연결은 다중입력 거래시 여전히 불가피하게 그 입력이 동일 소유자의 것임을 필연적으로 드러낸다. 만일 키 소유자가 공개되면, 연결은 다른 거래도 동일 소유자에게 속하는 것임을 노출할 위험이 있다.
매번 거래시 새로운 Public Key - Private Key 쌍을 사용하더라도 여러개의 입력을 갖는 경우에는 동일 소유자임이 밝혀지는 것은 키 생성 방식이 부모 자식 관계로 이루어져 있고 이들 사이에는 연결고리가 있기 때문입니다. 이 연결고리가 밝혀지면 다른 거래에서 쓰는 새로운 주소들도 그 소유자가 동일 소유자 에 속하는 것임을 알 수 있습니다.
https://steemit.com/kr/@goldenman/hd-wallet
위의 링크는 HD Wallet을 설명한 정리글 링크입니다.
11. 계산
정직한 사슬보다 더 빨리 대체 사슬을 만들어내려는 공격자의 시나리오를 고려해 보자. 만일 이런 시도가 성공한다 하더라도, 그게 아무것도 없는 곳에서 가치를 만들어내거나 공격자가 소유한 적도 없는 돈을 얻게 만드는 식으로 이 시스템을 무단 변경되도록 허용하진 않는다. 노드는 유효하지 않은 거래를 결제로 받아들이지 않으며, 정직한 노드는 그걸 포함하는 블록을 절대 받아들이지 않는다. 공격자는 오로지 자신의 거래에서 그가 최근 지출한 돈을 거둬들이는 것 하나만을 바꿀 수 있다.
이 챕터는 앞서 말했던 블록 위변조를 위해 공격자가 변조한 블록부터 현재 가장 마지막 블록까지 생성하여 노드에 전파하는 공격방법을 수학적으로 계산하는 내용입니다. 공격자는 시스템상 소유한 적도 없는 돈을 얻게 만드는 식의 공격은 노드에서 정상적인 거래로 받아들이지 않기 때문에 자신의 거래에서 사용된 금액을 자신의 지갑으로 거두어 들이는 것 하나만 바꿀 수 있다고 합니다.
정직한 사슬과 공격자 사슬간의 경주는 이항임의보행(Binomial Random Walk)으로 특징지을 수 있다. 성공 이벤트는 정직한 사슬이 그 우위(lead)를 +1만큼 늘리는 블록 하나를 연장한 것이고, 실패 이벤트는 공격자 사슬이 그 격차를 -1만큼 좁히는 블록 하나를 연장한 것이다.
이항 임의 보행이란 정해진 2개의 방향으로 랜덤하게 이동할 때 동전 던지기처럼 시행이 많아지면 결국 제자리에 머문다는 확률 이론이다. 여기서는 사슬의 우위가 +1이면 성공, -1이면 실패로 계산하였다.
공격자가 주어진 열세를 따라잡을 확률은 도박꾼의 파산(Gambler's Ruin) 문제와 유사하다. 도박꾼이 무제한의 신용을 갖고 열세로 시작하고 손익분기(breakeven)에 도달하려는 시도를 잠재적으로 무한한 횟수에 걸쳐 시행한다고 가정해 보자. 우리는 그가 점차 손익분기에 도달할 확률, 다시말해 공격자가 정직한 사슬을 따라잡을 확률을 다음과 같이 계산할 수 있다 [8]:
p > q 라 가정하면, 공격자가 따라잡아야 하는 블록 수가 늘어날수록 그럴 수 있는 확률은 지수적으로 감소한다. 그에게 주어진 조건상, 만일 그가 초기에 운좋게 앞으로 치고나가지 못한다면, 그의 기회는 그가 뒤쳐질수록 보이지 않을만큼 작아진다.
도박꾼의 파산문제는 도박사가 계속 도박을 할 수록 파산할 가능성이 높아진다는 확률 이론입니다. 이 식에서 p가 q보다 작을 경우에는 다음 블록의 수 z와 상관없이 따라잡을 확률이 1로 항상 따라잡을 수 있다는 결론이 나옵니다. 하지만 이 경우는 모든 노드들의 컴퓨팅 자원의 51%를 가지고 POW를 해야하기 때문에 사실상 불가능 합니다.
따라서 q가 p보다 작은 상황을 보면 이 상황에서는 z가 클 수록 확률이 지수적으로 줄어들게 됩니다. 즉, 뒤의 블록이 길수록 더욱 공격자의 성공 확률이 줄어드는 것입니다.
이제 송금인이 새로운 거래를 변경할 수 없다고 충분히 확신하기 전까지 수취인(recipient)이 얼마나 오래 기다려야할지 고려해 보자. 송금인이 자신이 지불했음을 수취인으로하여금 한동안 믿게 한 다음, 시간이 좀 지나서 지불금을 회수하도록 만들려는 공격자라고 가정한다. 해당 수신자(receiver)는 그런 일이 생길 때 경고를 받겠지만, 송금인은 그게 늦기를 바란다.
Sender가 송금한 다음 그 금액을 회수하려고 하는 공격자로 가정할 때 Receiver는 해당 Transaction이 변경할 수 없을 정도로 시간이 흘러서 확증을 하게 될 때까지 걸리는 시간을 계산하는 내용입니다. 공격자 Sender가 되돌리려는 시도를 할 때 Receiver에게 경고 메시지가 가지만 공격자는 그 메시지가 최대한 느리게 가길 바랄 것입니다.
수신자는 새로운 키 쌍을 생성하고 서명 직전에 송금인에게 공개키를 준다. 이는 송금인이 운좋게 충분히 앞설 때까지 계속 그 작업을 수행함으로써 미리 블록의 사슬을 준비하지 못하게 방지하고, 그 시점에 거래를 실행한다. 거래가 한 번 발신되면, 이 부정직한(dishonest) 송금인은 몰래 그의 거래를 대신할 버전으로 사슬 작업을 병행하기 시작한다.
수신자는 해당 거래가 블록에 추가되고 그 뒤에 z블록이 연결될 때까지 기다린다. 그는 공격자가 (블록 처리를) 진척시킨 규모를 알지 못하지만, 정직한 블록이 예상되는 블록당 시간 평균치를 따른다고 가정하면, 공격자의 잠재적 진척도는 기대값을 갖는 푸아송 분포(Poisson distribution)가 될 것이다:
이 부분은 Sender가 돈을 회수하기 위해 거래가 승인되기 이전에 미리 돌려 받는 Transaction을 만들어서 가짜 체인을 생성하지 못하도록 Receiver는 새로운 암호키 쌍으로 서명하기 직전에 Sender에게 Public Key를 전달합니다. 이렇게 함으로써 미리 만들고 있던 가짜 블록체인에 Transaction을 미리 만들어서 넣을 수 없습니다.
푸아송 분포(Poisson distribution)는 어떤 사건이 발생할 기대값과 그 사건이 일어날 횟수(k)의 확률에 대한 수식입니다. 여기서는 블록당 시간 평균치 입니다.
현재 공격자가 여전히 따라잡을 수 있는 확률을 얻기 위해, 그가 해당 시점부터 따라잡을 수 있는 확률로 만들
어낼 각 진척 규모별 푸아송 밀도를 곱한다:
분모의 무한꼬리 합산을 피하도록 정리하고...
C 코드로 바꿔서…
#include <math.h>
double AttackerSuccessProbability(double q, int z)
{
double p = 1.0 - q;
double lambda = z * (q / p);
double sum = 1.0;
int i, k;
for (k = 0; k <= z; k++)
{
double poisson = exp(-lambda);
for (i = 1; i <= k; i++)
poisson *= lambda / i;
sum -= poisson * (1 - pow(q / p, z - k));
}
return sum;
}
결과를 실행하면, z 에 따라 지수적으로 감소하는 확률을 볼 수 있다.
q=0.1
z=0 P=1.0000000
z=1 P=0.2045873
z=2 P=0.0509779
z=3 P=0.0131722
z=4 P=0.0034552
z=5 P=0.0009137
z=6 P=0.0002428
z=7 P=0.0000647
z=8 P=0.0000173
z=9 P=0.0000046
z=10 P=0.0000012
q=0.3
z=0 P=1.0000000
z=5 P=0.1773523
z=10 P=0.0416605
z=15 P=0.0101008
z=20 P=0.0024804
z=25 P=0.0006132
z=30 P=0.0001522
z=35 P=0.0000379
z=40 P=0.0000095
z=45 P=0.0000024
z=50 P=0.0000006
0.1% 미만의 P 를 풀면…
P < 0.001
q=0.10 z=5
q=0.15 z=8
q=0.20 z=11
q=0.25 z=15
q=0.30 z=24
q=0.35 z=41
q=0.40 z=89
q=0.45 z=340
음... 정확한 수학적 해석은 좀 더 시간을 두고 봐야하겠지만 결국 거래 이후의 블록의 수인 z가 늘어날 수록 공격자가 성공할 확률은 기하급수적으로 줄어들게 됩니다.
12. 결론
우리는 신뢰에 의존하지 않는 전자거래용 시스템을 제안했다. 강력한 소유권 통제를 제공하는 디지털 서명으로 만든 화폐(coins made from digital signatures)의 유력한 프레임워크로 시작했지만, 이는 이중지불 방지수단 없이는 불완전하다. 이를 해결하기 위해, 우리는 정직한 노드가 CPU 파워 대부분을 제어한다면 공격자가 전산적으로 변경하기가 금세 비현실적이 되는 작업증명을 사용해 공개된 거래 이력을 기록하는 개인 대 개인 네트워크를
제안했다. 이 네트워크의 견고함은 그 정형화 하지 않은 단순성(unstructured simplicity)에 있다. 노드는 거의 조정(coordination)없이 한 번에 모두 동작한다. 이들은 메시지가 경로를 지정받아 어떤 특정 위치로 가는 게 아니라 단지 최선의 노력을 다해 전달되면 그만이기 때문에 식별될 필요가 없다. 노드는 의지에 따라, 네트워크를 떠났다가 그가 없는 동안 벌어진 일의 증거로 작업증명 사슬을 받아들여 재합류할 수 있다. 이들은 CPU 파워를 사
용한 투표로, 유효한 블록을 연장하는 작업을 통해 그걸 승인했음을 나타내고 유효하지 않은 블록에 대한 작업을 거부함으로써 그걸 기각한다. 어떤 필요 규칙과 유인이든 이 합의 작용(consensus mechanism)을 통해 집행될 수 있다.
이 부분은 한번 읽어보시면 대부분 이해가 되는 내용이라 생각합니다.
정형화 하지 않은 단순성때문에 네트워크의 견고함이 있다는 부분은 정형화 하지 않아도 될정도의 단순한 구조여서 오히려 더 믿을 수 있다는 정도로 해석하였습니다.
최선의 노력을 다해 전달되면 그만이라는 부분은 Transaction이 모든 노드에 도달할 필요 없이 가능한 많은 노드에 전달되면 된다는 내용인 것 같습니다.
마지막에 어떤 필요 규칙과 유인이든 이 합의작용을 통해 집행될 수 있다는 부분은 비트코인의 합의 메커니즘은 어떤 규칙이나 보상이 성립되게 만드는 과정을 통해 이루어질 수 있다는 내용으로 마무리됩니다.
비트코인 백서는 이렇게 마무리 짓도록 하겠습니다.
블록체인에 처음 관심을 가지게 되어 여러 세미나에 참석하여 대부분 배운 내용이지만 직접 스스로 비트코인 White Paper를 읽은것은 처음이라 생각보다 많은 시간이 걸린것 같습니다. 읽다보니 뭔가 개념이 정리된 것 같아 보람있는 시간이 되었습니다.
'블록체인 > Bitcoin' 카테고리의 다른 글
Mastering Bitcoin Ch2 내용정리 (1) | 2018.04.05 |
---|---|
Mastering Bitcoin Ch1 내용정리 (0) | 2018.04.05 |
비트코인 라이트닝 네트워크(Lightning Network) (1/2) 강의 내용정리 (0) | 2018.03.18 |
비트코인 거래와 스크립트 언어 (1) | 2018.02.19 |