21/1/2018

50줄로 만들어 보는 tiny 블록체인

Blockchain

비트코인이나 암호화폐의 트랜잭션을 공개적이며 순차적으로 기록하는 디지털 분산 원장 입니다. - Google Search

보다 일반적으로 설명하자면, 블록체인은 새로운 데이터가 블록이라는 컨테이너에 저장되고, 이전 블록과 체인으로 연결된 변경불가능한 공용 데이터베이스입니다. 비트코인이나 다른 암호화폐에서 이러한 데이터는 트랜젝션(거래)의 묶음 이지만, 다른 타입의 데이터가수도 있습니다.

블록체인 기술은 비트코인 그리고 라이트코인과 같이 중앙기관에서 통제되지 않는 디지털 화폐를 탄생시켰습니다. 블록체인은 오늘날 금융시스템이 사기 또는 실폐의 대상이라고 믿는 개인에게 새로운 자유를 가져다 줍니다. 또한, 블록체인은 스마트 계약과 같은 흥미로운 개념을 도입한 이더리움과 같은 분산 컴퓨팅 기술을 혁신시켰습니다.

먼저 블록이 무엇인지 정의해봅시다. 블록체인에서블록은 타임스탬프인덱스를 저장합니다. 각 블록은 무결성을 위한 자체 해시를 갖습니다. 비트코인과 같이블록의 해시는 블록의 인덱스, 타임 스탬프, 데이터이전 블록 해시를 암호화 하는 해시입니다.

import hashlib


class Block:
    def __init__(self, idx, ts, data, pre_hash):
        self.idx = idx
        self.ts = ts
        self.data = data
        self.pre_hash = pre_has
        self.hash = self.hash_block()

    def hash_block(self):
        sha256 = hashlib.sha256():
        sha256.update(
            str(self.idx) +
            str(self.ts) +
            str(self.data) +
            str(self.pre_hash)
        )
        return sha256.hexdigest()

멋지네요! 블록체인 자료구조를 만들었고, 블록체인만들것이며, 실제 체인에 블록을 추가해야 합니다. 앞에서 말했듯이, 각 블록체인은 이전 블록정보가 필요합니다. 그런데

번째 블록에는 어떻게 이전 블록의 정보를 담을 수 있을까요?

첫번째 블록은 특별하며, 이는 Genesis Block 라고 부릅니다. 대부분 Genesis Block수동으로 추가되거나, 추가되게 하는 고유한 로직을 갖습니다.

우리는 Genesis Block반환하는 함수를 만들 것이며, Genesis Block인덱스 0, 임의의 데이터, 임의의 이전 블럭 해시 값을 갖습니다.

from datetime import datetime


def create_genesis_block():
    return Block(0, datetime.utcnow(), "Genesis Block", "0")

이제 우리는 Genesis Block만들있게 되었으므로, 후속 블록들을 생성하는 함수가 필요합니다. 이 함수는 블록체인의 이전 블록을 매개변수로 받고, 생성될 블록에 필요한 데이터를 만든알맞는 데이터와 함께 블록을 반환합니다. 새로운 블록이 이전 블록 정보를 해시할때, 새로운 블록과 블록체인의 무결성증가합니다. 이러한 작업이 없다면, 외부자가 과거의 정보를 바꾸거나 그들 소유의 새로운 정보로 이전의 블록체인을 위변하기 쉬워 집니다. 이러한 해시 체인은 암호화 증명을 수행하고, 블록체인에 블록이 추가될때 블록이 교체되거나 제거 되는 것을 보증합니다.

from datetime import datetime


def next_block(pre_block):
    idx = pre_block.idx + 1
    ts = datetime.utcnow()
    data = "Hey! I'm %d block " % idx
    hash_ = pre_block.hash
    return block(idx, ts, data, hash_)

이제 우리의 블록체인을 만들수 있습니다. 여기서 블록체인은 파이썬 리스트 입니다. 리스트의 첫번째 요소는 Genesis Block 이며, 후속 블록 추가가 필요합니다. for loop사용하여 20개의 새로운 블록을 추가해 봅시다.

blockchain = [create_genesis_block()]
pre_block = blockchain[0]


num_of_blocks_to_add = 20


for _ in range(0, num_of_blocks_to_add):
    block_to_add = create_next_block(pre_block)
    blockchain.append(block_to_add)
    pre_block = block_to_add

    print("Block #{} has been added to the blockchain!".format(block_to_add.idx))
    print("Hash: {}\n".format(block_to_add.hash))

우리가 지금까지 만들 것을 테스트봅시다.

$ python blockchain.py
Block #1 has been added to the blockchain!
Hash: efb894d339ab1e272641676758e1a5b5cbc5b82fd3c069c98a7d7338f8aa5944

Block #2 has been added to the blockchain!
Hash: 1d49888f46aafeaeb56738f115b0572592089316895736f43e254c7906bf6a50

Block #3 has been added to the blockchain!
Hash: b20b257dbd350c2097ebcfca70e7890c6552b79857e6306b3d549576d833e2fa

...(중략)

Block #19 has been added to the blockchain!
Hash: 11643f989f71121cdba4a9cc180890da75bd875505f736119cf6a32e81a9dba2

Block #20 has been added to the blockchain!
Hash: 43380ce50d045f4f30d126ff3a50ee3b1d4d039c7c55c4c9305ea165c48392fa

블록체인이 작동합니다! 더 많은 정보를 콘솔에 확인해보고 싶다면, 완성된 코드수정하고 출력해보세요.

우리의 블록체인을 실제 상용 블로체인들 처럼 확장하기 위해서는 서버 계층과 같은 기능들을 추가해야만 합니다. 이는 체인의 변경 사항을 추적하고, 한정된 시간에서 추가될 블록의 수를 제한하는 작업증명 역할을 합니다.

기술적으로자세히 알고 싶다면, Bitcoin Whitepaper참고하세요.


blockchain bitcoin cryptocurrency python


Previous post
Understanding decorator and closer on the Python
Next post
Python 함수 내부에서의 Null Validation 혹은 검증 로직에 대한 생각 위와 같이 함수에서 확인은 적절한 것일까요? 결론 부터 말하자면 “NO” 입니다. 함수내부에서 파라미터 의 검사를 하는것이 틀린 방법은 아닙니다. 하지만 부득이한 경우가 아니라면 함수에 정상적인 값이 들어온다는 전제하에 함수를 작성하는 것이 효율적입니다. 위와