目錄
一、準(zhǔn)備工作:
1、創(chuàng)建三個python文件:
2、創(chuàng)建nodes.json文件
3、transaction.json文件
4、打開三個控制臺
二、在三個節(jié)點(diǎn)上進(jìn)行交互。
二、添加交易發(fā)布請求(a向b發(fā)送10000coin)
一、準(zhǔn)備工作:
1、創(chuàng)建三個python文件:
lancoin_node_5001.py、lancoin_node_5002.py、lancoin_node_5003.py。
它們每個都將連接到不同的端口,一個端口用于a,一個端口用于b,一個端口用于c。
a在端口5001上,b在端口5002上,c在端口5003上
代碼示例(lancoin_node_5001.py):
# Module 1 -Create a Cryptocurrency
#To be installed:
#Flask==0.12.2:pip install Flask==0.12.2
#Postman HTrp Client:https://www.getpostman.com
#requests==2.18.4:pip install requests=-2.18.4
#時間戳
import datetime
import hashlib
import json
#Flask可以定義Web應(yīng)用的路由(URL到Python函數(shù)的映射),并處理HTTP請求和響應(yīng)。jsonify是一個函數(shù),用于將Python對象轉(zhuǎn)換為JSON格式的響應(yīng)。當(dāng)你在Flask路由函數(shù)中返回一個jsonify對象時,F(xiàn)lask會自動將該對象對應(yīng)的數(shù)據(jù)轉(zhuǎn)換為JSON格式,并設(shè)置合適的HTTP響應(yīng)頭,以便客戶端可以正確解析響應(yīng)內(nèi)容。
from flask import Flask, jsonify,request
import requests
from uuid import uuid4
from urllib.parse import urlparse
# 1******Building a Blockchain
class Blockchain:
def __init__(self):
self.transactions=[]
self.chain=[]
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_oparation=hashlib.sha256(str(new_proof**2-previous_proof**2).encode()).hexdigest()
if hash_oparation[: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_oparation=hashlib.sha256(str(proof**2-previous_proof**2).encode()).hexdigest()
if hash_oparation[: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:
try:
response = requests.get(f'http://{node}/get_chain')
response.raise_for_status() # 這將拋出異常,如果請求失敗
except requests.exceptions.RequestException as e:
print(f"Failed to get the chain from {node}. Exception: {e}")
continue
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='a',amount=1)
block=blockchain.create_block(proof, previous_hash)
response={'message':'Congratulation,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 get_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
#Addling 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
#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 nodes provided", 400
for node in nodes:
blockchain.add_node(node)
# 將響應(yīng)構(gòu)建移到循環(huán)外,并在所有節(jié)點(diǎn)添加后才返回
response = {
'message': 'All the nodes are now connected. The Lancoin 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
app.run(host='0.0.0.0',port=5001)
lancoin_node_5002.py、lancoin_node_5003.py則是lancoin_node_5001.py中的mine_block函數(shù)的blockchain.add_transaction(sender=node_address,receiver='a',amount=1),a改為b、c,然后app.run(host='0.0.0.0',port=5001)中的5001改為5002、5003
2、創(chuàng)建nodes.json文件
{
"nodes":["http://127.0.0.1:5001",
"http://127.0.0.1:5002",
"http://127.0.0.1:5003"]
}
3、transaction.json文件
{
"sender":"",
"receiver":"",
"amount":
}
4、打開三個控制臺
在這里我用的是Spyder編譯器,打開三個控制臺,分別在控制臺是運(yùn)行各節(jié)點(diǎn),控制臺1運(yùn)行5001節(jié)點(diǎn),控制臺2運(yùn)行5002節(jié)點(diǎn),控制臺3運(yùn)行5003節(jié)點(diǎn),如圖所示
二、在三個節(jié)點(diǎn)上進(jìn)行交互。
(1)跳轉(zhuǎn)到postman,創(chuàng)建三個測試,分別對應(yīng)5001、5002、5003節(jié)點(diǎn)
(2)獲取鏈來查看創(chuàng)世區(qū)塊是否創(chuàng)建良好http://127.0.0.1:5001/get_chain、http://127.0.0.1:5002/get_chain、http://127.0.0.1:5003/get_chain
以5001為例子
(3)發(fā)出第一個請求(post),將發(fā)出我們的第一個發(fā)布請求以將節(jié)點(diǎn)相互連接。
我們現(xiàn)在想做的是連接節(jié)點(diǎn),因此我將返回到nodes.json文件,復(fù)制后返回postman發(fā)出請求,
按照圖內(nèi),將三個都按照圖上進(jìn)行相應(yīng)的修改
(4)測試共識
首先在5001節(jié)點(diǎn)(也就是a)上挖一個塊
可以通過獲取鏈請求(get_chain)來查看它,就會發(fā)現(xiàn)我的新鏈
然后在5002節(jié)點(diǎn)上(也就是b)、5003節(jié)點(diǎn)(也就是a)選擇替換鏈請求。下面以5002為例子
二、添加交易發(fā)布請求(a向b發(fā)送10000coin)
(1)先選擇post請求,點(diǎn)開transaction.json文件,復(fù)制以后回到postman,在5001節(jié)點(diǎn)上,如圖
2)然后再5001界面get一個http://127.0.0.1:5001/mine_block。創(chuàng)建這個包含兩筆交易的新區(qū)塊,其中一筆交易與我剛剛開采了這個新區(qū)塊并因此給我一個addcoin有關(guān),當(dāng)然還有a給b的交易,給b10000coin
(3)查看5001是否開采區(qū)塊,3個區(qū)塊,如圖
(4)查看5002的區(qū)塊,2個區(qū)塊
(5)查看5003的區(qū)塊,2個區(qū)塊
(6)達(dá)成共識,以確保區(qū)塊鏈中的每個節(jié)點(diǎn)都具有相同的鏈。在postman的5002節(jié)點(diǎn)界面再運(yùn)行一遍http://127.0.0.1:5002/replace_chain(get),然后在5003節(jié)點(diǎn)界面運(yùn)行http://127.0.0.1:5003/replace_chain,然后5002、5003節(jié)點(diǎn)也會有3個節(jié)點(diǎn)
(7)最后在三個節(jié)點(diǎn)中分別get請求一下get_chain,以檢查是否具有相同的鏈。以5002為例
注:本篇用的代碼解釋都可在我以往的文章中找到
“創(chuàng)建一個簡單的區(qū)塊鏈,并使用 Flask 框架提供一個簡單的 Web 接口來與區(qū)塊鏈交互。(持續(xù)更新)-CSDN博客”
“使用了Python語言和Flask框架。創(chuàng)建一個區(qū)塊鏈網(wǎng)絡(luò),允許用戶通過HTTP請求進(jìn)行交互,如包括創(chuàng)建區(qū)塊鏈、挖礦、驗(yàn)證區(qū)塊鏈等功能。-CSDN博客”文章來源:http://www.zghlxwxcb.cn/news/detail-861777.html
“使用Python,結(jié)合Flask框架,創(chuàng)建一個可以處理交易、挖礦新區(qū)塊、驗(yàn)證區(qū)塊鏈有效性,并能在網(wǎng)絡(luò)節(jié)點(diǎn)間同步的區(qū)塊鏈網(wǎng)絡(luò)。(持續(xù)更新)-CSDN博客”文章來源地址http://www.zghlxwxcb.cn/news/detail-861777.html
到了這里,關(guān)于創(chuàng)建一個區(qū)塊鏈,是由三個節(jié)點(diǎn)組成的去中心化網(wǎng)絡(luò)。的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!