반응형

이전 작업증명(PoW)에 이어, 이번에는 비트코인을 구성하는 블록체인 네트워크에 대해 공부해보도록 하자.

 

이번 글에서는, 지금까지 블록체인을 공부하면서 계속 공부했던 블록체인의 구조를 전체적으로 한번 보게될 것 같다. 

블록체인(또는 비트코인구조)에 대한 다른 기초적인 개념이 잘 탑재되어있지 않다면, 이번 장을 따라가기 힘들 수도 있다.(아닐수도 있긴 하다 ㅎ)

 

이 포스팅을 쓰기 전에, 한번 bitcoin의 오픈소스 코드를 조금 읽어보고 왔다. (트랜잭션, 블록 생성 관련 코드)

그렇게 얻은 지식들을 조금 더 공유해보고자 한다.

 

비트코인 오픈소스 깃헙 링크

https://github.com/bitcoin/bitcoin/tree/master

 

GitHub - bitcoin/bitcoin: Bitcoin Core integration/staging tree

Bitcoin Core integration/staging tree. Contribute to bitcoin/bitcoin development by creating an account on GitHub.

github.com

비트코인 네트워크가 실행되는 단계는 다음과 같다.
1) 새로운 거래(트랜잭션)가 모든 노드에 전파된다.
2) 각 노드가 새로운 거래(트랜잭션)를 블록에 수집한다.
3) 각 노드가 그 블록에 맞는 난이도의 작업증명(PoW)을 찾는다.
4) 노드가 작업증명(PoW)을 찾으면(문제를 풀면) 해당 블록을 모든 노드에 전파한다.
5) 노드는 모든 거래(트랜잭션)가 유효하며 아직 지급되지 않았을 때만(타임스탬프가 타당하면) 그 블록을 받아들인다(승인한다).
6) 노드는 블록을 받아들였음(승인했음)을 나타내기 위해 앞서 받아들인 블록의 해시를 직전 해시로 사용해 체인의 다음 블록을 생성하는 작업을 수행한다.

 

각 단계들을 천천히 살펴보자.

A가 B에게 1BTC를 송금하는 트랜잭션을 가지고 설명을 해보도록 하겠다.

bitcoin 깃헙 오픈소스의 '/primitives/transaction.h' 부분을 참고했다.

1. 새로운 거래(트랜잭션)가 모든 노드에 전파된다.

우선 한번 트랜잭션이 어떻게 생성되는지도 알아볼까?

주로 비트코인에서 트랜잭션을 생성하는 기능은 비트코인의 고수준 API나 지갑 관련 코드(bitcoin/src/wallet)에 의해 처리된다.

 

  1. 송금을 하는 A는 API가 적용된 application을 통해 송금할 금액과 수신자 주소를 지정한다. 이 정보를 바탕으로 CTxOut객체가 생성되고, CTxIn객체 이전 트랜잭션의 출력(hash값, sign 등)을 참조하여 생성된다.
  2. 지정된 In/Out을 이용하여 'CMutableTransaction'객체가 생성된다. 이 단계에서 트랜잭션에 대한 기본적인 정보들을 생성할 수 있다.
  3. 서명을 하는 단계가 수행된다. 이전 과정에서 입력으로 받은 CTxIn객체 내의 scriptSig 필드를 채우는 과정이 필요하다. (A가 해당 트랜잭션을 수행할 권한이 있음을 증명하는 단계)
  4. 이렇게 만들어진 트랜잭션을 비트코인 네트워크를 구성하는 모든 노드에 전송한다.

2. 각 노드가 새로운 거래(트랜잭션)을 블록에 수집한다.

트랜잭션과 블록의 차이를 알 필요가 있다.

 

트랜잭션: 트랜잭션은 모든 가치전송(송금 등)의 단위이다. 우리가 흔히 말하는 '블록'과는 구분되는 개념이라고 보아야 한다. 트랜잭션은 블록을 구성하는 기본 단위라고도 볼 수 있는데, 그렇다고 블록=가치전송 이다? 이런 개념은 아니다. 블록의 개념을 다시한번 살펴볼까?

 

블록: 블록은 이러한 트랜잭션들을 검증하고, 트랜잭션을 구성하는 데이터들을 저장하기 위한 개념이라고 볼 수 있다. 즉, 트랜잭션이 모여 형성된 데이터의 묶음이라고 말할 수 있다. 우리가 작업증명(PoW)등을 이용하는 것은 트랜잭션 각각에 적용하는 것이 아닌, 블록에 수행하는 것이다.

이런식으로 구성된다고 볼 수 있을것이다. 그렇기 때문에, 블록에서 트랜잭션을 수집한다고 표현한다. 다음 단계로 넘어가보자.

3. 각 노드가 그 블록에 맞는 난이도의 작업증명(PoW)를 찾는다.

이전 포스팅(4. 작업증명)을 통해 작업증명에 대한 이해를 했으면 알겠지만, 모든 블록마다 블록 생성 속도, 하드웨어 속도, 관여도 등의 변화로 인해 난이도는 자동으로(알고리즘에 따라)보정되는 과정을 거친다.

 

작업증명에 대해 설명한 링크를 올려놓겠다.

https://nullorm.tistory.com/40

 

[Bitcoin] 블록체인 기술공부 / 비트코인 백서 공부 (4. 작업증명(PoW))

지난번 포스팅에서 다뤘었다. 대체 PoW가 무엇인가!!! 작업증명이 그래서 뭔데!!! 자. 지금부터 한번 시작해보도록 하자. 라는 말을 쓰는 지금 시점에서, 나는 작업증명이 뭔지 모른다. 따라서, 이

nullorm.tistory.com

따라서, 채굴에 참여하는 모든 노드(CPU)들은 해당 블록을 구성하는 모든 트랜잭션들의 타당성을 작업증명을 통해 검증하는 과정을 거치며, 위에서 말한 "작업증명(PoW)를 찾는다"라는 워딩보다는 "작업증명(PoW)를 한다"라는 워딩을 사용하는 것이 더욱 적합할 것 같다.

 

이 과정을 통해 작업증명에 성공한 채굴자(Miner)는 채굴보상과, 거래 수수료 등을 보상으로 받게 된다. 

4) 노드가 작업증명(PoW)을 찾으면(문제를 풀면) 해당 블록을 모든 노드에 전파한다.

3번 과정을 통해 작업증명에 성공했으면, 해당 블록의 Nonce를 모든 노드에 전파하여, 모든 노드에서 해당 Nonce가 블록의 Nonce와 일치하는지를 판단하는 과정을 거친다. 

 

5) 노드는 모든 거래(트랜잭션)가 유효하며 아직 지급되지 않았을 때만(타임스탬프가 타당하면) 그 블록을 받아들인다(승인한다).

위의 문장을 세 개로 쪼개보자.

1. 모든 거래(트랜잭션)가 유효하며

작업증명(PoW)를 통해 얻은 valid한 Nonce의 타당성을 검사한다.

2. 아직 지급되지 않았을 때만

해당 블록을 구성하는 내부 트랜잭션들에 대한 이중지불 여부를 검사한다.(Timestamp 서버를 사용한다.)

3. 그 블록을 받아들인다.

그 블록이 Valid한 블록이라는 것을 네트워크에 알린다.

 

이 과정에서 블록체인의 51% 해킹이 발생할 수 있는 여지가 있다. 만약, Invalid한 Nonce에 대해 50% 이상의 노드가 동의할 경우, 해당 값이 Valid한 Nonce인 것으로 판단되어 해당 값이 approve될 수 있긴 하다.

 

이렇게 볼 수 있을 것이다. 어렵지 않으므로 넘어가보자.

6) 노드는 블록을 받아들였음(승인했음)을 나타내기 위해 앞서 받아들인 블록의 해시를 직전 해시로 사용해 체인의 다음 블록을 생성하는 작업을 수행한다.

이를 네트워크에 알리는 과정에 대한 설명이다.

5번 과정을 통해 블록을 승인했음을 블록체인 네트워크에 알리기 위해, 어떤 과정을 거치는지를 이야기한다.

워딩 그대로 해석하면 되기에, 부가적인 설명은 생략하도록 하겠다.

 

체인에 대한 이야기(+ 보안: 잘못된 블록이 들어왔을 경우)

노드는 항상 가장 긴 체인을 옳은 것으로 간주하고 그걸 잇는 작업을 지속한다. 동시에 두 노드가 다음 블록의 서로 다른 버전을 전파하면, 일부 노드가 그중 하나 또는 다른 것을 먼저 받을 수 있다. 이때 그들이 먼저 받은 것을 작업하되, 다른 분기 branch도 보관해 그쪽이 더 길어질 때를 대비한다. 이 동수(tie)는 다음 작업증명이 발견될 때 깨져 한쪽 분기가 더 길어지며, 그러면 다른 분기를 작업하던 노드가 더 긴 분기로 전환한다.

전파한 새로운 거래가 반드시 모든 노드에 도달할 필요는 없다. 많은 노드에 도달하는 한, 블록 안에 곧 들어갈 것이다. 블록 전파는 또한 메시지 누락을 허용한다. 노드가 어떤 블록을 받지 못하면 다음 블록을 받고 누락된 것을 알아차릴 때 그걸 요청한다.

 

자주 나오는 이야기이지만, 모든 노드들은 체인의 여러 분기 중에서 가장 긴 체인을 옳은 것으로 간주하도록 설계되어있다.

 

서로 다른 두 노드가 체인을 잇는 다음 블록에 대한 서로 다른 버전을 전파하였을 때, 이를 받는 노드는 이 두 블록을 모두 받을 수 있다. 이 두 블록을 받은 노드는, 그들이 먼저 받은 블록에 대한 검증을 하지만, 다른 블록 또한 reject하지 않고 저장하여 다른 branch가 더 길어질 때를 대비한다(현재 branch가 invalid한 branch일 경우를 대비).

그 다음에는 위에서 서술된 대로, 때마다 더 길어지는 branch를 찾아 타당한 branch를 찾아간다.

 

 

이번 장에서는 비트코인 네트워크에 대한 전반적인 구조를 알아보았다. 솔직한 견해로는, 다른 세부적인 내용이 궁금하지 않다면 이번 포스팅만 봐도 블록체인(또는 비트코인)의 블록, 트랜잭션 구조에 대한 전반적인 이해가 될 것이라고 생각한다.

 

다음 포스팅에서는 채굴 보상(인센티브)에 대해 알아보도록 하자.

반응형
반응형

지난번 포스팅에서 다뤘었다. 

대체 PoW가 무엇인가!!! 작업증명이 그래서 뭔데!!!

자. 지금부터 한번 시작해보도록 하자. 라는 말을 쓰는 지금 시점에서, 나는 작업증명이 뭔지 모른다.

따라서, 이 글을 읽는 사람들에게 누구보다 모르는 사람의 관점에서 잘 설명할 수 있지 않을까? (라는 희망.)

 

1. 서론

블록체인 네트워크에서 비트코인은 블록체인에 새로운 블록을 추가하는 방식으로 조폐(화폐를 제조) 및 송금을 한다.

작업증명은 이 조폐 및 송금에서 사용되는 트랜잭션(Transaction: 거래)시에 이를 거래하는 방법이다. 

나카모토 사토시의 비트코인 백서에는 이런 말이 있었다(비트코인 백서 서론)

필요한 것은 신뢰 대신 암호학적 증명(cryptographic proof)에 기반해, 거래 의사가 있는 두 당사자가 신뢰받는 제삼 자를 찾지 않고 서로 직접 거래하게 하는 전자 결제 시스템이다.

 

즉, 거래를 중개하는 중개 플랫폼(은행 등)을 신뢰해야만 개인 간의 거래가 가능했던 이전의 방식이 아닌, 암호학적 증명에 기반하겠다는 말이다. 이는 곧, 사람, 시스템을 신뢰하는 데에는 어떻게든 오류가 생길 수 있으니, 절대적인 수학을 믿겠다는 말로 들린다. 

 

2008년 글로벌 금융위기 사태 직후, 금융위기 조사위원회(FCIC)는 525페이지 분량의 보고서에 이런 말이 있다.

"당시의 위기는 인간의 행동과 무대책의 결광지, 천재지변이나 컴퓨터 모델 문제가 아니다. 셰익스피어를 인용하자면 잘못은 저 별들이 아니라 우리에게 있다." 즉, 2009년의 나카모토 사토시는 인간에 의해 만들어진 금융시스템을 신뢰하기보다는, 보다 믿을 수 있는 수학적(암호학적 증명) 방법에 기댔다고 볼 수 있겠다.

 

그렇다면, PoW는 대체 뭘까?

 

 1. PoW(Proof of Work: 작업증명)

비트코인의 전체적인 구조를 살펴보자.

자, 시장이 처음 생기면 일단 어떻게 해야하는가?

1. 화폐를 만든다(찍는다)

2. 화폐를 시장에 공급한다.

3. 시장 구성원들이 화폐와 재화를 거래하며 화폐를 거래한다.

전체적으로 보면 이러한 구조가 될 것이다. 그런데, 각각의 단계를 어떠한 주체가 담당하는지 살펴보자.

 

1. 중앙은행에서 화폐를 발행한다.

2. 은행이 시장에 화폐를 공급한다.

3. 구성원들이 화폐를 거래한다(전자화폐의 경우, 이중지불문제와 보안을 위해 은행의 중개가 필요)

결국, 모든 과정에서 은행은 필수불가결의 요소이다.

하지만, 비트코인은 무엇인가?

바로 은행이 존재하지 않는, 은행을 신뢰하지 않는, 수학을 믿는 전자화폐이다. 이러한 과정들에서, 은행을 대신할 수 있는 요소로 등장하는 것이 바로 PoW, 작업증명이다.

 

작업증명이 비트코인에서 어떠한 기능을 하는지 가볍게 일단 한번 보자.

1. 채굴자는 화폐를 발행하고 이를 시장에 공급한다.(물론 바로 공급을 하지 않을 수 있겠지만.. 이들도 돈을 벌어야지)

2. 구성원들이 화폐를 거래한다.

 

해당 두 과정이 위의 세 과정을 압축했다고 볼 수 있다. 작업증명(PoW)는 이 두 과정 모두에서 작동한다.

 

우선, 조폐(1번)의 과정에서는, 화폐 발행인(채굴자)에게 일(채굴)을 했다는 것을 증명하도록 하여 화폐를 발행한다.

중앙집권화되지 않은 탈중앙화된 블록체인의 조폐 과정에서는 처음 만들어진 알고리즘 이외에는 누가 얼마의 화폐를 받을 지 결정할 수 있는 중앙 권력이 없기 때문에 모든 참여자들이 자동으로 동의할 수 있는 방법이 필요하다.

 

그렇다면, 채굴자는 어떤 문제를, 어떤 해시함수를 계산한다는 것일까? 간단하게 그림으로 한 번 알아보자.

비트코인의 작업증명 방식을 간단하게 그림으로 나타내보았다.

우선, 작업증명은 SHA-256과 같은 해시연산을 거쳐 이루어지는데, 

과정은 이러하다.

Hash(이전 블록의 해시값 || 생성할 블록의 트랜잭션 data || 임의의 Random한 Nonce) < 목표값

을 달성할 경우, 작업증명에 성공했다고 보는 것이다.

이와 관련하여 백서에서는 어떻게 이야기하는지 살펴보자.

우리는 타임스탬프 네트워크용으로 블록의 해시에 주어진 0 비트들을 모두 발견할 때까지 블록 안에 임시값을 증가시키는(incrementing a nonce) 것으로 작업증명을 구현했다.

 

이 말이 위에서 한 말과 같은 말로 받아들이면 될 것이다.

이게 대체 뭔 과정이길래 이정도만으로도 작업증명이 된다는 것일까?

답은 바로 Hash함수의 일방향적 특성에 있다.

 

수학적(암호학적)으로, 해시(Hash)함수는 일방향함수이기 때문에, 이를 역산하는 것이 무차별 대입(Brute Force)이외에는 방법이 없다는 점에 착안하여, 모든 채굴자가 해시함수를 계산해 가장 먼저 계산한 사람이 새로 발행되는 비트코인을 받아가는 구조이다.

 

또한 작업증명(PoW)는, 다수결의 체인의 대표성을 결정하는 문제도 해결한다. 만약, 1 IP당, 1표에 기반한 다수결로 검증을 진행하게 된다면, 한번에 수많은 IP를 할당할 수 있는 누군가(악의적인 공격자)에 의해 해당 네트워크 전체가 장악될 수 있다. 위에서 소개한 다수결은 기본적으로 CPU당 1표이다. 다수결의 결과는 가장 많은 자원이 사용된 작업증명들의 가장 긴 체인이 된다(즉, Hash Rate가 가장 높은 체인이 가장 긴 체인이 된다.) 정직한 노드들에 의해 다수의 CPU파워가 통제된다면, 가장 정직한 체인이 가장 빠르게 늘어나 다른 경쟁 체인들을 압도할 것이다.

 

또한, 과거 블록을 수정하려면 공격자는 해당 과거 블록의 값에 대한 작업증명을 재수행해야하고, ( Hash(해당 블록의 이전 블록 해시 값 + 변경하고자 하는 데이터 + Nonce) 를 다시 해야함.) 또한, 해당 블록 이후의 모든 타임스탬프의 블록에 대하여 모든 연산을 재수행해야 하는 문제가 생긴다. 또한, 이러한 작업을 가장 정직한 노드들의 작업 속도를 따라잡아야 그것이 가장 무결한 노드라는 것을 인정받을 수 있다. 

따라서, 비트코인은 그 구조상 블록의 수가 늘어날수록 블록의 위/변조가능성은 거의 0에 수렴하게 된다는 것을 알 수 있다.

 

또한, 실제로 발생한 문제이기도 하지만, 채굴자들은 자원을 아끼기 위해 기존 CPU의 수만배 파워를 내는 채굴기를 개발해내었다. 이러한 상황에서 채굴의 난이도는 상대적으로 쉬워질 수 밖에 없기 떄문에, 초기 알고리즘은 채굴의 난이도 (위 그림에서는 목표 값)를 시간당 평균 블록 수에 따른 평균 목표값을 조정하여 결정하도록 하였다.

즉, 블록들이 너무 빠르게 생성된다면 채굴 난이도는 높아진다는 것이다(목표값이 낮아진다는 것이다.)

 

3. 마치며...

이렇게 작업증명에 대한 기본적인 개념들을 다루어보았다.

다소 수학적인 내용이 등장할 것이라고 예상했었지만, 해시함수 이외에는(이것도 별 수학적으로 접근하지는 않았지만...) 그런 내용은 없었던 것 같다.

작업증명(Proof of Work) 이외에도 지분증명(Proof of Stake)라는 개념이 존재하는데, 이는 나아아중에 다뤄보도록 하겠다.

 

글 읽어주셔서 감사하옵니다^^

 

반응형

+ Recent posts