안녕하세요. 어미새입니다.


오늘은 합의 알고리즘의 등장 배경과, 비트코인 네트워크에서 사용되는 합의 알고리즘인, 작업증명(Pow)방식에 대한 개념 정리를 해보도록 하겠습니다.

 

합의 알고리즘


네트워크에 연결된 사용자는 그 누구도 신뢰할 수 없는 사용자입니다. 분산 처리 시스템 및 탈중앙화 시스템은 중앙에서 관리하는 기구나 단체가 없기 때문에 시스템 내부에서 데이터를 검증하고 관리할 수 있는 수단이나 방법이 필요합니다.

비트코인에서도 마찬가지로 어떤 트랜잭션이 발생했을 경우 해당 트랜잭션이 유효한 트랜잭션인지에 대한 합의 방법이 필요하며, 새로운 블록이 진짜인지, 가자짜인지에 대한 검증이 필요합니다.

올바른 데이터의 검증은 네트워크의 신뢰도를 향상 시키며, 신뢰도가 높은 시스템일수록 시스템의 가치는 상승하게 됩니다. 합의 알고리즘에 대해 더 자세히 알고 싶으신분은 제가 이전에 작성한 합의 알고리즘편을 참조하시길 바랍니다.

 

비트코인 시스템에서는 비잔티움 장군의 문제점 및 네트워크의 신뢰도 향상을 위해 작업증명 방식(PoW)의 합의 알고리즘을 사용하고 있습니다. 지금부터 PoW가 무엇인지에 대해 상세히 알아보도록 하겠습니다.

 

PoW(Proof-of-Work)


PoW에 대한 개념을 정리하기 위해서는 비트코인 마이닝 원리에 대한 선행학습이 필요합니다. 

마이닝(채굴)이란 일종의 수학문제를 푸는것과 같습니다. 임이의 nonce 값을 대입하여 블록 해시 결과 값을 생성하고, 생성된 결과 값이 target 보다 작을 경우 새로운 블록으로 인정받을 수 있습니다. 새로운 블록을 생성한 채굴자는 블록을 생성한 댓가로 신규로 발행되는 비트코인의 수량 및 거래 수수로를 '보상'으로 받게됩니다.

현재 시점을 기준으로 '보상'받는 금액은 1억원이 넘는 아주 큰 금액입니다. 채굴자(마이너)는 이러한 보상을 받기 위해서 수학문제를 아주 열심히 풀 수 밖에 없겠죠?

 

 

해시함수의 특징때문에 어떤 nonce 값을 대입해야 target보다 작은 블록해시 정보를 찾을 수 있을지는 알 수 없습니다. 즉 올바른 결과 값을 찾기 위해서는 nonce의 값을 0부터 1식 증가 시키면서 target 보다 작은 결과 값이 나올때까지 무한 반복 작업을 수행해야합니다.

이러한 수학문제를 풀이하는 과정을 1초에 몇번이나 수행할 수 있는지에 대한 수치 정보를 해시파워라고 표현하며, 해시파워가 높은 사용자는 더 많은 문제를 풀어낼 수 있습니다. 그리고 문제를 더 많이 풀어낼 수 있는 능력을 보유한 채굴자가 새로운 블록을 찾을 확률이 높습니다!

즉 더 많은 연산을 수행한 채굴자는 더 많은 일을 했다는 의미이며, 확률적으로 많은 문제를 풀었을 경우 블록을 찾을 확률이 높아지며, 더 많은 '보상'을 받게되는거죠!

 

그렇기 때문에 PoW를 정의할때 더 많은 일을 한 사람에게 더 많은 보상이 주어지는 방식이라고 표현 합니다.

 

Pow 장단점.


 

무한 경쟁

채굴을 통해 받을 수 있는 '보상' 금액은 커지면, 채굴자는 자연스럽게 더 많은 보상을 위해서 더 빠른 연산력을 원하게 됩니다. 예를 들어 A라는 채굴자가 '해시 파워'를 높여서 더 많은 보상을 받게되면, 채굴자 B와 C 또한 덩달아서 '해시 파워'를 높이기 시작합니다. 

왜냐구요? 보상에서 뒤쳐질 수 없기 때문이죠! 채굴자들은 더 많은 보상을 받기 위해 주변에 있는 채굴자들 보다 더 많은 문제를 풀기 원하고 이러한 문제풀이에 대한 경쟁이 계속 가열화될 수 밖에 없습니다. 그래서 PoW 합의 알고리즘을 경쟁 방식이라고 표현합니다. 

 

 

여기서 또 한가지 재미있는 사실은 경쟁이 치열해지면서 비트코인 네트워크의 전체 해시파워가 상승하게 됩니다. 즉 문제 풀이 능력이 올라갔기 때문에 '난이도'또한 상향됩니다. (난이도가 상향되지 않으면 10분에 1~2블록을 찾아내야하는 규칙이 무너지기 때문이죠!)

난이도가 상승되면, 자연스럽게 문제풀이에 필요한 연산력이 올라가고, 연산력이 올라간 만큼 컴퓨터의 전력 소모 또한 증가합니다! 과도한 전력소모는 높은 유지비용으로 변환되어, 블록체인 네트워크의 장점중 하나인 저렴한 유지비용이 무색해는 현상이 발생합니다!

 

하지만 아이러니하게도 경쟁이 심화될수록 비트코인 네트워크의 보안은 강화됩니다..

 

높은 보안력


해시 함수의 특징, 그리고 전자 서명의 개념 때문에 블록을 조작하기란 사실상 불가능에 가깝습니다. 만약 블록을 조작했다고 하더라도 해당 블록의 트랜잭션 정보가 변경되면 머클 루트의 결과 값이 변경되고, 머클 루트의 결과 값이 변경되면, 블록 해시 정보 또한 변경됩니다.

블록 해시 정보가 만약 target 보다 작은 값이라면 상관 없겠지만, target 보다 큰 결과 값이라면 다시 target 보다 작은 블록 해시 정보를 얻기 위하여 무작위로 nonce 값을 대입하여 새로운 블록 해시 정보를 얻어야만합니다.

이러한 작업을 수행하는 도중 이미 비트코인의 메인 체인은 계속해서 이어져 나가고 있을것입니다. 메인 체인 보다 더 긴 체인을 형성해야지만 조작된 블록이 포함된 체인이 메인 체인으로 인정 받을 수 있음으로 현재 생성되고 있는 메인 체인 보다 더 빠르게 블록을 생성해 나가야합니다.

경쟁이 가속화 되어 조작된 블록이 아닌 정상적인 블록을 생성하기도 어려워지는 시점에는 사실상 블록을 조작하는것이 불가능 해짐으로 보안력이 높아질 수 밖에 없는것입니다.

한줄 요약 : PoW 알고리즘에 의해 사실상 비트코인 거래 정보 조작은 불가능하다!

 

하지만!


만약에 연산력이 엄청난 진짜! 말도 안되는 울트라 슈퍼캡짱 연산력을 가진 컴퓨터가 1초에도 몇개씩의 블록을 생성할 수 있다면.. 해킹이 가능해집니다.

현재의 암호체계는 결과값을 토대로 입력값을 알 수 는 없지만, 임이의 숫자를 계속 대입하면 언젠가는 입력 값, 즉 키 정보를 알아낼 수 있습니다. 현재의 연산력으로는 100년이 넘는 긴 시간이 필요합니다.

만약 양자학 컴퓨터가 상용화 되면 현재의 암호체계가 무너진다는 의미도 이와 같은 맥락입니다. 너무 연산력이 빨라서 100년은 연산해야된다고 이야기 했던 부분이 무색해지겠죠.. 불과 몇분, 몇시간안에 풀어낸다고합니다!

 

이상 긴 글 읽어주셔서 감사합니다!

채굴(마이닝)과 관련된 연재 포스팅입니다. 혹시 이전 포스팅을 읽지 않으셨다면 이전 포스팅을 먼저 읽어보시는것을 추천드립니다.

 ● 채굴(마이닝)이란 무엇인가? (1/3)





'새로운 블록 생성'


채굴자(마이너)가 새로운 블록을 생성하고, 검증하는 과정에 소모된 자원에 대한 '보상'으로 비트코인을 지급받는 행위를 '채굴'이라고 합니다. 마이너가 새로운 블록을 생성하기 위해서는 어떤 특정한 수학문제를 풀어내야하며, 이때 수학문제의 풀이과정을 이해하기 위해서는 반드시 블록 해시 연산 과정해시 함수의 특징에 대한 사전 학습이 반드시 필요합니다.



'수학 문제란?'


도대체 어떤 수학문제를 푸는것일까요? 비트코인 플랫폼에서 채굴자(마이너)는 블록에 담길 정보 중 nonce 정보를 제외한 모든 구성 요소 정보를 미리 알 수 있습니다. 즉, 채굴자는 새로운 블록으 ㄹ생성하기 위하여 새로운 블록에 접한한 nonce 정보를 찾아야 합니다. 임이의 nonce 정보를 대입하고 출력한 '블록해시' 결과 값이 난이도(target)보다 작은 결과 값을 찾아야 하며, target보다 작은 블록 해시 결과 값을 찾았을 경우 새로운 블록이 생성될 수 있습니다.






이해를 돕기 위해 'nonce'에 임이의 결과 값을 넣어서 '블록해시'를 만드는 과정이 어떻게 진행되는지 확인해보겠습니다. 아래의 Json 데이터는 블록체인 인포 사이트를 통해 1번 블록의 정보를 찾아온 결과 값입니다. 

(https://blockchain.info/block-height/1?format=json)


{

"blocks": [

{

"hash": "00000000839a8e6886ab5951d76f411475428afc90947ee320161bbf18eb6048",

"ver": 1,

"prev_block": "000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f",

"mrkl_root": "0e3e2357e806b6cdb1f70b54c3a3a17b6714ee1f0e68bebb44a74b1efd512098",

"time": 1231469665,

"bits": 486604799,

"fee": 0,

"nonce": 2573394689,

"n_tx": 1,

"size": 215,

"block_index": 14850,

"main_chain": true,

"height": 1,

"tx": [

{

"lock_time": 0,

"ver": 1,

"size": 134,

"inputs": [{

"sequence": 4294967295,

"witness": "",

"script": "04ffff001d0104"

}],

"weight": 536,

"time": 1231469665,

"tx_index": 14854,

"vin_sz": 1,

"hash": "0e3e2357e806b6cdb1f70b54c3a3a17b6714ee1f0e68bebb44a74b1efd512098",

"vout_sz": 1,

"relayed_by": "0.0.0.0",

"out": [{

"spent": false,

"tx_index": 14854,

"type": 0,

"addr": "12c6DSiU4Rq3P4ZxziKxzrL5LmMBrzjrJX",

"value": 5000000000,

"n": 0,

"script": "410496b538e853519c726a2c91e61ec11600ae1390813a627c66fb8be7947be63c52da7589379515d4e0a604f8141781e62294721166bf621e73a82cbf2342c858eeac"

}]

}

]

}

]


위의 데이터를 토대로 nonce 정보를 제외하고 블록 헤더 결과 값을 채워 넣었을 경우 아래의 그림과 같은 형태로 데이터가 구성됩니다.



블록 해시편에서 언급한 블록 해시 연산 과정을 통해 nonce 정보에 0을 대입하여 블록 해시 결과 값을 출력해보고 이러한 과정을 총 5번 반복하여 블록 해시 결과 값이 어떻게 출력되는지 확인해보도록 하겠습니다.



위의 예제 소스를 실행 결과는 아래와 같습니다.



결과 화면을 보시면 아시겠지만, 해시 함수의 특징으로 인하여 nonce 정보가 변경될 때 마다 블록 해시 결과 값은 전혀 다른 결과 값을 가지는것을 확인할 수 있습니다.  즉, nonce 정보에 어떤 값을 입력해야 target 보다 작은 블록 해시 결과 값을 얻을 수 있을지 채굴자는 미리 예측할 수 없으며, nonce 값을 1식 증가시키면서 target보다 작은 블록 해시 결과 값을 찾아내는 연산과정을 반복해야만합니다.


수학 문제를 연산하는 과정은 생각보다 단순합니다. nonce를 0부터 대입하여 target보다 작은 블록 해시 결과 값이 도출될때까지 nonce 값을 무한정 증가 시키는 작업이며, 이러한 과정을 더 빠르게 연산할 수 있도록 CPU 채굴에서 GPU를 활용한 채굴 나아가 asis라는 채굴 전용 칩까지 등장하게 된것입니다.


어느 정도 이해가 되셨나요? 심플하게 다시 정리를 해보자면


● '채굴'은 일종의 보상의 개념이다.

● 보상을 받기 위해서는 새로운 블록을 생성하기 위하여 일종의 수학문제를 풀어야한다.

● 수학문제의 정답이 되기 위한 조건은 'target'보다 작은 블록 해시 결과 값을 가지는 블록을 찾아야한다.

● 해시함수의 특징으로 인해 'target'보다 작은 '블록해시'를 만들어내기 위한 'nonce'의 값은 절대 유추할 수 없다.


그렇다면 난이도(target)은 무엇이고, 왜 필요했을까요? 다음 포스팅에서는 난이도(target)이 무엇이고 어떻게 값을 구하는지에 대한 포스팅을 이어가도록 하겠습니다.


[참고 자료]

https://jayground8.github.io/what_is_hash_and_mining/https://bitcoinwisdom.com/bitcoin/difficultyhttp://d2.naver.com/helloworld/8237898http://coinnews.tistory.com/14http://bithumb.cafe/archives/5214https://cafe.coinbang.co.kr/bbs_detail.php?bbs_num=63&tb=board_coininfor&b_category=https://steemit.com/kr/@twinbraid/2b3hcu

'비트코인 > 마이닝 원리' 카테고리의 다른 글

채굴(마이닝)이란 무엇인가? (1/3)  (1) 2018.04.13



마이닝에 대한 이해를 하기 위해서는 블록체인의 블록 구조에 대한 개념정리가 먼저 필요합니다. 채굴에 대한 설명을 하기 앞서 비트코인의 블록체인 구조에 관한 내용을 조금 설명하고 넘어가겠습니다.



Remind


'블록'은 크게 헤더와 바디정보로 구성되어있으며, 다음 그림과 같이 버전, 이전 블록 해시, 머클 루트, 타임, 난이도 목표, 논스 정보로 구성됩니다.






1. 버전 : 해당 블록이 생성된 시점의 비트코인 소프트웨어 버전 정보입니다.

2. 이전 블록 해시 : 새로운 블록이 생성된 시점의 이전 블록 해시 정보를 참조하는 정보입니다(이 요소 정보로 인하여 블록이 체인형태로 연결될 수 있었습니다).

3. 머클 루트 : 트랜잭션의 무결성 및 블로 해시의 무결성을 검증하는 역할을 수행하며, 블록 바디에 저장된 TXID 정보를 머클 트리한 결과 값입니다.

4. 타임 : 해당 블록의 대략적인 생성 시간을 의미합니다.

5. bits : 난이도 해시 목표 값을 의미하는 지표입니다.

6. nonce : 블록을 만드는 과정에서 해시 값을 구하기 위한 재료 역할을 수행합니다.





개념만 잡자! 그래서 채굴이 뭔대?





가상화폐 열풍이 불면서 '채굴'에 대한 이야기를 많이 접하셨을거라고 생각합니다. 비트코인뿐만 아니라 암호화폐에서의 채굴(인센티브) 시스템은 아주 중요한 역할을 수행합니다. 그렇다면 도대체  '채굴'은 무엇일까요? 먼저 아래의 질문에 대한 답을 여러분들은 하실 수 있으신가요?


1.중앙에서 관리 감독하는 기관이 없는 탈 중앙화된 비트코인 네트워크에서는 도대체 누가 화폐, 즉 비트코인을 어떻게 발행할까요?

2. 블록체인 기술은 분산되고 독립적인 공통장부 관리기술입니다. 그렇다는 이야기는 누군가는 거래 기록을 기록하고, 관리해야한다는 의미이며, 도대체 누가 거래기록을 기록할까요?

3. 블록은 크게 헤더와 바디정보로 구성됩니다. 블록의 바디정보에는 다수의 거래정보가 담겨져있습니다. 그렇다면 이 블록은 누가 생성할까요?


위의 질문에 대한 답을하기 앞서 먼저 '채굴'에 대한 개념을 이해하기 아주 좋은 동영상을 찾았습니다. 대략 1분 55초 분량의 아주 짧은 영상이니 꼭 시청해 보시면 좋겠습니다. (한글 자막을 지원하니, 아래의 그림과 같이 하단에 있는 자막을 설정하시고 보시면됩니다.)






채굴이란 무엇인가?









영상을 보시고나니 어느 정도 채굴에 대한 감이 잡히셨나요? 그렇다면 채굴(마이닝)이 필요했던 이유가 무엇일까요?





채굴(마이닝)이 왜 필요했을까요?


탈 중앙화된 금융거래 시스템인 비트코인 네트워크에서는 어떤 거래가 발생하고, 발생된 거래 내역이 투명하게 네트워크를 통해 공유되어야합니다. 그렇다면 누군가는 이 거래 내역을 기록하고, 기록된 거래내역을 블록에 담아 사용자들에게 전파하는 역할을 수행해야합니다. 또한, 악의 적인 사용자에 의해 잘못된 거래 기록이 전파되는것을 방지하기 위해 작성된 블록의 유효성을 검증하는 과정이 필요합니다.


앞서 이야기한 작업들을 수행하기 위해서는 서버 자원 및 전력자원이 낭비됩니다. 그렇다면 아무런 보상 없이 이러한 일을 수행하기엔 무리가 있지 않을까요?



이러한 작업들을 참여자가 자발적으로 수행할 수 있도록 별도의 인센티브 제도가 필요했으며, 이러한 작업을 수행한 참여자에게 보상의 개념으로 비트코인을 지급함으로써 네트워크에 기여도를 높일 수 있도록 하였습니다. 그리고 이러한 보상을 우리는 '채굴'이라고 표현하고 있습니다.



이제 왜 '채굴'이 필요했는지에 대하여 이해가 되셨나요? 여기까지 설명을 들으셨다면 아래와 같은 의문점이 생기실겁니다.

1. '블록'은 수학문제를 풀어서 생성이된다. 그렇다면 수학 문제는 도대체 무엇이고 어떻게 풀어야하는가?
2. 생성된 '블록'이 진짜인지 가짜인지 누가 어떻게 판단하는가?

다음 포스팅에서 위의 질문에 대한 답과 더불어 본격적으로 블록체인 기술에 대해서 파헤쳐보는 포스팅을 이어가도록 하겠습니다.



[참고자료]


https://organicmedialab.com/2014/01/11/virtuous-cycle-of-bitcoin-mining/
https://brunch.co.kr/@bumgeunsong/41
http://www.leejungmin.org/post/2017/05/30/mastering-bitcoin/


'비트코인 > 마이닝 원리' 카테고리의 다른 글

채굴(마이닝)이란 무엇인가? (2/3)  (0) 2018.04.13

안녕하세요. 어미새입니다.


이전 포스팅에서는 머클루트는 무엇이고 어떻게 머클루트 값을 구하는지, 그리고 실제 그렇게 값이 구해지는지 검증까지 해봤습니다. 혹시 이전 글을 읽지 않으신 분은 한 번 읽어보고 오셨으면 좋겠습니다.


오늘은 비트코인의 블록 정보 중 블록의 식별자 역할을 수행하는 블록 해시에 관한 정의와, 블록 해시 값을 구하는 과정에 대해 학습하도록 하겠습니다.

블록 해시(Hash of the block)


블록 해시(Block Hash)는 블록의 식별자 역할을 수행하며, 쉽게 블록의 이름 정보라고 생각하시면 될 것 같습니다. 블록 해시는 블록 헤더 정보인 버전, 이전 블록 해시, 머클루트, 타임, bits, Nonce 정보를 모두 합산한 후 SHA256 함수를 통해 해시한 결과 값입니다. 먼저 블록의 구조를 살펴보도록 하겠습니다.






위의 그림과 같이 블록 헤더 정보는 크게 6가지로 구성되며, 블록 해시는 블록의 헤더 정보를 통해 구할 수 있습니다. 우선 블록의 상세 정보를 확인해보기 위해 이전 포스팅에서 소개해드린 '블록체인 인포' 사이트에 접속하여 가장 최근에 생성된 블록 정보를 확인해보겠습니다. (https://blockchain.info/ko)

이 글을 작성하기 시작한 시점에서 가장 최근에 생성된 블록의 높이는 #508217번째 블록입니다. 해당 블록을 선택하여 블록의 상세 정보를 확인해보겠습니다.



위의 정보를 살펴보면 타임 스탬프, Bits, 해시 난수, 이전 차단, Merkle Root 정보를 확인할 수 있습니다. 앞서 설명한 블록 해시를 구하는 공식에는 6가지 요소가 필요하나 여기에는 버전 정보가 누락되어 있습니다. 그리고 타임 스탬프 정보 또한 우리가 보기 편한 형식으로 변형되어 있습니다. 실습을 위해서는 조금더 디테일한 형태의 데이터가 필요하기때문에 블록의 모든 정보를 JSON 형태로 제공 받을 수 있는 형태로 요청해보도록 하겠습니다. 요청하는 방식은 아래의 링크와 같습니다.

(https://blockchain.info/block-height/508217?format=json)

참고로 위의 URL의 /508217? 이 부분에 숫자 부분이 블록 높이 정보입니다. 다른 블록 정보의 Json을 요청하고 싶다면 이 숫자 정보를 해당 블록의 높이 정보로 변경하여 호출하시면 되겠습니다.


Json 데이터로 확인해보니 보다 상세하게 블록 정보를 확인할 수 있었습니다.(개발자라서 그런지 Json 데이터가 더 보기 편하네요..) Json 데이터를 보시면 버전(ver), 이전 블록 해시(prev_block), 머클루트(mrkl_root), 타임(time), bits, 논스(nonce) 정보가 정확하게 출력되어 있습니다.


"ver":536870912

"prev_block":"00000000000000000060e66690d8a6646b7f8bb4aeb3fa7be258ae4011e362b5"

"mrkl_root":"98f0bb94fc154733f22ac54994e9637981900fcee8a0db7d5880b5b79ca3853d"

"time":1518070436

"bits":392292856

"nonce":2699712111



위의 정보를 이용하여 아래의 블록해시 값을 구할 수 있습니다. 그럼 바로 PHP를 활용하여 소스를 작성해보고 실행해보겠습니다.



저번 시간에도 이런 오류가 발생하였습니다.. 당황하지 않고 저번 시간에 해결했던 방법 처럼 엔디안 형태로 변행해 보았습니다. (오랜 시간 끝에 찾아낸 코드는 아래와 같습니다.)


<?
 
function SwapOrder($in){
 $Split = str_split(strrev($in));
 $x='';
 for ($i = 0; $i < count($Split); $i+=2) {
     $x .= $Split[$i+1].$Split[$i];
}
 return $x;
}

function littleEndian($value){
 return implode (unpack('H*',pack("V*",$value)));
}

function hextobin($hexstr)
{
   $n = strlen($hexstr);
   $sbin="";  
   $i=0;
   while($i<$n)
  {      
       $a =substr($hexstr,$i,2);          
       $c = pack("H*",$a);
       if ($i==0){$sbin=$c;}
       else {$sbin.=$c;}
       $i+=2;
  }
   return $sbin;
}

$ver            = 536870912;
$prev_b         = '00000000000000000060e66690d8a6646b7f8bb4aeb3fa7be258ae4011e362b5';
$mrkl_r         = '98f0bb94fc154733f22ac54994e9637981900fcee8a0db7d5880b5b79ca3853d';
$time           = 1518070436;
$bits           = 392292856;
$nonce          = 2699712111;

//1. 버전, 타임, bits, nonce 정보를 리틀 엔디안 형태로 변형.
$ver            = littleEndian($ver);
$time           = littleEndian($time);
$bits           = littleEndian($bits);
$nonce          = littleEndian($nonce);

//2. 이전 블록 해시, 머클루트 결과 값을 모두 반대 순서로 변형
$prev_b         = SwapOrder($prev_b);
$mrkl_r         = SwapOrder($mrkl_r);

//3. 블록 헤더 정보를 모두 합산(순서가 꼭 맞아야합니다.)
$header         = $ver . $prev_b . $mrkl_r . $time . $bits . $nonce;

//4. 바이너리 형태로 변형
$header_bin     = hextobin($header);

//5. SHA 형태로 변형 후 바이너리 형태로 변형
$hasing_1       = hextobin(hash('sha256', $header_bin ));

//6. SHA 형태로 변형
$hasing_2       = hash('sha256', $hasing_1);

//7. 결과를 모두 반대 순서로 변형.
$block_hash     = SwapOrder($hasing_2);

echo $block_hash;

?>



위의 코드 처럼 블록해시 정보는 블록헤더의 정보를 단순히 합산하여 해싱하는 것이 아닙니다. 버전, 타임, bits, 논스정보는 리틀 엔디안 형태로 변형 해야 하며, 이미 해싱된 머클루트와 이전 블록 해시 정보는 반대로 뒤집어 주어야합니다. 다시 정리해보면 아래의 7가지 변환 과정을 거쳐서 블록 해시 정보를 구할 수 있습니다!

  1. 버전, 타임, bits, 논스 정보는 리틀 엔디안 형태로 데이터를 변형해야 한다.

  2. 이전 블록 해시, 머클루트는 결과 값을 모두 반대 순서로 바꿔주어야 한다.

  3. 헤더 정보들을 모두 합산합니다.(이어붙이기)

  4. 합산한 헤더 정보를 바이너리 형태로 변형합니다.

  5. 다시 SHA 형태로 변형 후 바이너리 형태로 또 변형합니다.

  6. 변형한 값을 다시 SHA 형태로 변형합니다. (5~6번 과정은 합산한 정보를 2중 해싱한다고 생각하시면 됩니다.)

  7. 이렇게 얻은 결과 값을 다시 뒤집어 놓습니다.



추가적으로 저는 숫자를 문자열로 입력하는 멍청한 실수를 해서 2시간을 허비했습니다.. 개발자로써 자괴감이..

자 그럼 결과가 정상적으로 출력되는지 확인해보겠습니다.



드디어 블록해시 정보를 구할 수 있었습니다. 아래의 링크는 비트코인 블록 해싱 알고리즘에 대한 자세한 설명을 해주고 있는 사이트입니다. 꼭 접속하셔서 해당 내용 확인해보셨으면 좋겠습니다!

(https://en.bitcoin.it/wiki/Block_hashing_algorithm)


자 그럼 오늘 배운내용을 간략하게 정리를 해보겠습니다.

  1. 블록해시는 블록의 이름정보를 의미하면 해당 블록의 식별자 역할을 수행한다.

  2. 블록해시는 블록 헤더 정보를 7단계의 복잡한 과정을 통하여 구할 수 있다. (아마 인터넷상에서는 자세하게 설명할 경우 오히려 이해하기 어려울 것 같아 7가지 과정을 누락하신 것 같습니다..)


이상으로 블록 헤더의 구성요소인 머클루트를 구하는 과정, 그리고 블록의 이름정보인 블록해시를 구하는 과정까지 학습하였습니다. 아마도 이 글을 읽으시는 분들 중에서는 왜 이렇게 까지 과정에 대해서 집착하지? 라는 생각을 하실 수 있을 것 같습니다. 하지만 이 과정이 반드시 학습하는데에 큰 도움이 될것이라고 믿습니다!

이상 긴 글 읽어주셔서 감사합니다!


[참고자료]https://en.bitcoin.it/wiki/Block_hashing_algorithmhttps://steemit.com/kr/@loum/how-to-calculate-the-block-hash-in-bitcoinhttps://homoefficio.github.io/2016/01/23/BlockChain-%EA%B8%B0%EC%B4%88-%EA%B0%9C%EB%85%90/http://hanaloum.blogspot.kr/2014/06/block-1_9584.html







안녕하세요. 어미새입니다.


이더리움 백서를 쉽게 이해할 수 있도록 풀어서 설명하는 연재물을 작성하고 있습니다. 어느덧 백서의 중반부를 향해 달려가고 있습니다. 혹시 지난 포스팅을 읽지 못하셨던분들은 먼저 아래의 포스팅을 읽어보시는것을 추천드립니다.





Remind


이더리움에서 메시지는 컨트랙트에 의해 생성되며, 컨트랙트가 실행되는 과정, 그리고 그 과정에서 수수료가 소비되는 과정에 대한 내용을 다뤘습니다. (gas 기억하시죠?)

컨트랙트는 특정 조건이 맞았을때 실행되는 프로그램 코드이며, 해당 코드는 EVM 환경에서 작동됩니다. 지난 시간에서 언급되어듯이 악의적인 프로그램을 막기 위해 코드가 실행되는 바이트의 양에 따라 수수료인 gas가 소모되며, 이러한 과정의 프로세스가 어떻게 흘러가는지에 대한 설명으로 이어졌습니다.

스마트 컨트랙트 코드는 정상적으로 수행이 완료되던지, gas가 부족하여 종료되던지, 혹은 오류가 발생하는 시점에서 종료가되며, 비트코인의 부족한 상태 변화와 달리 이더리움에서는 다양한 상태 변화를 가질 수 있다는 것을 설명하였습니다. 또한, 컨트랙트 코드는 연산을 위해 스택, 메모리, 저장소에 접근할 수 있어야 하며, 블록 헤더 데이터 뿐만 아니라 특정 값이나, 메시지 발송자 및 수신되는 메시지의 데이터에 접근할 수 있으며, 결과 값으로 데이터의 바이트 배열을 반환 할 수도 있었습니다.


블록체인과 채굴(Blockchan and Mining)


[그림 - 이더리움 백서]


이더리움 블록체인은 여러면에서 비트코인 블록체인과 유사하나, 어느정도 차이점들이 있다. 이더리움과 비트코인에서의 각 블록체인 구조에 대한 주요 차이점으로는 비트코인과는 달리 이더리움 블록은 트랜잭션 리스트와 가장 최근의 상태(state) 복사본을 가지고 있다는 것이다. 그것 외에도, 두개의 다른 값 - 블록 넘버와 difficulty - 이 또한 블록내에 저장된다. 기본적인 이더리움 블록 검증 알고리즘은 다음과 같다.

이더리움의 블록체인은 비트코인 블록체인과 유사하지만 차이점이 있습니다. 이더리움과 비트코인의 블록체인 구조에 대한 주요 차이점은 이더리움의 블록에는 트랜잭션 리스트와 가장 최신의 상태(state) 복사본을 가지고 있으며, 블록 넘버difficulry 정보도 블록내에 저장됩니다.


이더리움 블록 검증 알고리즘 시나리오.


  1. 생성된 블록에 참조되는 이전 블록이 실제 존재하는 블록인지, 유효한지 확인 한다.

  2. 타음 스탬프 값이 이전 블록의 타임 스탬프 값보다 큰 값인지 확인한다, 만약 크다면 15분 이내인지 확인한다.

  3. 블록 넘버, difficulty, 트랜잭션 루트, 삼촌 루트, gas 리미트등, 기타 다양한 이더리움 로우 레벨 정보가 유효한지 확인 한다.

  4. 블록에 포함된 작업 증명이 유효한지 확인한다.

  5. S[0] 상태 정보가, 이전 블록의 마지막 상태(state)라고 가정 하고

  6. TX를 현재 블록의 n개의 트랜잭션을 가지는 리스트라고 가정했을때 0부터 n-1에 대해, S[i+1] = APPLY(S[i], TX[i])로 설정 한다. 이때 어플리케이션이 오류를 반환 하거나, 블록에서 소모된 총 gas가 GASLIMIT를 초과하면 오류를 반환 한다.

  7. 채굴자에게 지불된 보상 블록을 S[n] 추가한 후 이것을 S_FINAL이라고 했을때

  8. 상태 S_FINAL머클 트리 루트가 블록 헤더가 가지고 있는 최종 상태 루트와 같은지 검증한다. 이 값이 같으면 그 블록은 유효한 블록이며, 다른면 유효하지 않은 것으로 판단한다.


이러한 과정은 모든 상태를 각 블록에 저장해야하기때문에 매우 비효율적인 것처럼 보이지만, 효율성 측면에서는 비트코인과 비교할만 하다(즉 비슷하다는 의미인것 같습니다). 그 이유로는 상태가 트리 구조로 저장되고, 모든 블록 뒤에 트리의 작은 부분만이 변경되기 때문이다. 보통, 인접한 두개의 블록간에는 트리의 대부분의 내용이 같으며, 한 번 데이터가 저장되면 포인터(서브트리의 해쉬)를 사용하여 참조될 수 있습니다.

패트리시아 트리(Patricia tree)로 알려진 트리는 머클트리 개념을 수정하여 노드를 효율적으로 삽입하거나, 삭제할 수 있도록 도와줍니다. 또한, 모든 상태 정보가 마지막 블록에 포함되어 있기떄문에 전체 블록체인 히스토리를 모두 저장할 필요가 없으며, 이러한 방법을 만약 비트코인에 적용한다면 5~20배의 저장 공간 절약 효과가 생길것입니다.

물리적인 하드웨어 관점에서 볼 떄, 컨트랙트 코드는 "어디에서" 실행되는지에 대한 의문이 쉽게 들 수 있습니다. 그에 대한 해답은 다음과 같습니다. 컨트랙트 코드를 실행하는 프로세스는 상태 전환 함수 정의의 한 부분이고, 이것은 블록 검증 알고리즘의 부분입니다. 따라서 트랜잭션이 블록 B에 포함되면 그 트랜잭션에 의해 발생할 코드의 실행은 현재 또는 향후에 블록 B를 다운로드 하고 검증하는 모든 노드들에 의해 실행될 것입니다.


어플리케이션(Applications)


이더리움을 이용하여 제작할 수 있는 어플리케이션은 총 세 가지 카테고리의 어플리케이션으로 분류할 수 있습니다.


첫번째 카테고리는 금융 어플리케이션으로 돈과 직접적으로 연관된 컨트랙트를 계약 참여자로 하여 보다 강력하게 설정-관리하게끔하는 어플리케이션입니다. 금융 어플리케이션의 예로는 하위 화폐, 파생상품, 헷지 컨트랙트, 예금용 전자지갑, 유연장, 최종적으로는 고용계약 수준의 것들을 포함할 수 있습니다.

두번째 카테고리는 준(準) 금융 어플리케이션으로 금전이 관련되어 있지만, 상당 부분 비(非) 화폐적인 면이 존재하는 계약을 위한 어플리케이션이 이에 해당됩니다. 준 금융 어플리케이션의 예로는 어려운 연산 문제를 푸는 자에게 자동적으로 포상금이 지급되는 계약입니다.

마지막으로 온라인 투표와 분권형 버넌스(Governance)와 같이 금융과 관련성이 아예 없는 어플리케이션이 있겠습니다.


토큰 시스템(Token Systems)

블록체인토큰시스템(On-blockchain token system)은 하위 화폐(미화/금등과 연동된), 주식과 스마트 자산(Smart Property : 비트코인의 블록체인 상에서 소유권이 컨트롤/관리되는 자산), 위조 불가능한(secure unforgeable) 쿠폰, 기타 토큰 시스템(예 : 인센티브 부여를 위한 포이튼 제도)등, 다양한 형태의 거래시스템을 네트워크 상에서 구현할 수 있도록 도와주는 어플리케이션들을 갖고 있습니다. 이더리움에서 토큰 시스템은 놀랍도록 쉽게 구현할 수 있으며, 토큰 시스템을 이해하는 데에 핵심은 아래와 같습니다.

  • 모든 화폐 혹은 토큰시스템은 근본은 결국 한 가지 오퍼레이션만을 수행하는 데이터베이스이다.

  • A가 최소 x 단위의 화폐를 보유하고 있는 상태에서, A로부터 x단위의 화폐/토큰을 차감하고, 차감된 x단위의 화폐/토큰을 B에게 지급한다(A가 최종적으로 이 거래를 승인 한다).

이더리움에서 유저는 바로 위의 로직을 컨트랙트에 반영 시키기만하면 됩니다. Serpent에서 토큰 시스템을 실행하는 기본적은 코드는 아래와 같습니다.

def send(to, value):
  if self.storage[msg.sender] >= value:
      self.storage[msg.sender] = self.storage[msg.sender] - value
      self.storage[to] = self.storage[to] + value


def send(to, value) : : sender는 명시되어있지 않지만 보내는 사람이며, to는 받는 사람, value는 값이라고 생각하시면 되겠습니다.

if self.storage[msg.sender] >= value: : 만약 저장된 sender의 값이 보내고자하는 value 즉, 값보다 크거나 같으면 (보내는 수량보다 더 많은 값을 가지고 있어야한다는 의미입니다.)

self.storage[msg.sender] = self.storage[msg.sender] - value : sender의 값을 가져와 value 만큼 차감한 후 sender의 값에 저장합니다.

self.storage[to] = self.storage[to] + value : to 즉, 받는 사람의 값을 가져와 value만큼 더한 후 값을 저장합니다.


위의 코드는 본 백서에서 설명한 은행시스템의 상태변환함수(state transition function)를 아무런 가공없이 그대로적용시킨 것입니다.

토큰 시스템을 개발하기 위해서는 통화의 단위를 정의하고 배급하기 위한 최초의 작업, 또는 더 나아가 여타 컨트랙트들이 계좌의 잔금에 대한 정보 요청을 처리하기 위한 추가 코드가 더 필요할 수 있습니다. 하지만, 그 정도가 토큰 시스템을 만드는 데 필요한 전부입니다. 이론적으로, 이더리움에 기반한 하위화폐 체계로서의 토큰 시스템은 비트코인에 기반환 메타 화폐가 갖고 있지 않은 중요한 특성을 지니고 있을 수 있습니다. (거래비용을 거래 시 사용한 화폐로 직접 지불할 수 있다는 점)

컨트랙트을 집행하기 위해서는 발송인에게 지불해야하는 비용 만큼의 이더 잔고를 유지해야합니다. 그리고 컨트랙트 집행 시 수수료로 받는 내부화폐(하위화폐)를 (상시 돌아가고 있는 내부화폐-이더 거래소에서) 즉각 환전하여 이더 잔고로 충전할 수 있습니다. 컨트랙트 집행 시 수수료로 받는 내부화폐(하위화폐)를 내부화폐-이더 거래소에서 즉각 환전하여 이더 잔고로 충전할 수 있습니다. 유저들은 이더로 그들의 계좌들을 "활성화" 시켜야 하지만, 각 컨트랙트를 통해 얻어지는 만큼의 금액을 이더로 매번 환전할 수 있기 때문에, 한 번 충전도니 이더는 재사용이 가능하다고 볼 수 있습니다.


마무리


이더리움 블록체인은 여러면에서 비트코인 블록체인과 비슷하며 가장 큰 차이점은 블록에 더 많은 정보를 담을 수 있다는 점인것 같습니다. 이더리움의 블록체인은 비트코인의 블록체인과 달리 블록에 트랜잭션 리스트와 가장 최신의 상태(state) 복사본을 가지고 있다는 점이며, 추가로 블록 넘버와, difficulty 정보 또한 블록내에 저장됩니다.

블록의 유효성 검증 과정에서도 비트코인의 경우 타임 스탬프 값이 2시간 이내인지 확인했지만, 이더리움에서는 15분 이내인지 확인하는 과정이 있었습니다. 이 의미는 블록의 평균 생성 시간이 비트코인 보다 훨씬 빠르다는것을 의미합니다.

또한, 이더리움에서는 모든 상태를 각 블록에 저장해야 하기 때문에 비효율적인것처럼 보일 수 있지만, 상태가 트리 구조로 저장되고, 모든 블록 뒤에 트리의 작은 부분만이 변경되기 때문에 효율성 측면에서는 비트코인과 비슷한 수준이지만 더 많은 기능을 수행할 수 있다는 내용을 말하고 싶었던것 같습니다.


이더리움을 통해 개발 가능한 어플리케이션은 크게 3가지 카테고리로 분류할 수 있으며, 금융, 준 금융, 비 금융 어플리케이션으로 나누어 설명하고자 하였습니다. 토큰 시스템은 코인 및 토큰의 차이점에 대하여 작성한 포스팅 문서를 참조하시면 이해하시는데 더 큰 도움이 될것이라고 생각합니다.


어느덧 이더리움 백서 7편입니다. 백서의 흐름으로 이제 중반을 조금 넘은 시점입니다. 대략 11 ~ 12편 정도에서 백서의 내용이 마무리될것 같습니다. 백서의 다음 내용은 파생상품과 가치안전통화, 신원조회 / 평판 시스템(Identity and Reputation Systems), 분산형 파일 저장소(Decentralized File Storage), 탈중앙화된 자율조직(Decentralized Autonomous Organizations), 추가적인 어플리케이션들(Further Applications) 등과 같은 어플리케이션에 대한 설명이 이어집니다.

이더리움에 대한 사전지식 없이 백서를 읽고, 정리하고, 부족한 부분들은 인터넷의 자료를 통해 이해하는 방식으로 백서의 내용을 써가고 있습니다, 그렇다보니 조금 부족한면이 있습니다. 하지만 부족하더라도 이왕 시작한 포스팅 주제이니 끝까지 마무리 해보도록 하겠습니다.

설명을 조금 쉽게 풀어서 해야하는 주제들은 재 포스팅할 예정입니다. 백서편이 빨리 끝나고 조금은 쉬우면서도 재미있게 내용을 풀어보고 싶네요~ (괜히 백서부터 했나..)


이상 긴 글 읽어주셔서 감사합니다!

혹시나 이더리움 백서를 먼저 읽고 싶으신분은 아래의 링크를 통해 이더리움 백서를 먼저 확인해보시는것도 좋을것 같습니다.



[참고문헌]


https://github.com/ethereum/wiki/wiki/%5BKorean%5D-White-Paper#%EC%83%81%ED%83%9C%EB%B3%80%ED%99%98%EC%8B%9C%EC%8A%A4%ED%85%9C%EC%9C%BC%EB%A1%9C%EC%84%9C%EC%9D%98-%EB%B9%84%ED%8A%B8%EC%BD%94%EC%9D%B8bitcoin-as-a-state-transition-system

https://github.com/ethereum/wiki/wiki/White-Paper

'이더리움 > 이더리움(백서)' 카테고리의 다른 글

이더리움 백서(6편)  (0) 2018.04.12
이더리움 백서(5편)  (0) 2018.04.11
이더리움 백서(3편)  (0) 2018.04.10
이더리움 백서(2편)  (0) 2018.04.06
이더리움 백서(1편)  (0) 2018.04.06

+ Recent posts