Block Chain

사전 용어 정리

Block Chain

  • 말 그대로 데이터(Block)을 연결(Chain)한것
  • 구조체를 링크드리스트로 연결하는것과 유사

Hash

  • 임의의 크기를 가진 데이터(Key)를 고정된 크기의 데이터(Value)로 변화시켜 저장하는 것

  • 출력값으로 입력값을 예측할 수 없는것, 같은내용을 입력값으로 주면 결과값은 항상 같다.
  • Key가 정수일때 m으로 나눈 나머지를 Value로 취하는 것도 해시 함수라고 할 수 있다(Value의 충돌이 잦으므로 좋은 해시함수라고는 할 수 없음).

  • 해시함수 종류: HAS-160, SHA-1, SHA-256 등

Block Chain 구현

Block의 구성요소

  1. 이전 블록의 해시값
  2. 현재 블록에서 저장할 정보
  3. Nonce

Chain 구현

  1. 시작 블록(Genesis Block) 설정
  2. 이전 블록의 해시값과 현재 블록의 데이터를 해시함수에 넣어 다음 블록의 해시값을 구하는것을 반복

Python 알고리즘 - 파이썬으로 구현한 기본적인 블록체인 : A Practical Introduction to Blockchain  with Python 출처 : https://www.stechstar.com/user/zbxe/AlgorithmPython/59573

Nonce의 역할/작업 증명

단순히 이전 해시값을 해시함수에 넣어 계속 해시를 구하는 과정은 간단하기 때문에 블록들의 연결을 구현하기가 너무 쉬움(O(n))

-> 이전 블록의 해시값 끝에 데이터를 추가하고, nonce(0이상의 정수)를 추가해 만들어진 해시값의 처음 n개의 값이 0이 되게(0000ed268b…)하는 가장 작은 nonce값 채택 // 이를 작업 증명(Proof of Work)라고 함

Code

Genesis Block을 포함한 10개의 Block Chain 만들기

import hashlib

class Block:
    def __init__(self, data, prevhash, n):
        self.data = data
        self.prevhash = prevhash
        self.n = n  # 앞에 0이 몇개 나오는지

    def get_hash(self):
        nonce = 0
        if self.prevhash == None:  # 시작 블록
            self.nonce = 0
            self.hash = hashlib.sha256(self.data.encode()).hexdigest()
            return 0

        pad = '0' * self.n
        while True:
            hash = self.prevhash + str(self.data) + str(nonce)
            hash = hashlib.sha256(hash.encode()).hexdigest()
            if hash.startswith(pad):
                self.nonce = nonce
                self.hash = hash
                break
            nonce += 1
        return 0


def block_chain_printer(block_chain):
    for block in block_chain:
        print(f'nonce:{block.nonce}')
        print(f'data:{block.data}')
        print(f'prevhash:{block.prevhash}')
        print(f'hash:{block.hash}')
        print()

GenesisBlock = Block('Genesis Block', None, 4)
GenesisBlock.get_hash()
block_chain = [GenesisBlock]

for i in range(10):
    prior_block = block_chain[-1]
    NextBlock = Block(i+1, prior_block.hash, 4)
    NextBlock.get_hash()
    block_chain.append(NextBlock)

block_chain_printer(block_chain)

결과

Genesis Block이후 모든 블록에 대해 hash값의 맨처음 4자리는 0이다. Nonce가 5이상이 되면 10개의 블록을 만드는데도 적지 않은 시간이 걸린다.

Block Chain의 장점

데이터 변경이 어렵다 – 중간 블록의 데이터를 변경한다면 이후의 블록들에 대해 다시 nonce를 다 계산해줘야하므로