반응형

https://minii22.tistory.com/144

 

블록체인 만들기2

 

minii22.tistory.com

기존에 작성한 블록체인을 기반으로 직접 암호화폐 생성

 

 

hadcoin 파일을 생성한다.

 

# Module 1 - Create a Blockchain

#Importing the libraries
import datetime
import hashlib
import json
from flask import Flask, jsonify

# Part 1 - Building a Blockchain

class Blockchain:
    
    def __init__(self):
        self.chain = [] # 블록을 포함한 체인, 다른 블록을 포한하는 리스트
        self.create_block(proof = 1, previous_hash = '0') # 제네시스 블록 생성

    def create_block(self, proof, previous_hash):
        block = {'index': len(self.chain)+1,
                 'timestamp': str(datetime.datetime.now()),
                 'proof': proof,
                 'previous_hash': previous_hash}
        self.chain.append(block)
        return block
    
    def get_previous_block(self):
        return self.chain[-1]
    
    def proof_of_work(self, previous_proof):
        new_proof = 1 # 새로운 증명 변수
        check_proof = False
        while check_proof is False:
            hash_operation = hashlib.sha256(str(new_proof**2 - previous_proof**2).encode()).hexdigest() # 비대칭
            if hash_operation[:4] == '0000':
                check_proof = True
            else:
                new_proof += 1
        return new_proof
    
    def hash(self, block):
        encode_block = json.dumps(block, sort_keys = True).encode()
        return hashlib.sha256(encode_block).hexdigest()
    
    def is_chain_valid(self, chain):
        previous_block = chain[0]
        block_index = 1
        while block_index < len(chain):
            block = chain[block_index]
            if block['previous_hash'] != self.hash(previous_block):
                return False
            previous_proof = previous_block['proof']
            proof = block['proof']
            hash_operation = hashlib.sha256(str(proof**2 - previous_proof**2).encode()).hexdigest() # 해시 연산
            if hash_operation[:4] != '0000': # 해시 연신이 4개의 선행 제로를 갖는지
                return False
            previous_block = block
            block_index += 1
        return True

    
# Part 2 - Mining our Blockchain

# Creating a Web App
app = Flask(__name__)

# Creating a Blockchain
blockchain = Blockchain()

# Mining a new Blockchain
@app.route("/mine_block", methods=['GET'])
def mine_block():
    previous_block = blockchain.get_previous_block() # 이전 블록
    previous_proof = previous_block['proof'] # 이전 증명
    proof = blockchain.proof_of_work(previous_proof) # 작업 증명 메서드를 호출해서 증명을 얻음
    previous_hash = blockchain.hash(previous_block) # 이전 해시
    block = blockchain.create_block(proof, previous_hash) # 블록체인 추가, 반환된 블록
    # 채굴한 새 블록을 정의할 모든 키 정의
    response = {'message': 'Congratulations, you just mined a block!',
                'index': block['index'],
                'timestamp': block['timestamp'],
                'proof': block['proof'],
                'previous_hash': block['previous_hash']} # 응답 딕셔너리, 블록 딕셔너리
    return jsonify(response), 200 # 200 HTTP 상태 코드
    
# Getting the full Blockchain
@app.route("/get_chain", methods=['GET'])
def get_chain():
    response = {'chain': blockchain.chain,
                'length': len(blockchain.chain)}
    return jsonify(response), 200

# Checking if the Blockchain is valid
@app.route('/is_valid', methods = ['GET'])
def is_valid():
    is_valid = blockchain.is_chain_valid(blockchain.chain)
    if is_valid:
        response = {'message': 'All good. The Blockchain is valid.'}
    else:
        response = {'message': 'Houston, we have a problem. The Blockchain is not valid.'}
    return jsonify(response), 200

# Running the app
app.run(host = '0.0.0.0', port =  5000)

Module 1에서 사용했던 위의 코드(blockchain.py)를 hadcoin.py에 붙여 넣는다.

 

pip install requests==2.18.4

Anacoda Prompt에서 위의 명령어로 라이브러리를 설치한다.

from flask import Flask, jsonify, request

탈중앙화된 블록체인에 노드를 추가할 때에는 requests 모듈이 필요하다.

 

import requests

requests 라이브러리를 불러와서 탈중앙화된 블록체인 내의 모든 노드가 실제로 동일한 체인을 가지고 있는지 확인한다.

 

from uuid import uuid4
from urllib.parse import urlparse

uuid4와 urlparse 함수로 네트워크의 각 노드에 대한 주소를 생성하고 이 노드별 URL을 분석하기 위해 추가한다.

 

 

 

    def __init__(self):
        self.chain = [] # 블록을 포함한 체인, 다른 블록을 포한하는 리스트
        self.transactions = []
        self.create_block(proof = 1, previous_hash = '0') # 제네시스 블록 생성

    def create_block(self, proof, previous_hash):
        block = {'index': len(self.chain)+1,
                 'timestamp': str(datetime.datetime.now()),
                 'proof': proof,
                 'previous_hash': previous_hash,
                 'transactions': self.transactions}
        self.transactions = []
        self.chain.append(block)
        return block

트랜잭션이 블록에 통합되기 전 이들을 수용하는 개별 목록을 생성해야 한다.

그리고 init 메서드에 있어서 이 트랜잭션 목록을 정확히 어디에 추가할지를 파악하는 것이 중요하다.

이 위치는 제네시스 블록을 생성하기 위한 블록 생성 함수 이전에 위치해야 한다.

 

    def add_transactions(self, sender, receiver, amount):
        self.transactions.append({'sender': sender,
                                  'receiver': receiver,
                                  'amount': amount})
        previous_block = self.get_previous_block()
        return previous_block['index'] + 1

수신자와 발신자, 애드코인 거래량이 있는 트랜잭션을 생성하고 이를 트랜잭션 목록에 추가하는 메서드 생성

트랜잭션을 수신하는 블록의 인덱스 반환

이를 위해 신규 블록을 찾아야 한다.

 

 

 

 

합의는 모든 노드에 항상 같은 체인을 포함하게 하는 알고리즘이다.

그래서 노드에서 새로운 블록이 채굴될 때마다 해당 노드 주변의 새로운 트랜잭션을 수용하고 탈중앙화 네트워크에 있는 다른 노드가 같은 체인으로 업데이트되도록 한다.

 

    def __init__(self):
        self.chain = [] # 블록을 포함한 체인, 다른 블록을 포한하는 리스트
        self.transactions = []
        self.create_block(proof = 1, previous_hash = '0') # 제네시스 블록 생성
        self.nodes = set()
    def add_node(self, address):
        parsed_url = urlparse(address)
        self.nodes.add(parsed_url.netloc)

노드가 될 새로운 변수를 생성하고 set 함수로 빈 집합을 초기 설정한다.

addnode 메서드는 노드 주소를 인수로 취하고 네트워크 주소를 포함하는 노드를 추가한다.

 

 

 

# Module 2 - Create a Cryptocurrency

#Importing the libraries
import datetime
import hashlib
import json
from flask import Flask, jsonify, request
import requests
from uuid import uuid4
from urllib.parse import urlparse

# Part 1 - Building a Blockchain

class Blockchain:
    
    def __init__(self):
        self.chain = [] # 블록을 포함한 체인, 다른 블록을 포한하는 리스트
        self.transactions = []
        self.create_block(proof = 1, previous_hash = '0') # 제네시스 블록 생성
        self.nodes = set()
        

    def create_block(self, proof, previous_hash):
        block = {'index': len(self.chain)+1,
                 'timestamp': str(datetime.datetime.now()),
                 'proof': proof,
                 'previous_hash': previous_hash,
                 'transactions': self.transactions}
        self.transactions = []
        self.chain.append(block)
        return block
    
    def get_previous_block(self):
        return self.chain[-1]
    
    def proof_of_work(self, previous_proof):
        new_proof = 1 # 새로운 증명 변수
        check_proof = False
        while check_proof is False:
            hash_operation = hashlib.sha256(str(new_proof**2 - previous_proof**2).encode()).hexdigest() # 비대칭
            if hash_operation[:4] == '0000':
                check_proof = True
            else:
                new_proof += 1
        return new_proof
    
    def hash(self, block):
        encode_block = json.dumps(block, sort_keys = True).encode()
        return hashlib.sha256(encode_block).hexdigest()
    
    def is_chain_valid(self, chain):
        previous_block = chain[0]
        block_index = 1
        while block_index < len(chain):
            block = chain[block_index]
            if block['previous_hash'] != self.hash(previous_block):
                return False
            previous_proof = previous_block['proof']
            proof = block['proof']
            hash_operation = hashlib.sha256(str(proof**2 - previous_proof**2).encode()).hexdigest() # 해시 연산
            if hash_operation[:4] != '0000': # 해시 연신이 4개의 선행 제로를 갖는지
                return False
            previous_block = block
            block_index += 1
        return True

    def add_transactions(self, sender, receiver, amount):
        self.transactions.append({'sender': sender,
                                  'receiver': receiver,
                                  'amount': amount})
        previous_block = self.get_previous_block()
        return previous_block['index'] + 1

    def add_node(self, address):
        parsed_url = urlparse(address)
        self.nodes.add(parsed_url.netloc)
    
# Part 2 - Mining our Blockchain

# Creating a Web App
app = Flask(__name__)

# Creating a Blockchain
blockchain = Blockchain()

# Mining a new Blockchain
@app.route("/mine_block", methods=['GET'])
def mine_block():
    previous_block = blockchain.get_previous_block() # 이전 블록
    previous_proof = previous_block['proof'] # 이전 증명
    proof = blockchain.proof_of_work(previous_proof) # 작업 증명 메서드를 호출해서 증명을 얻음
    previous_hash = blockchain.hash(previous_block) # 이전 해시
    block = blockchain.create_block(proof, previous_hash) # 블록체인 추가, 반환된 블록
    # 채굴한 새 블록을 정의할 모든 키 정의
    response = {'message': 'Congratulations, you just mined a block!',
                'index': block['index'],
                'timestamp': block['timestamp'],
                'proof': block['proof'],
                'previous_hash': block['previous_hash']} # 응답 딕셔너리, 블록 딕셔너리
    return jsonify(response), 200 # 200 HTTP 상태 코드
    
# Getting the full Blockchain
@app.route("/get_chain", methods=['GET'])
def get_chain():
    response = {'chain': blockchain.chain,
                'length': len(blockchain.chain)}
    return jsonify(response), 200

# Checking if the Blockchain is valid
@app.route('/is_valid', methods = ['GET'])
def is_valid():
    is_valid = blockchain.is_chain_valid(blockchain.chain)
    if is_valid:
        response = {'message': 'All good. The Blockchain is valid.'}
    else:
        response = {'message': 'Houston, we have a problem. The Blockchain is not valid.'}
    return jsonify(response), 200

# Running the app
app.run(host = '0.0.0.0', port =  5000)
pip uninstall urllib3 requests
pip install requests

전체 코드이고 실행했을 때 오류가 떠서 requests를 재설치했다.

실행

 

 

콘솔에 다음과 같이 입력하면 parsed_url에 포함된 것을 볼 수 있다.

이것이 url 파싱의 의미이다.

 

parsed_url.netloc를 입력하면 포트를 포함한 url을 얻을 수 있다.

 

    def replace_chain(self):
        network = self.nodes
        longest_chain = None
        max_length = len(self.chain)
        for nodes in network:
            response = requests.get('http://127.0.0.1:5000/get_chain')

가장 긴 체인보다 짧은 모든 체인을 교체하는 메서드 생성

특정 노드에서 호출하기 때문에 self의 한 가지 인수만 취한다.

 

네트워크의 노드는 파싱된 url 네트워크와 동일하다.

parsed_url.netloc와 같음

이것이 각각의 노드가 노드 집합에 있는 것이다.

 

    def replace_chain(self):
        network = self.nodes
        longest_chain = None
        max_length = len(self.chain)
        for nodes in network:
            response = requests.get(f'http://{node}/get_chain')

노드 식별 방법

네트워크의 노드와 일치시키기 위해 교체해야 하는 것은 노드이며, 네트워크의 노드를 반복 수행하지만 각 노드를 개별적으로 수행한다.

그래서 네트워크의 각 노드로 이 요청에 관한 response를 얻고 루프의 모든 노드를 일반화한다.

노드는 127.0.0.1:5000이기 때문에 포트를 포함한 이 url을 node로 교체한다.

→ 체인의 길이를 얻는 응답

 

    def replace_chain(self):
        network = self.nodes
        longest_chain = None
        max_length = len(self.chain)
        for node in network:
            response = requests.get(f'http://{node}/get_chain')
            if response.status_code == 200:
                length = response.json()['length']
                chain = response.json()['chain']
                if length > max_length and self.is_chain_valid(chain):
                    max_length = length
                    longest_chain = chain
        if longest_chain:
            self.chain = longest_chain
            return True
        return False

확인을 위해 response.status_code를 입력해 이 응답의 상태 코드 특성을 얻고 200과 같다고 입력

그리고 노드의 길이를 얻을 수 있다.

 

#Creating an address for the node on Port
node_address = str(uuid4()).replace('-', '')

포트 상 노드를 위한 주소 생성

채굴자가 신규 블록을 채굴할 때마다 암호화폐를 습득할 수 있기 때문에 주소를 생성해야 한다.

→ 새로운 노드를 추가하기 전 시작되는 5000번 포트의 노드 주소를 만드는 작업 

 

# Mining a new Blockchain
@app.route("/mine_block", methods=['GET'])
def mine_block():
    previous_block = blockchain.get_previous_block() # 이전 블록
    previous_proof = previous_block['proof'] # 이전 증명
    proof = blockchain.proof_of_work(previous_proof) # 작업 증명 메서드를 호출해서 증명을 얻음
    previous_hash = blockchain.hash(previous_block) # 이전 해시
    blockchain.add_transactions(sender = node_address, receiver = 'Hadelin', amount = 1) # 트랜잭션 추가
    block = blockchain.create_block(proof, previous_hash) # 블록체인 추가, 반환된 블록
    # 채굴한 새 블록을 정의할 모든 키 정의
    response = {'message': 'Congratulations, you just mined a block!',
                'index': block['index'],
                'timestamp': block['timestamp'],
                'proof': block['proof'],
                'previous_hash': block['previous_hash'],
                'transactions': block['transactions']} # 응답 딕셔너리, 블록 딕셔너리
    return jsonify(response), 200 # 200 HTTP 상태 코드

mine_block 요청과 연결된 블록 채굴 함수를 수정해서 다시 한번 이 블록체인을 암호화폐로 바꾸는 작업

이를 위해서는 트랜잭션을 포함해야 한다.

채굴자가 블록을 채굴할 때 애드코인을 습득

 

 

Get 요청

  • 무언가를 찾을 때 쓰는 요청으로 이때는 아무것도 생성할 필요가 없다.
  • 블록을 채굴할 때 새로 채굴된 블록을 포함한 응답을 받는다고 하면 블록을 찾을 때는 무언가를 게시하거나 생성할 필요가 없는 것이다.

 

Post 요청

  • http 클라이언트 내에 무언가를 게시한다.
  • 이 게시 작업이 블록체인에 새로운 트랜잭션 추가를 위해 구현해야 하는 새로운 요청이다.
  • 블록체인에 트랜잭션을 추가하기 위해서는 먼저 해당 트랜잭션을 게시할 필요가 있고 이 트랜잭션을 게시하기 위해서 해당 트랜잭션의 키, 즉 발신자와 수신자, 애드코인 거래량을 포함하는 json 파일을 생성해야 한다.
#Adding a new transaction to the Blockchain
@app.route('/add_transaction', methods = ['POST'])
def add_transaction():
    json = request.get_json()
    transaction_keys = ['sender', 'receiver', 'amount']
    if not all (key in json for key in transaction_keys):
        return 'Some elements of the transaction are missing', 400
    index = blockchain.add_transaction(json['sender'], json['receiver'], json['amount'])
    response = {'message': f'This transaction will be added to Block {index}'}
    return jsonify(response), 201

기본적인 트랜잭션을 생성한다.

이 함수는 발신자와 수신자, 애드코인 거래량이 포함되는 트랜잭션을 알려준다.

그리고 Postman에 게시된 json 파일을 불러와 모든 키가 존재하는지 확인한다.

해당 트랜잭션을 지정해 줄 올바른 블록을 찾기 위해서는 해당 트랜잭션을 포함할 다음 블록의 인덱스가 무엇인지 파악해야 한다.

 

#Connecting new nodes
@app.route('/connect_node', methods = ['POST'])
def connect_node():
    json = request.get_json()
    json.get('node')

트랜잭션 추가 메서드에서 수행했듯이 get_json 함수를 통해서 네트워크에 새로운 노드를 게시하라는 요청을 하고 해당 json 파일을 반환함으로써 현재 연결하려는 노드를 포함하여 모든 노드를 탈중앙화된 네트워크에 포함시킬 수 있다.

동일한 코드를 사용할 것이기 때문에 그대로 복사하면 된다.

다음으로 네트워크에 있는 모든 노드와 새로운 노드를 연결한다.

 

json 파일이 어떤 양상을 보이는지 확인

노드를 입력하고 주소가 포함된 주소 목록을 입력한다.

 

#Connecting new nodes
@app.route('/connect_node', methods = ['POST'])
def connect_node():
    json = request.get_json()
    nodes = json.get('nodes')
    if nodes is None:
        return "No node", 400
    for node in nodes:
        blockchain.add_node(node)
    response = {'message': 'All the nodes are now connectes. The Hadcoin Blockchain now contains the following nodes',
                'total_nodes': list(blockchain.nodes)}
    return jsonify(response),201

노드가 빈 목록인지 아닌지 여부를 확인

for 루프로 도출해야 하는 값을 찾고

개별적으로 응답을 얻은 후 jsonify 함수와 http 상태 코드를 이용해 반환한다.

 

노드 연결 요청 작업 완료

 

 

# Replacing the chain by the longest chain if needed
@app.route('/replace_chain', methods = ['GET'])
def replace_chain():
    is_chain_replaced = blockchain.replace_chain()
    if is_chain_replaced:
        response = {'message': 'The nodes had different chains so the was replaced by the longest one.',
                    'new_chain': blockchain.chain}
    else:
        response = {'message': 'All good. the chain is the latgest one.',
                    'actual_chain': blockchain.chain}
    return jsonify(response), 200

필요할 때 가장 긴 체인으로 교체하는 요청

 

{
    "nodes": ["http://127.0.0.1:5001",
              "http://127.0.0.1:5002",
              "http://127.0.0.1:5003"]
}

nodes.json 파일을 생성한다.

nodes라는 키는 네트워크에 있는 모든 노드의 주소를 포함한다.

키의 값은 네트워크에 있길 원하는 노드들의 주소가 있는 리스트이다.

 

{
    "sender": "",
    "receiver": "",
    "amount":
}

transaction.json 파일을 생성한다.

sender, reciever, amount 세 개의 키를 입력한다.

이것은 발신자와 수신자 사이에 교환되는 애드코인의 거래량이다.

 

# Module 2 - Create a Cryptocurrency

# To be installed:
# Flask==0.12.2: pip install Flask==0.12.2
# Postman HTTP Client: https://www.getpostman.com/
# requests==2.18.4: pip install requests==2.18.4

# Importing the libraries
import datetime
import hashlib
import json
from flask import Flask, jsonify, request
import requests
from uuid import uuid4
from urllib.parse import urlparse

# Part 1 - Building a Blockchain

class Blockchain:

    def __init__(self):
        self.chain = []
        self.transactions = []
        self.create_block(proof = 1, previous_hash = '0')
        self.nodes = set()
    
    def create_block(self, proof, previous_hash):
        block = {'index': len(self.chain) + 1,
                 'timestamp': str(datetime.datetime.now()),
                 'proof': proof,
                 'previous_hash': previous_hash,
                 'transactions': self.transactions}
        self.transactions = []
        self.chain.append(block)
        return block

    def get_previous_block(self):
        return self.chain[-1]

    def proof_of_work(self, previous_proof):
        new_proof = 1
        check_proof = False
        while check_proof is False:
            hash_operation = hashlib.sha256(str(new_proof**2 - previous_proof**2).encode()).hexdigest()
            if hash_operation[:4] == '0000':
                check_proof = True
            else:
                new_proof += 1
        return new_proof
    
    def hash(self, block):
        encoded_block = json.dumps(block, sort_keys = True).encode()
        return hashlib.sha256(encoded_block).hexdigest()
    
    def is_chain_valid(self, chain):
        previous_block = chain[0]
        block_index = 1
        while block_index < len(chain):
            block = chain[block_index]
            if block['previous_hash'] != self.hash(previous_block):
                return False
            previous_proof = previous_block['proof']
            proof = block['proof']
            hash_operation = hashlib.sha256(str(proof**2 - previous_proof**2).encode()).hexdigest()
            if hash_operation[:4] != '0000':
                return False
            previous_block = block
            block_index += 1
        return True
    
    def add_transaction(self, sender, receiver, amount):
        self.transactions.append({'sender': sender,
                                  'receiver': receiver,
                                  'amount': amount})
        previous_block = self.get_previous_block()
        return previous_block['index'] + 1
    
    def add_node(self, address):
        parsed_url = urlparse(address)
        self.nodes.add(parsed_url.netloc)
    
    def replace_chain(self):
        network = self.nodes
        longest_chain = None
        max_length = len(self.chain)
        for node in network:
            response = requests.get(f'http://{node}/get_chain')
            if response.status_code == 200:
                length = response.json()['length']
                chain = response.json()['chain']
                if length > max_length and self.is_chain_valid(chain):
                    max_length = length
                    longest_chain = chain
        if longest_chain:
            self.chain = longest_chain
            return True
        return False

# Part 2 - Mining our Blockchain

# Creating a Web App
app = Flask(__name__)

# Creating an address for the node on Port 5000
node_address = str(uuid4()).replace('-', '')

# Creating a Blockchain
blockchain = Blockchain()

# Mining a new block
@app.route('/mine_block', methods = ['GET'])
def mine_block():
    previous_block = blockchain.get_previous_block()
    previous_proof = previous_block['proof']
    proof = blockchain.proof_of_work(previous_proof)
    previous_hash = blockchain.hash(previous_block)
    blockchain.add_transaction(sender = node_address, receiver = 'Hadelin', amount = 1)
    block = blockchain.create_block(proof, previous_hash)
    response = {'message': 'Congratulations, you just mined a block!',
                'index': block['index'],
                'timestamp': block['timestamp'],
                'proof': block['proof'],
                'previous_hash': block['previous_hash'],
                'transactions': block['transactions']}
    return jsonify(response), 200

# Getting the full Blockchain
@app.route('/get_chain', methods = ['GET'])
def get_chain():
    response = {'chain': blockchain.chain,
                'length': len(blockchain.chain)}
    return jsonify(response), 200

# Checking if the Blockchain is valid
@app.route('/is_valid', methods = ['GET'])
def is_valid():
    is_valid = blockchain.is_chain_valid(blockchain.chain)
    if is_valid:
        response = {'message': 'All good. The Blockchain is valid.'}
    else:
        response = {'message': 'Houston, we have a problem. The Blockchain is not valid.'}
    return jsonify(response), 200

# Adding a new transaction to the Blockchain
@app.route('/add_transaction', methods = ['POST'])
def add_transaction():
    json = request.get_json()
    transaction_keys = ['sender', 'receiver', 'amount']
    if not all(key in json for key in transaction_keys):
        return 'Some elements of the transaction are missing', 400
    index = blockchain.add_transaction(json['sender'], json['receiver'], json['amount'])
    response = {'message': f'This transaction will be added to Block {index}'}
    return jsonify(response), 201

# Part 3 - Decentralizing our Blockchain

# Connecting new nodes
@app.route('/connect_node', methods = ['POST'])
def connect_node():
    json = request.get_json()
    nodes = json.get('nodes')
    if nodes is None:
        return "No node", 400
    for node in nodes:
        blockchain.add_node(node)
    response = {'message': 'All the nodes are now connected. The Hadcoin Blockchain now contains the following nodes:',
                'total_nodes': list(blockchain.nodes)}
    return jsonify(response), 201

# Replacing the chain by the longest chain if needed
@app.route('/replace_chain', methods = ['GET'])
def replace_chain():
    is_chain_replaced = blockchain.replace_chain()
    if is_chain_replaced:
        response = {'message': 'The nodes had different chains so the chain was replaced by the longest one.',
                    'new_chain': blockchain.chain}
    else:
        response = {'message': 'All good. The chain is the largest one.',
                    'actual_chain': blockchain.chain}
    return jsonify(response), 200

# Running the app
app.run(host = '0.0.0.0', port = 5000)

hadcoin_node_5001.py, hadcoin_node_5002.py, hadcoin_node_5003.py

3개의 파일을 생성한다.

해당 코드의 가장 아래 포트 번호만 파일명에 맞게 수정을 한다.

 

 

Demo

노드 5001번, 노드 5002번, 노드 5003번

노드를 위한 Json, 트랜잭션을 위한 Json

이렇게 3가지 노드와 Json 파일 2개를 준비했다.

그리고 3개의 콘솔을 만들어 진행한다.

 

각각의 콘솔에서 3가지 노드를 실행시켰다.

 

Postman에서 3개의 tab을 만들고, 첫 번째 tab에서 ' http://127.0.0.1:5001/get_chain' Get 요청을 하여 체인을 불러온다.

그러면 제네시스 블록을 볼 수 있다.

 

나머지도 포트번호만 바꿔서 요청을 보낸다.

 

이제 Post 요청을 보낸다.

connect_node로 post 요청을 보내는데 Body에 json 파일을 넣는다.

노드 5001번에서 다른 노드로 연결하기 위해 5001은 빼고 다른 노드만 넣어서 요청을 한다.

정상적으로 작동하는 것까지 확인을 했다.

 

다른 노드에서도 똑같이 Post 요청을 한다.

 

이제 블록체인이 완전히 연결되었다.

 

 

다시 Get 요청으로 블록을 채굴한다.

요청 이름은 mine_block이다.

메시지가 뜨고 증명은 533이다.

1 애드코인을 Hadelin에게 보낸 것이다.

 

새로운 블록을 채굴했고 새로운 체인을 확인하려면 get_chain 요청을 해서 확인할 수 있다.

이제 2개의 블록이 있는 것을 알 수 있다.

 

5002번 노드에서 replace_chain을 Get 요청으로 보내면 가장 긴 체인으로 교체되었다.

 

5003번 노드에서도 replace_chain으로 교체 요청을 보냈다.

 

5001번 노드에서 Post 요청을 보낸다.

Hadelin이 Kirill에게 10000 애드코인을 보낸다.

Kirill에게 보내는 트랜잭션으로 세 번째 블록으로 추가되었다.

 

mine_block Get 요청을 보내면 2개의 트랜잭션을 포함한 새로운 블록을 얻는다.

 

그리고 get_chain으로 세 개의 블록을 갖고 있는 것을 확인할 수 있다.

 

그러나 Kirill의 체인(5002)에서 get_chain 요청을 실행하면 2개의 블록만 있는 것을 볼 수 있다.

 

하지만 replace_chain 요청으로 가장 긴 체인으로 교체되어 

같은 요청을 보낸다면 현재 체인이 보이고 체인이 가장 길다는 메시지가 보인다.

 

5003에서도 확인하면 가장 긴 체인으로 교체된 것을 볼 수 있다.

 

5001 노드에서 5003으로 100000 애드코인을 보낸다.

네 번째 블록으로 트랜잭션이 추가되었다.

 

mine_block 요청을 해서 두 개의 트랜잭션을 포함한 새로운 블록을 만든다.

 

블록체인 내에 있는 모든 노드가 같은 체인을 갖도록 이 두 개의 노드에 합의를 적용한다.

 

 

먼저 체인을 불러오면 두 개의 트랜잭션이 있는 네 개의 블록을 포함한 체인인 것을 알 수 있다.

 

5002인 Kirill의 노드는 세 개의 블록만 가지고 있다.

따라서 replace_chain 요청을 하여 가장 긴 체인으로 교체한다.

 

다시 get_chain으로 같은지 확인한다.

 

5003 노드에서도 동일하게 replace_chain 요청으로 교체를 한다.

 

따라서 모든 체인에 네 개의 블록이 있는 것을 확인할 수 있다.

3개의 노드에서 모두 같은 체인을 갖고 있는 것이다.

반응형

'PBL > 블록체인' 카테고리의 다른 글

스마트 계약 만들기  (0) 2024.08.27
스마트 계약 직관적 이해  (0) 2024.08.17
암호화폐 트랜잭션 직관적 이해  (0) 2024.08.04
암호화폐 직관적 이해2  (0) 2024.08.04
암호화폐 직관적 이해1  (0) 2024.07.28