블럭체인 알고리즘 - (2) 분산

HeejinShin·2023년 2월 27일
0

블록체인

목록 보기
2/3

오늘 구현할 알고리즘은 다음과 같다.

# Register : 새로운 노드 가입

# Consensus : 어떤 체인이 맞는 것인지에 대해 합의

** 이 체인과 2체인이 다른 경우에 길이가 긴 체인이 맞는 체인

. 새로운노드를 구성시킬 땐 다른 포트를 사용 ex 5000 > 5001 > 파이썬 실행 > 각각의 노드들을 각 레지스터들끼리 체인을 비교하는 방식을 활용할 것임. 이렇게 구동되기 위해서 어떻게 코드를 짜야하는 지 해볼 것임.

1. init 작성

	def __init__(self):
    	self.chain = []
        self.current_transaction = []
        self.nodes = set() 
        self.new_block(previous_hash=1, proof=100)
  • nodes에 set()을 이용하여 노드를 담는다. 포트를 통해 불러온 노드들이 같은 노드이더라도 한 번만 저장하게 만들기 위해 중복을 허용하지 않는 set을 사용한 것.

2. 노드 저장

그리고 이제 init 형태를 초기화 까지 ㄴ진행이 됐다면, node를 저장을 할 건데, 그 부분이 register_node. 메서드.

	def register_node(self, address):
    	parsed_url = urlparse(address)
        self.nodes.add(parsed_url.netloc)
  • address를 url주소를 넣어 받음
  • 라이브러리 임포트 할때 다 작성되어있는 부분이기 때문에 그냥 사용하면 됨 , 해당 변수를 저장
  • .add()를 통해 set자료안에 node를 저장한다.

알고가기) 여기서 node의 개념:

3. 체인 비교

  • 두개의 함수 사용
    - valid
    • resolve
    • 한 노드가 다른도느돠 다른 체인을 가지고 있을 때 가장 긴 체인이 유효하다.
	def valid_chain(self, chain):
    	last_block = chain[0]    # 첫 번째 제네시스 블록이 저장됨 
        current_index = 1
        
        while current_index < len(chain): 
        	block = chain[current_index]
            print('%s', % last_block) 
            print('%s', % block) 
            print("\n---------\n")
            ---------------------------------
            
            #check that the hash of the block is correct 
            # 해시값 비교, 검증 
            if block['previous_hash'] != self.hash(last_block):
            		return False
            last_block = block
            current_index += 1
            
        return True
  • 맞는 유효한 체인이 무엇인지 검증하는 과정을 거친 것임
  • 이어서 resolve, consensus과정
	def resolve_conflicts(self):
    	# 구동되는 이웃 노드들을 다 넣는다
    	neighbours = self.nodes     #각 노드들을 저장하는 neighbours
        new_chain = None
        
        max_length = len(self.chain)  #Our chain length
        for node in neighbours:
        		tmp_url = 'http:// + str(node) + '/chain'   # url을 받아서 request를 통해 체인 정보 저장 
                response = requests.get(tmp_url)
                if response.status_code == 200:
                		length = response.json()['length']
                        chain = response.json()['chain']
                        
                        if length > max_length and self.valid_chain(chain):   # 긴 체인을 선택하게 됨 
                        		max_length = length
                
                if new_chain:
                		self.chain = new_chain
                        return True
                        
                return False
  • blockchcain.py가 마무리 된 것
  • 이어서 websited에 뿌려주는 작업
	 @app.route('/nodes/register', methods=['POST'])
     def register_nodes():
     		values = request.get_json()
            
            nodes = values.get('nodes')
            if nodes i None: #Bad Request 400
            	return "Error: Please supply a valid list of nodes", 400
            for node in nodes:
            		blockchain.register_node(node)
                    
            response = {
            		'message' =  ' New nodes have been added', 
                    'total_nodes': list(blockchain.nodes),
            }
            return jsonify(response), 201
            
          

blockcahin.resolve_conflict > 반환값이 들어가고, bool결과를 통해 해당 값이 우리게 맞는 체인이다 아니다 하는 알림메시지가 나올것 (if replace, else)

새로 알게된 코드 기능

  1. append(dict)
 def new_transaction(self,sender,recipient,amount):
		self.current_transaction.append(
			{
				'sender' : sender,  # 송신자
				'recipient' : recipient,  #수신자
				'amount' : amount	#얼마 보낼지			 
				
			}
		)
  • list자료구조에 apppend()를 하는데 dic 형태 자료를 통째로 (key: value) 넣었다.
  1. 파이썬의 내장데코레이터인 @property
	@property
	def last_block(self):
		return self.chain[-1]

	def pow(self, last_proof):
		proof = 0
		while self.valid_proof(last_proof, proof) is False:
			proof += 1

		return proof

https://www.daleseo.com/python-property/ 참고해서 getter,setter, 데코레이터 쓸때 각각 비교해보기.

  1. 파이썬의 암호화 모듈 hashlib 사용
	def valid_proof(last_proof, proof):
        guess = str(last_proof + proof).encode()
        guess_hash = hashlib.sha256(guess).hexdigest()
        return guess_hash[:4] == " 0000 "
  • sha256() ; 해시 객체를 만드는데 사용
profile
Studying Go Lang

0개의 댓글