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


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


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

블록 해시(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


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



이번 포스팅에서는 지난 시간에 이어서 블록헤더 정보인 '머클 루트'에 대해 알아보도록하겠습니다. 머클 루트의 값은 어떻게 생성되는지, 예제를 통해서 검증하는 시간을 갖도록 하겠습니다.

이번 포스팅을 이해하기 위해서는 반드시 해시 함수에 대한 개념이 필요하며, 해시 함수에 대해서 잘 모르시는 분은 아래의 링크를 통해 먼저 해시 함수에 관한 내용을 읽어보시길 바랍니다.



'머클트리(Merkle Tree)' 와 '머클루트(Merkle Root)'


'머클트리(Merkle Tree)' 혹은 '해시트리(Hash Tree)'라는 데이터 구조는 Ralph Merkle이라는 사람이 1979년에 특허를 낸 개념입니다. 머클 트리의 목적은 어떤 블록의 데이터가 분리돼서 전달 될 수 있도록 하는것이며, 블록의 용량을 효율적으로 활용하수 있는 데이터 구조를 가지고 있습니다. 해시 함수의 특징으로 머클 트리 하위 노드들의 해시 값은 상위 노드에 영향을 주며, 어떤 악의적인 유저가 머클 트리 최하위에 있는 트랜잭션 정보를 가짜로 바꿔치기 하면 상위 부모들의 해시 값이 변경되고, 머클 루트 값 또한 변경됩니다. 머클 루트 정보가 변경될 경우 블록 해시 정보 또한 변경되어 해당 블록은 기존의 블록과 전혀 다른 블록으로 인식됩니다.


즉, 머클트리의 목적은 데이터의 간편하고 확실한 인증을 위해 사용합니다.


'머클루트(Merkle Root)'란 블록체인의 원소역할을 수행하는 블록의 바디부분에 저장된 트랜잭션들을 머클 트리한 최종 결과 값입니다.



블록의 구조는 크게 블록 헤더와, 블록 바디 정보로 구성되며, 블록의 바디 정보는 트랜잭션, 즉 거래 정보로 구성된다고 설명해드렸습니다. 블록의 바디 정보에 저장된 트랜잭션의 정보들이 유효한지 머클 트리를 통해 검사할 수 있습니다. 그럼 머클 트리는 어떻게 구성되고 최종적으로 머클 루트는 어떻게 만들어질까요?


머클 루트 연산 원리.


  1. 최초 데이터를 SHA256 형태의 해시값으로 변환한다.

  2. 가장 가까운 노드 2개를 한쌍으로 묶어 합친 후 해시값으로 변환한다.

  3. 계속해서 해시값으로 변환하여 마지막 하나가 남을때까지 이 과정을 반복한다.


<br/>

위의 그림처럼 각 해시된 결과값 TXID의 노드를 2개씩 짝지어 합친 후 다시 SHA256 함수를 통해 해시 값으로 변환하고 최종적으로 하나의 결과 값이 나올때 까지 이 과정을 계속해서 반복합니다. 최종적으로 남은 하나의 노드 값이 '머클루트' 결과 값이 되는겁니다!


다시 한번 정리해보면 아래와 같습니다.


  1. 블록헤더의 머클루트 값은 블록바디의 거래내역 정보인 TXID의 해시트리 결과 값이다.

  2. 머클루트의 역할은 각 거래 정보의(TXID)의 정보들이 변경되었는지에 대한 유효성을 검사하는 역할을 수행한다.

  3. 머클루트의 결과 값을 통해 블록 해시의 정보가 구성됨으로 그 블록의 유효성 또한 검사할 수 있다.

<

머클 루트 연산 과정


비트코인의 블록정보를 쉽게 볼 수 있도록 제공해주는 사이트인 '블록체인 인포' (https://blockchain.info/ko) 라는 사이트를 통해 블록 정보를 확인해보겠습니다. 제가 보고 있는 현 시점에서 블록체인 인포 사이트의 최신블록의 정보는 아래의 그림과 같이 #508186 입니다.



최신 블록인 #508186을 선택(클릭)하여 해당 블록의 정보를 자세히 살펴보겠습니다.



비트코인의 블록 정보를 확인해 볼 수 가 있습니다. 각 해당 요소들에 대한 설명에 대해서는 추후 계속적인 포스팅에 대해서 설명해 드리겠습니다. 이번 시간은 머클 루트 값을 구하는 과정을 테스트할 예정이기 때문에 다수의 거래정보가 있는 거래 리스트를 확인해 보겠습니다.



최신 블록은 위의 그림과 같이 정말 많은 거래 내역이 있기때문에, 테스트에 적합하지 않습니다. 거래 내역이 2건 내지 4건인 블록이 적당한 수치인것 같습니다. 마침 #99997번째 블록의 거래내역이 2건이기 때문에 해당 블록으로 테스트를 진행해보겠습니다. 해당 블록의 머클 루트와 거래정보는 아래의 그림과 같습니다.




블록#99997의 머클 루트는 5140e5972f672bf8e81bc189894c55a410723b095716eaeec845490aed785f0e 이며, 거래 내역은 아래의 그림과 같습니다.



그럼 이제 거래 내역의 TXID 정보를 합산한 후 SHA256으로 변환하는 코드를 짜고 그 결과 값을 확인해 보겠습니다.




결과는 위의 그림처럼.. 이상한 결과가 나오고 있습니다... 여러분은 알고 계셨나요?? 머클루트는 이렇게 구하는게 아니라는걸요??


머클루트의 결과 값을 정확하게 구하기 위해서는 엔디안이라는 개념이 필요합니다, 컴퓨터에서 어떤 크기의 데이터를 메모리에 저장할 때 바이트 단위로 나누어 저장하며, CPU 아키텍처에 따라 바이트 저장 순서가 달라질 수 있기 때문에 리틀-엔디안빅-엔디안 방식으로 나누어 질 수 있습니다.


쉽게 생각해서 앞선 TXID를 컴퓨터가 이해하기 쉬운 형태로 변환한 후, 합산해야합니다. 우선 정확하게 머클 루트를 구하는 예제 코드를 보여드리겠습니다.



위의 예제 코드의 1번의 과정처럼 문자열을 스왑해주고, 2번의 과정으로 스왑된 데이터를 바이너리로 형태로 변경해야합니다. 그리고 이렇게 만들어진 데이터 TXID 1번과, TXID 2번의 문자열을 합산하는것이 아니라 이어 붙여준 후 해시 함수를 2번 연산해 주어야합니다. 이렇게 해시 함수를 통해 얻은 결과 값을 4번과정과 같이 다시 역으로 꺼내주면 정확한 머클 루트 값을 구할 수 있습니다.


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



이렇게 해서 블록의 바디 정보인 TXID 정보를 토대로 머클 루트 결과 값을 만드는 과정을 확인해볼 수 있었습니다. 다음 포스팅에서는 비트코인의 블록헤더 정보는 무엇이고, 어떻게 값을 구하는지에 대해 알아보도록 하겠습니다.


추가로 머클 루트 구하는 방법을 테스트해보고 싶으신분은 아래의 링크를 통해 풀 코드를 확인해보시면 좋겠습니다. 해당 코드는 TXID의 양이 많더라도, 루프 문을 통하여 값을 구할 수 있도록 짜여진 코드입니다.


지금까지 긴 글 읽어주셔서 감사합니다!


[참고자료]


https://steemit.com/kr/@jayground8/hashmerkleroothttps://steemit.com/kr/@jsralph/merkle-treeshttps://steemit.com/kr/@twinbraid/5uzvbu-02http://twinbraid.blogspot.kr/2017/11/blog-post.htmlhttps://blockchain.info/ko/block/

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



비트코인의 블록체인 구조를 이해하기 위해서는 해시 함수에 대한 개념정리가 먼저 필요합니다.


해시함수

  1. 해시함수는 임이의 길이를 갖는 메시지를 입력받아 고정된 길이의 해시값을 출력하는 함수이다.

  2. 해시 함수를 사용하는 목적은 메시지의 오류나 변조를 탐기 위해, 즉 데이터의 무결성을 제공하기 위해 사용한다.


해시함수의 특징

  1. 어떤 입력 값에도 항상 고정된 길이의 해시 값을 출력한다.

  2. 입력 값의 아주 일부만 변경되어도 전혀 다른 결과 값을 출력한다.(눈사태 효과)

  3. 출력된 결과 값을 토대로 입력 값을 유추할 수 없다.

  4. 입력 값은 항상 동일한 해시 값을 출력한다.


해시 함수에 대한 보다 자세한 내용을 원하시는 분은 이전에 작선 포스팅을 참조하시면 좋을것 같습니다. (http://withbabybird.tistory.com/6)


본 포스팅에서는 비트코인의 블록체인 구성 요서에 대한 간략한 개요정도만 설명할 예정이며, 추후 각 구성요서에 대한 개별 포스팅을 진해하여 자세한 내용을 다루도록하겠습니다.


블록체인(Block-chain)


블록체인 기술은 블록과 블록을 체인형태(링크드 리스트)로 연결한 자료구조를 사용합니다. 블록체인 기술은 분산 컴퓨팅 기반의 데이터 위변조 방지 기술로써, 데이터를 '블록' 단위로 관리합니다. 블록체인 기술은 분산되고, 독립적인 데이터 관리를 가능하도록 도와주며, 네트워크에 연결된 모든 사용자들이 블록체인 데이터의 변경 결과를 열람할 수 있으며, 합이 알고리즘에 의해 새롭게 추가되는 블록의 검증이 이루어지고, 검증된 블록만들 기존의 블록체인에 연결하여 데이터 위변조를 방지할 수 있게됩니다. 즉 블록체인 기술은 분산되고 독립적인 공통 장부(원장, Ledger) 관리 기술이라고 할 수 있습니다.


비트코인 시스템은 블록체인 기술을 통해 순수하게 사용자들로만 이루어진, 그리고 조작이나 통제가 불가능한 금융 시스템을 만들 수 있게 되었습니다.


'블록(Block)'


블록은 블록체인의 원소 개념으로, 다수의 트랜잭션(거래 정보)를 가지고 있으며, 데이터 베이스(블록 체인)에 저장하기 위한 데이터 묶음(트랜잭션 묶음)이라고 생각하시면 좋을것 같습니다. 블록의 이름은 Height(높이)라는 용어로 불리며, 블록체인을 길게 이어진 수평선으로 보는 것이 아니라 한 칸 한 칸 쌓아나가 탑의 형태로 구성된다고 생각하여 Height(높이)라는 말을 쓴다고 합니다. 하지만 이 이름은 정확한 블록의 이름이 아니며, 블록의 정확한 이름은 블록의 식별자 역할을 수행하는 블록의 해시 값입니다.

비트코인 시스템에 적용된 블록체인의 '블록'은 평균 10분에 한번식 생성될 수 있도록 설게되었으며, 블록의 크기는 1MB로 약 1800 - 4200건의 거래내역을 담을 수 있습니다. 비트코인의 블록체인에 저장되는 '블록'은 크게 블록 헤더정보와, 블록 바디정보로 구분할수있습니다.

블록 헤더 : 블록 헤더는 전반적인 블록의 상태 정보를 나타내며, 버전(Version), 이전 블록 해시(Previous block hash), 머클 루트(Merkle Root), 타임(Time), 난이도 목표(bits), 논스(Nonce) 정보로 구성됩니다.

블록 바디 : 블록 바디에는 다수의 거래 정보(트랜잭션)로 구성됩니다.



'블록 해시(Hash of the block)'


블록 해시는 블록의 식별자 역할을 수행하며, 블록 헤더 정보인 버전, 이전 블록 해시, 머클 루트, 타임, bits, 논스정보를 각 표현식에 맞게 변경한 후 합산하여 SHA256 해시함수를 통해 출력된 결과 값입니다,



'버전'


비트코인 네트워크의 버전 정보를 의미합니다. 해당 블록이 생성되는 시점에서 네트워크에서 사용되었던 버전 정보를 기록합니다.


'이전 블록 해시(Previousblockhash)'


블록체인의 자료구조는 링크트 리스트 형태로 구성됩니다. 블록이 생성되는 시점에서 이전 블록의 정보를 참조하여 블록이 체인 형태로 연결될 수 있도록 도와주는 역할을 수행합니다.



위의 그림처럼 각 블록의 헤더 정보에는 이전 블록의 해시정보를 가지고 있습니다. 각 블록이 이전 블록의 해시 정보를 가지고 있기 때문에 각 블록이 서로 서로 연결되어 있는 구조가 될 수 있습니다.


'머클 루트(Merkle Root)'


'머클 루트'는 블록의 바디 부분에 저장된 트랜잭션(거래 정보) 들의 해시 트리라고 생각하시면 되겠습니다. 각 트랜잭션과 가까운 노드 끼리 쌍을 지어 해시 값을 구하여 최종적으로 구해진 해시 값이 머클루트 해시 값이 되겠습니다.

머클루트의 역할은 아래와 같습니다.

  1. '머클루트'(머클해시)값을 통해 단일 블록 내에 존재하는 트랜잭션의 무결성을 검증할 수 있다.

  2. '머클루트'(머클해시)값을 이용하여 블록의 해시 값을 생성하였기 때문에 블록의 해시의 무결성도 함께 검증할 수 있다.

쉽게 말해 해당 블록이 유효한지에 대한 무결성을 검증하기 위한 요소가 머클루트 혹은 머클해시라는 구성요소입니다.


'타임(Time)'


해당 블록의 대략적인 생성 시간을 의미합니다. 타임 스탬프는 유닉스 기준일 자로 표시되며 1970년 1월 1일 자정부터 경과한 시간을 초 단위로 계산한 값입니다.


'bits'


bits는 난이도 해시 목표 값을 의미하는 지표입니다. 이 부분에 대해서는 마이닝 즉 채굴이 어떻게 이루어지는지에 대한 포스팅에서 자세히 다루도록 하겠습니다.


'Nonce'


난스는 블록을 만드는 과정에서 해시 값을 구할 때 필요한 재료 역할을 수행합니다. 이 부분에 대해서도 채굴과 관련된 포스팅에서 자세히 다루도록 하겠습니다.


이것으로 비트코인의 블록체인 기술 및 구성요소에 대한 시간을 마치도록 하겠습니다. 각 구성요소에 대한 자세한 내용은 추후 개별 포스팅을 통해 심도있게 다루겠습니다.

긴글 읽어주셔서 정말 감사합니다!


[참고 사이트]


https://steemit.com/kr/@jsralph/merkle-trees

https://steemit.com/kr/@feyee95/1-1

https://commons.wikimedia.org/wiki/File:Bitcoin_block_structure.svghttp://hanaloum.blogspot.kr/2014/06/block-1_9584.htmlhttps://www.slideshare.net/YechanAn/blockchain-77203988http://blog.naver.com/PostView.nhn?blogId=renucs&logNo=220958282185&parentCategoryNo=&categoryNo=36&viewDate=&isShowPopularPosts=false&from=postViewhttps://homoefficio.github.io/2016/01/23/BlockChain-%EA%B8%B0%EC%B4%88-%EA%B0%9C%EB%85%90/http://privacy.jiransoft.co.kr/%EB%B9%84%ED%8A%B8%EC%BD%94%EC%9D%B8%EA%B3%BC-%EB%B8%94%EB%A1%9D%EC%B2%B4%EC%9D%B8%EA%B8%B0%EC%88%A0/https://brunch.co.kr/@ppineapple17/1


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


이전 블록체인 포스팅에서 합의 문제, 합의 알고리즘에 대해서 알아봤습니다. 블록체인에서 합의 알고리즘이란 어떤 방식으로 블록을 생성해 낼 것이며, 어떤 블록이 '진짜'인지 판별하기 위한 알고리즘이라고 설명해드렸습니다. 좀 더 구체적으로 설명을 해드리자면 블록체인을 조작할 수 없어야 하고어떤 블록이 유효한지 확인할 수 있는 메커니즘이 필요합니다. 이러한 과정을 검증하는 메커니즘이 합의 프로토콜, 합의 알고리즘이라고 생각하시면 됩니다. 또한 합의 알고리즘은두 개의 유효한 블록체인이 생성됐을 때 하나를 선택하는 방법도 필요합니다.


이번 포스팅에서는 '해시함수'란 무엇이고 블록체인에서 '해시함수'는 어떤 역할을 수행하는지에 대해 알아보도록 하겠습니다.('해시함수'의 특징 및 역할은 추후 블록 구성요소에 대해 학습하기 위해서 반드시 개념을 알고 넘어가야합니다.)


해시 함수란 무엇인가?


해시함수는 메시지의 오류나 변조를 쉽고 빠르게 탐지할 수 있습니다. 또한, 데이터의 무결성을 제공하기 위해 사용되며, 매우 빠른 데이터 검색을 위한 소프트웨어에서도 널리 사용됩니다. 비트코인에서는 SHA-256 방식의 해시 함수를 사용하고 있습니다. 해시함수는 아래와 같은 특징을 가지고 있습니다.


해시 함수의 특징


  1. 어떤 입력 값에도 항상 고정된 길이의 해시 값을 출력한다.

  2. 입력 값의 아주 일부만 변경되어도 전혀 다른 결과 값을 출력한다.(눈사태 효과)

  3. 출력된 결과 값을 토대로 입력 값을 유추할 수 없다.

  4. 입력 값은 항상 동일한 해시 값을 출력한다.


SHA(Secure Hash Algorithm)


해시(Hash)의 종류에는 MD 알고리즘 및 SHA 알고리즘이 있습니다. 이번 포스팅에서는 비트코인에서 사용되는 알고리즘인 SHA256 함수에 대해서 알아보도록 하겠습니다. SHA(Secure Hash Algorithm)알고리즘은 미국 NSA에 의해 만들어졌습니다. 160비트의 값을 생성하는 해시 함수로, MD4가 발전한 형태입니다. MD5보다 조금 느리지만 좀 더 안전한 것으로 알려져 있으며, SHA에 입력하는 데이터는 512비트 크기의 블록이며 알고리즘의 동작원리는 아래 그림과 같습니다.



SHA 알고리즘은 크게 SHA-1과 SHA-2로 나눌 수 있으며 종류에 따른 성능은 아래의 표와 같습니다.



간다한 실습을 통해 해시 함수의 특징을 이해 해보도록 하겠습니다. 먼저 아래의 사이트는 입력 값을 SHA256 방식으로 변환해주는 사이트입니다.


사이트에 접속하시면 아래의 그림과 같은 화면이 있습니다, 상단의 입력박스에 해시하고자하는 입력 값을 누른 후 파란색 버튼인 'SHA256 해시를 생성!' 버튼을 누르면 입력값을 해시 값으로 변경하여 결과 값이 출력됩니다.



위의 사이트를 활용하여 앞서 설명한 해시 함수의 특징을 살펴보겠습니다.


  1. 어떤 입력 값에도 항상 고정된 길이의 해시값을 출력한다.

위의 특징은 다시 말해서 입력 값의 길이와 상관 없이, 즉 책 한권의 분량의 데이터를 넣어도, 몇 글자 되지 않은 작을 글자를 넣어도 같은 결과가 나온다는 의미입니다. 먼저 어미새라는 짧은 문자열을 입력한 후 결과 값을 확인해 보겠습니다.



위의 그림과 같이 결과 값은 256비트(32바이트) 데이터의 길이로 결과 값이 출력되는 것을 확인 할 수 있었습니다. 그럼 이번에는 아주 긴 문자열을 넣어보도록 하겠습니다.



위의 그림과 같이 입력 값의 길이가 길어도 고정된 길이인 256비트의 길이로 결과 값이 출력되는 것을 확인할 수 있습니다. 즉 입력 길이에 상관없이 항상 고정된 문자열의 길이를 반환하는 특징을 확인할 수 있습니다. 그렇다면 이러한 특징을 어떻게 활용할 수 있을까요? 이 부분에 대한 설명을 하기 위해서는 먼저 해시 함수의 두 번째 특징인 눈사태 효과에 대한 설명이 필요합니다.


2.눈사태 효과 : 입력 값의 아주 일부만 변경되어도 전혀 다른 결과 값을 출력한다.


눈 사태 효과는, 입력 값의 아주 일부만 변경되어도 전혀 다른 결과 값을 출력하는 특징입니다. 먼저 Hello word라는 단어를 입력하고 결과 값을 출력해보겠습니다.



Hello word의 결과 값은 위의 그림과 같이 256비트의 고정된 길이의 결과 값 AEA1D1146A00E1C55E49C7837C224ECFB76CA0337FD4BB6DC09E892CA0190119이 출력되는것을 확인할 수 있었습니다. 이번에는 마지막에 s를 추가하여 Hello words를 입력하고 결과 값을 출력해보겠습니다.



Hello wordHello words는 단어 한글자 차이지만 아래처럼 전혀 다른 결과 값이 출력되는것을 확인할 수 있었습니다.

1번 결과 : AEA1D1146A00E1C55E49C7837C224ECFB76CA0337FD4BB6DC09E892CA0190119

2번 결과 : 1FCBB61355A529153565A480CA98017D9FD97DD38B0C2CBE3EA56E68F3BC8745


입력 값의 아주 일부만 변경되어도 전혀 다른 결과 값이 출력됩니다, 입력 값의 일부만 변경되었을 뿐인데 이렇게 전혀 다른 값으로 출력 된다면 출력된 결과 값을 토대로 입력값을 유추하는건 불가능할겁니다.


그럼 아주 방대한 데이터의 내용이 변경되었는지 확인하는 과정이 있다고 생각해봅시다. 데이터가 변경되었는지 한 글자 한 글자식 비교한다면 아주 오랜 시간이 소요될겁니다. 하지만 해시함수를 이용한다면 어떤 길이의 입력값이라도 256비트의 고정된 결과값을 출력할 것이고 입력값의 아주 일부만 변경되어도 전혀 다른 값이 출력되는 특징 때문에 데이터가 변경되었는지 쉽게 확인할 수 있습니다.


추가적으로 해시함수는 입력된 값이 같을 경우 항상 같은 결과 값을 출력해야합니다. 입력된 값은 같으나 다른 결과가 나온다면 데이터의 무결성을 검증할 수 없겠죠?

입력된 결과 값은 다르지만 같은 결과 값이 출력될 경우가 있습니다. (이련 경우는 아주~ 아주~~~ 희박하다고 합니다.) 입력 값이 다르지만 같은 결과 값이 출력되는 경우를 충돌이라고 표현하며, 충돌이 적은 해시함수가 좋은 해시함수가 되겠습니다.


이상으로 간단한 해시 함수의 정의와, 해시함수의 특징에 대해 알아봤습니다. 긴 글 읽어주셔서 감사합니다!



[참고 사이트]

https://blog.iwanhae.ga/introduction_of_bitcoin/

https://steemit.com/kr/@twinbraid/2b3hcu

http://www.convertstring.com/ko/Hash/SHA256

https://seed.kisa.or.kr/iwt/ko/intro/EgovHashFunction.do

+ Recent posts