์ƒˆ์†Œ์‹

์ธ๊ธฐ ๊ฒ€์ƒ‰์–ด

๐Ÿ“  Secure/๐Ÿ†” Crypto

[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
๋ฐ˜์‘ํ˜•
Contents

ํฌ์ŠคํŒ… ์ฃผ์†Œ๋ฅผ ๋ณต์‚ฌํ–ˆ์Šต๋‹ˆ๋‹ค

์ด ๊ธ€์ด ๋„์›€์ด ๋˜์—ˆ๋‹ค๋ฉด ๊ณต๊ฐ ๋ถ€ํƒ๋“œ๋ฆฝ๋‹ˆ๋‹ค.