이것을 해결하기 위한 방안으로 블록체인이 등장하게 되었다. 블록체인이란
암호학적 증명에 기반해, 거래하는 두 당사자가 제 3자 없이 직접 거래하게 해주는 화폐시스템이다. 블록체인은 개인 대 개인간 분산 타임스탬프 서버를 사용해 이중지불 문제를 해결한다.
"각 소유자는 화폐를 송금할 때 이전의 거래 내역 및 다음 소유자 공개키의 해시값에 전자적으로 서명을 하고 이 정보를 이 화폐의 끝에 첨가한다."
만약 사람 A에서 사람 B에게 만 원짜리 한 장이 준다고 가정하자. 그러면 A는 만 원짜리의 이전 거래 내역(=A에게 만 원이 도달한 과정)과 B의 공개키의 해시값에 자신(=A)의 개인키를 이용해 전자서명을 하고 이 값을 돈에 첨가한다. 하지만 여기에서 '이중지불' 문제가 발생할 수 있다. 예를 들자면, A가 B에게 만 원을 준다고 하고, 또 A가 C에게 똑같은 만 원을 준다고 할 수 있는 것이다. 이러한 문제는 어떻게 해결할 수 있을까?
바로 모든 거래를 인식하는 것이다. A가 B에게 만 원을 준다는 거래가 발생하고 나서, A가 C에게 똑같은 만 원을 준다는 거래를 시도한다고 가정해보자. 이 때, 만약 우리가 위의 두 거래를 다 알고 있다면, 먼저 온 거래(=A가 B에게 돈을 보내는 것)만 승인하고 나머지 거래(=A가 C에게 돈을 보내는 것)는 무시하면 된다. 이러한 방식은 타임스탬프 서버, 작업증명 등으로 구현될 수 있다.
"타임스탬프 서버는 타임스탬프가 찍힌 항목 블록의 해시를 가져가 그 해시를 신문이나 유즈넷 게시물처럼 널리 배포하는 식으로 작동한다."
2 파트에서 이중 지불 문제가 발생했을 때, 먼저 온 거래만 승인하고 나머지는 다 무시하면 된다고 했었다. 타임스탬프 서버는 각 거래가 발생한 시간을 찍어 먼저 온 것과 나중에 온 것을 구분하는 역할을 한다.
"작업증명은 기본적으로 CPU당 1표다. 다수의사는 최다 작업증명 동작이 투입된 가장 긴 사슬로 대표된다."
거래(블록)에 대한 검증을 하는 과정이다. 블록체인에서는 특정 문제를 가장 빨리 푼 사람에게 검증할 기회를 준다. 특정 문제란 x를 해시했을 때 00...으로 시작하는 출력값이 나오는 x를 구하는 것이다. 연속되는 0의 개수가 많으면 많을수록 난이도는 증가하게 되고, 더 많은 CPU 파워가 소모된다. 문제를 먼저 푼 사람은 자신의 답을 다른 모든 사용자들에게 전송하게 되고, 다른 사용자들은 그 답이 맞는지 확인한다. 만약 답이 맞다면, 문제를 푼 사람에게 검증할 기회를 준다. 검증했을 때 거래(블록)가 정당하다고 판단되면, 그 거래(블록)를 이전 거래(블록)와 연결한다. 그렇다면 어떠한 근거로 가장 긴 블록이 옳다고 할 수 있으며, 검증하는 사람(=문제를 푼 사람)이 정직하다고 할 수 있을까?
이것에 대한 답은 6. 인센티브에서 설명하겠다.
-블록: 거래의 집합들. 모든 거래를 이어붙이는 것은 힘드므로 블록에 거래를 모아놓고 블록을 연결한다.
네트워크 실행 과정은 다음과 같다.
1) 새로운 거래가 모든 노드에 브로드캐스트된다.
2) 각 노드가 새로운 거래를 블록에 수집한다.
3) 각 노드가 그 블록에 맞는 난도의 작업증명을 찾아 나선다.
4) 노드가 작업증명을 찾은 시점에, 거기서 모든 노드로 그 블록을 브로드캐스트한다.
5) 노드가 모든 거래가 유효하며 아직 지불되지 않았다는 조건에 맞을 경우에만 그 블록을 승인한다.
6) 노드는 블록 승인을 표현하기 위해 이전의 해시로 승인된 블록의 해시를 사용해 사슬 안에 다음 블록을 생성한다.
각 참여자들은 가장 긴 사슬을 정확한 것이라고 간주하고 그것을 기준으로 작업한다. 만일 두 노드가 동시에 다음 블록의 다른 버전을 브로드캐스트해도 결국 하나의 블록을 기준으로 연결한다. 사람 A는 a라는 블록을, 사람 B는 b라는 블록을 모든 다른 사람에게 전송한다고 가정해보자. 이 때, a 블록이 옳고 b 블록이 잘못된 것이라면 시간이 지나면서 결국 b 블록은 무시되고 a 블록에 대해서만 작업을 한다는 것이다.
"어떠한 근거로 검증하는 사람(=문제를 푼 사람)이 정직하다고 할 수 있을까?"
"어떠한 근거로 가장 긴 블록이 옳다고 할 수 있을까?"
인센티브란 문제를 푼 사람에게 주는 일종의 보상금으로 가상화폐로 지급된다.
1번 질문에 대한 답.
이 인센티브는 검증하는 사람이 정직하게 행동할 수 있게 해준다. 그러려면 검증하는 사람이 얻는 이득이 많아지기 위해 인센티브인 가상화폐의 가치가 계속 올라가야 하는데, 어떻게 하면 올라갈 수 있을까?
바로 네트워크 사용자가 많아지면 된다. 비트코인의 공급은 정해져 있다. 따라서 가격이 올라가려면 수요가 증가해야 한다. 수요를 늘리는 방법은 검증하는 사람이 정직하게 행동해 많은 사람이 참여하는 것 뿐이다.
2번 질문에 대한 답.
만약 탐욕스러운 공격자가 잘못된 블록을 연결한다고 가정해보자. 그 블록이 진짜인 것처럼 보이려면 다른 정직한 사람들보다 문제를 더 빨리 풀어 블록을 길게 연결해야 한다. 이는 다른 정직한 사람들의 CPU파워의 합보다 강해야 한다는 것이다. 최소 전체 CPU 파워 중 51%를 차지하고 있어야 하는데 네트워크에 참여하는 사람은 상당히 많으므로 사실상 불가능하다.
거래가 많아서 저장할 공간 (디스크 공간)이 부족해지면 공간 절약을 위해 거래가 폐기될 수 있다. 이를 방지하기 위해 거래는 머클트리로 해시되며, 그 루트만 블록의 해시 안에 포함된다.
머클트리란 이진트리 형태로 거래를 두 개씩 묶는 것이다. 이렇게 거래를 두 개씩 묶어놓으면 나중에 찾을 때 쉽게 찾을 수 있다. (tree가 균형을 이루고 있으면 logN만큼 걸린다.)
특정 결제가 있다는 것을 어떻게 확인할 수 있을까?
먼저 사용자는 가장 긴 사슬을 가졌다고 확신할 때까지 네트워크 노드를 조회한다. 왜냐하면 가장 긴 사슬이 가장 정확하기 때문이다. 그 다음 거래 일시와 블록의 타임스탬프가 일치하는 블록을 찾은 뒤, 머클 트리에서 찾으면 된다. 하지만 네트워크를 공격자가 과점한다면 그가 조작한 거래에 속을 수 있다. 이를 방지하기 위한 한 방법으로는 네트워크 노드가 유효하지 않은 블록을 탐지해 그 경고를 받을 때, 사용자의 소프트웨어가 그 온전한 블록을 내려받게 하고 경고된 거래에 그 모순을 확인하는 것이 있다.
"화폐를 독립적으로 다루는 것은 가능하더라도, 송금에 모든 푼돈을 별도 거래로 만드는 것은 무리한 일이다. 가치를 나누고 합칠 수 있도록, 거래는 복수의 입출금을 포함한다."
구체적인 설명은 https://brownbears.tistory.com/382 참고하면 된다.
어떻게 하면 누가 누구에게 돈을 보내는지를 모르게 할 수 있을까?
바로 공개키 익명성을 보존하는 것이다. 이렇게 하면 모든 사람들은 누군가가 다른 누군가에게 보내는 금액을 볼 수 있지만, 그 사람이 누구인지는 알 수 없다. 하지만 만약에 모든 입금에 같은 개인키 공개키를 사용하게 되면 그 입금들은 동일 소유자의 소유임이 드러나게 된다.