[Python] 블록체인 원리 및 구현
by Edward Park
Block Chain
사전 용어 정리
Block Chain
- 말 그대로 데이터(Block)을 연결(Chain)한것
- 구조체를 링크드리스트로 연결하는것과 유사
Hash
-
임의의 크기를 가진 데이터(Key)를 고정된 크기의 데이터(Value)로 변화시켜 저장하는 것
- 출력값으로 입력값을 예측할 수 없는것, 같은내용을 입력값으로 주면 결과값은 항상 같다.
-
Key가 정수일때 m으로 나눈 나머지를 Value로 취하는 것도 해시 함수라고 할 수 있다(Value의 충돌이 잦으므로 좋은 해시함수라고는 할 수 없음).
- 해시함수 종류: HAS-160, SHA-1, SHA-256 등
Block Chain 구현
Block의 구성요소
- 이전 블록의 해시값
- 현재 블록에서 저장할 정보
- Nonce
Chain 구현
- 시작 블록(Genesis Block) 설정
- 이전 블록의 해시값과 현재 블록의 데이터를 해시함수에 넣어 다음 블록의 해시값을 구하는것을 반복
출처 : 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를 다 계산해줘야하므로