[Crypto] Python | ๋ธ๋ก์ฒด์ธ ์ดํดํ๊ธฐ
1. ๊ธฐ์ด ๋ธ๋ก ๋ง๋ค๊ธฐ
๋ธ๋ก์ ๊ฐ๊ฐ์ ๋ฐ์ดํฐ ๊ฐ์ ๊ฐ์ง๋ค
- timestamp : ์ธ์ ๋ง๋ค์ด ์ก๋์ง
- hash : ํ์ฌ ๋ธ๋ก์ ํด์ ๊ฐ
- previous hash : ์ด์ ๋ธ๋ก์ ํด์ ๊ฐ
- nonce : ๋ ผ์ค
- transaction : ์ค์ ๋ฐ์ดํฐ ์ ๋ณด์ธ ํธ๋์ ์
class Block:
def __init__(self, transactions, previous_hash, nonce = 0):
self.timestamp = datetime.now() #datetime.now()๋ฅผ ์ฌ์ฉํด์ ํ์ฌ ๊ฐ์ timestamp
self.transactions = transactions
self.previous_hash = previous_hash
self.nonce = nonce
self.hash = self.generate_hash() #generate_hash() ํจ์๋ฅผ ๋ง๋ค์ด์ ํด์๋ฅผ ์์ฑ
ํด์๋ฅผ ๋ง๋๋ generate_hash()ํจ์ ๋ง๋ค๊ธฐ
ํด์์ฒ๋ฆฌํ๊ณ ์ถ์ ์ ๋ณด๋ฅผ sha256์์ ๋ฃ๊ณ (string์ด๋ผ๋ฉด encode()๋ฅผ ํด์ฃผ์ด์ผ ํจ)
์ด๋ฅผ hexdigest ํจ์๋ฅผ ์ฌ์ฉํ์ฌ ํ๋ฆฐํธ ๊ฐ๋ฅ
from hashlib import sha256
test_content = 'test string for making hash'
test_hash = sha256(test_content.encode())
print(test_hash.hexdigest())
์ค์ Blockํด๋์ค์ generate_hash() ํจ์
from datetime import datetime
from hashlib import sha256
class Block:
def __init__(self, transactions, previous_hash, nonce =0):
self.timestamp = datatime.now()
self.transactions = transactions
self.previous_hash = previous_hash
self.nonce = nonce
self.hash = self.generate_hash()
def print_block(self):
print("timestamp : ", self.timestamp)
print("transactions : ", self.transactions)
print("current hash : ", self.generate_hash())
def generate_hash(self):
block_contents = str(self.timestamp) + str(self.transactions) + str(self.previous_hash) + str(self.nonce)
block_hash = sha256(block_contents.encode())
return block_hash.hexdigest()
2. ๋ธ๋ก์ฒด์ธ ํด๋์ค ๋ง๋ค๊ธฐ
์ด์ ์ ๋ง๋ ๋ธ๋ก์ ๊ฐ์ง๊ณ ์ค์ ๋ก ์ด์ ๋ธ๋ก๊ณผ ๋ค์ ๋ธ๋ก์ ์ฐ๊ฒฐํ BlockChain์ ๋ง๋ ๋ค.
๋ธ๋ก ์ฒด์ธ์ ํด๋์ค๋ค์ด ๊ฐ์ ธ์ผ ํ ๊ฐ๊ณผ ๋ฉ์๋๋ ?
- ๋ชจ๋ ๋ธ๋ก๋ค์ list
- ๋ชจ๋ transaction๋ค
- genesis_block์ ๋ง๋๋ ๋ฉ์๋
- ๋ธ๋ก์ ์ถ๊ฐํ๋ ๋ฉ์๋
- chain validation ( ๋ธ๋ก ์ฒด์ธ ๊ฒ์ฆ )
init
๋ธ๋ก์ฒด์ธ ํด๋์ค์์ ์ฒ์์ ํ์ํ ํญ๋ชฉ๋ค์ __init__์ผ๋ก ์ด๊ธฐํ ํด์ค๋ค.
๋ชจ๋ ๋ธ๋ก์ ์ ์ฅํ chain list์ ๋ชจ๋ transaction ๋ฐ์ดํฐ๋ฅผ ์ ์ฅํ all_transactions๋ฅผ ์ถ๊ฐํด์ค๋ค.
from block import Block
class Blockchain:
def __init__(self):
self.chain = []
self.all_transactions = []
genesis block
๋ธ๋ก ์ฒด์ธ์ ์ฒซ ๋ธ๋ก์ผ๋ก ์ด์ ๋ธ๋ก์ ๊ฐ์ง ์๋ ์ ์ผํ ๋ธ๋ก
transactions(๊ฑฐ๋๋ด์ญ)๊ณผ ์ด์ ํด์ ๊ฐ์ ๊ฐ์ง ํ์๊ฐ ์์ผ๋ฏ๋ก Block({},0)์ผ๋ก ์์ฑ์ด ๊ฐ๋ฅ
ํด๋์ค๊ฐ ์ฌ์ฉ๋ ๋ ๋ฐ๋ก genesis block์ด ์์ฑ๋๋๋ก __init__์์ genesis_block()์ ์คํ
from block import Block
class Blockchain:
def __init__(self):
self.chain = []
self.all_transactions = []
def genesis_block(self):
transactions = {}
block = Block(transactions, 0)
self.chain.append(block)
return self.chain
POW(proof of work)
์๋ก์ด ๋ธ๋ก์ ์ถ๊ฐํ๊ธฐ ์ํด ๋ธ๋ก์ฒด์ธ์ ์์ ์ฆ๋ช ํจ์
์๋ก์ด ๋ธ๋ก์ด ์ถ๊ฐ๋ ๋ block์ difficulty์ ๋ฐ๋ผ nonce ๊ฐ์ ์ฆ๊ฐ ์ํค๋ฉฐ ํด๋น ๋ฒ์์ ์๋ hash ๊ฐ์ ์ฐพ๋ ์์ ์ด ํ์
์ด๋ฅผ ๋ด๋ถํจ์๋ก ๋ง๋ค์ด ์๋์ผ๋ก pow๊ฐ ์งํ๋๋๋ก ์์ฑ
pow๋ difficulty(๊ธฐ๋ณธ์ผ๋ก 2์ ๊ฐ)์ ๋ฐ๋ผ์ ํด๋น ํด์ฌ๋ฅผ ์ฐพ๊ธฐ ์ํด ๊ณ์ nonce๊ฐ์ ๋ํ๋ฉด์ ๋ง๋ ๊ฐ์ ์ฐพ์๋ธ๋ค.
ex) difficulty๊ฐ 2์ธ๊ฒฝ์ฐ (proof_of_work(block, difficulty=2)) ํด์ฌ์ ์ฒ์ ๋์๋ฆฌ๊ฐ 00์ผ๋ก ์์๋๋ ํด์ฌ๊ฐ์ ์ฐพ๊ธฐ ์ํด ๊ณ์ nonce๋ฅผ ๋ํด๊ฐ๋ค.
from block import Block
class Blockchain:
def __init__(self):
self.chain = []
self.all_transactions = []
def genesis_block(self):
transactions = {}
block = Block(transactions, 0)
self.chain.append(block)
return self.chain
##########################
def proof_of_work(self, block, difficulty=2):
proof = block.generate_hash()
while proof[:2]!='0'*difficulty:
block.none +=1
proof = block.generate_hash()
return proof
##########################
block ์ถ๊ฐํ๊ธฐ
์๋ก์ด ๋ธ๋ก์ด ์ถ๊ฐ๋๋ add_block ๋ฉ์๋ ์ถ๊ฐ
genesis block๊ณผ๋ ๋ค๋ฅด๊ฒ ์ดํ ๋ธ๋ก๋ค์ transactions, ์ด์ hash๊ฐ์ ๊ฐ์ง๋ค.
from block import Block
class Blockchain:
def __init__(self):
self.chain = []
self.all_transactions = []
def genesis_block(self):
transactions = {}
block = Block(transactions, 0)
self.chain.append(block)
return self.chain
##########################
def add_block(self, transactions):
previous_block_hash = self.chain[len(self.chain)-1].hash
new_block = Block(transactions, previous_block_hash)
proof = self.proof_of_work(new_block)
self.chain.append(new_block)
return proof, new_block
##########################
def proof_of_work(self, block, difficulty=2):
proof = block.generate_hash()
while proof[:2]!='0'*difficulty:
block.none +=1
proof = block.generate_hash()
return proof
Validate
validate๊ฐ ํ์ฌ๋ ์๋๋ ์ํ๊ธฐ์ ๋ธ๋ก์ ์ ๋ณด๋ฅผ ๋ณ๊ฒฝํ๋๋ผ๋ ํด๋น ๋ธ๋ก์ฒด์ธ์ด validateํ์ง ์ ์ ์๋ค.
๊ฐ๋จํ validate_chain ๋ฉ์๋๋ก ํด๋น ๋ธ๋ก์ฒด์ธ์ ์๋ณ์กฐ๊ฐ ์์๋์ง(hash๊ฐ์ด ๋ณ๊ฒฝ๋์ง ์์๋์ง) ํ์ธ ๊ฐ๋ฅ
from block import Block
class Blockchain:
def __init__(self):
self.chain = []
self.all_transactions = []
def genesis_block(self):
transactions = {}
block = Block(transactions, 0)
self.chain.append(block)
return self.chain
def add_block(self, transactions):
previous_block_hash = self.chain[len(self.chain)-1].hash
new_block = Block(transactions, previous_block_hash)
proof = self.proof_of_work(new_block)
self.chain.append(new_block)
return proof, new_block
##########################
def validate_chain(self):
for i in range(1, len(self.chain)):
current = self.chain[i]
previous = self.chain[i-1]
if current.hash != current.generate_hash():
print("๋ธ๋ก์ ํ์ฌ ํด์๊ฐ ์์ฑ๋ ๋ธ๋ก ํด์์ ๋์ผํ์ง ์์ต๋๋ค.")
return False
if privious.hash != previous.generate_hash():
print("์ด์ ๋ธ๋ก์ ํด์๊ฐ ํ์ฌ ๋ธ๋ก์ ์ ์ฅ๋ ์ด์ ํด์ ๊ฐ๊ณผ ๋์ผํ์ง ์์ต๋๋ค.")
return False
if current.previous_hash != previous.hash:
return False
return True
##########################
def proof_of_work(self, block, difficulty=2):
proof = block.generate_hash()
while proof[:2]!='0'*difficulty:
block.none +=1
proof = block.generate_hash()
return proof