目錄
大概來(lái)說(shuō):
二、代碼注釋
1.添加交易方法(add_transaction函數(shù))
2.添加新的節(jié)點(diǎn)(add_node 函數(shù))
3、替換鏈的方法(replace_chain函數(shù))
總結(jié)
大概來(lái)說(shuō):
- 定義了一個(gè)名為Blockchain的類(lèi),用于構(gòu)建區(qū)塊鏈。
- 在Blockchain類(lèi)中,定義了創(chuàng)建區(qū)塊、獲取上一個(gè)區(qū)塊、工作量證明、哈希計(jì)算、驗(yàn)證區(qū)塊鏈等方法。
- 使用Flask框架創(chuàng)建了一個(gè)Web應(yīng)用,提供了挖礦、獲取整個(gè)區(qū)塊鏈和驗(yàn)證區(qū)塊鏈的API接口。
- 運(yùn)行Web應(yīng)用,監(jiān)聽(tīng)5000端口。
一、代碼展示
# 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# 時(shí)間戳
import datetime
import hashlib
import json# Flask可以定義Web應(yīng)用的路由(URL到Python函數(shù)的映射),并處理HTTP請(qǐng)求和響應(yīng)。
# jsonify是一個(gè)函數(shù),用于將Python對(duì)象轉(zhuǎn)換為JSON格式的響應(yīng)。
# 當(dāng)你在Flask路由函數(shù)中返回一個(gè)jsonify對(duì)象時(shí),F(xiàn)lask會(huì)自動(dòng)將該對(duì)象對(duì)應(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:
? ? # 初始化區(qū)塊鏈類(lèi)
? ? def __init__(self):
? ? ? ? self.transactions = [] ?# 存儲(chǔ)交易信息
? ? ? ? self.chain = [] ?# 存儲(chǔ)區(qū)塊鏈
? ? ? ? self.create_block(proof=1, previous_hash='0') ?# 創(chuàng)建創(chuàng)世區(qū)塊
? ? ? ? self.nodes = set() ?# 存儲(chǔ)網(wǎng)絡(luò)節(jié)點(diǎn)? ? # 創(chuàng)建一個(gè)新的區(qū)塊
? ? 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) ?# 將新區(qū)塊添加到鏈中
? ? ? ? return block ?# 返回創(chuàng)建的區(qū)塊? ? # 獲取鏈中最后一個(gè)區(qū)塊
? ? def get_previous_block(self):
? ? ? ? return self.chain[-1]? ? # 工作量證明(Proof of Work)
? ? 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? ? # 哈希函數(shù),用于計(jì)算區(qū)塊的哈希值
? ? def hash(self, block):
? ? ? ? encode_block = json.dumps(block, sort_keys=True).encode()
? ? ? ? return hashlib.sha256(encode_block).hexdigest()? ? # 驗(yàn)證區(qū)塊鏈的有效性
? ? 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? ? # 添加網(wǎng)絡(luò)節(jié)點(diǎn)
? ? def add_node(self, address):
? ? ? ? parsed_url = urlparse(address)
? ? ? ? self.nodes.add(parsed_url.netloc)? ? # 替換鏈,如果找到更長(zhǎng)的鏈則替換當(dāng)前鏈
? ? def replace_chain(self):
? ? ? ? network = self.nodes
? ? ? ? longest_chain = None
? ? ? ? max_length = len(self.chain)
? ? ? ? for node in network:
? ? ? ? ? ? response = requests.get(f'http://127.0.0.1:5000/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 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)
? ? 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']
? ? }
? ? 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
@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# 運(yùn)行Flask應(yīng)用
app.run(host='0.0.0.0', port=5000)
二、代碼注釋
注:下面對(duì)三個(gè)函數(shù)進(jìn)行講解,其他函數(shù)的詳解在我的另外一篇我的文章里“
創(chuàng)建一個(gè)簡(jiǎn)單的區(qū)塊鏈,并使用 Flask 框架提供一個(gè)簡(jiǎn)單的 Web 接口來(lái)與區(qū)塊鏈交互。-CSDN博客”add_transaction
函數(shù)、add_node
函數(shù)、replace_chain
函數(shù)
1.添加交易方法(add_transaction函數(shù))
這個(gè)函數(shù)用于向區(qū)塊鏈中添加交易記錄。它接受三個(gè)參數(shù):發(fā)送者(sender)、接收者(receiver)和交易金額(amount)。該函數(shù)將交易信息以字典的形式添加到當(dāng)前區(qū)塊的交易列表中,并返回下一個(gè)區(qū)塊的索引值。
? # 添加交易 #創(chuàng)建一個(gè)字典,包含發(fā)送者、接收者和金額信息,然后將這個(gè)字典添加到self.transactions 列表中。 ????????def add_transaction(self, sender, receiver, amount): ? ? ? ? self.transactions.append({ ? ? ? ? ? ? 'sender': sender, ? ? ? ? ? ? 'receiver': receiver, ? ? ? ? ? ? 'amount': amount ? ? ? ? }) #獲取當(dāng)前區(qū)塊鏈的最后一個(gè)區(qū)塊,并返回它的索引加1,這個(gè)索引加1將是下一個(gè)區(qū)塊的索引。???????? ????????previous_block = self.get_previous_block() ? ? ? ? return previous_block['index'] + 1
2.添加新的節(jié)點(diǎn)(add_node 函數(shù))
這個(gè)函數(shù)用于向網(wǎng)絡(luò)中添加新的節(jié)點(diǎn)。它接受一個(gè)參數(shù):節(jié)點(diǎn)地址(address)。該函數(shù)使用 urlparse
函數(shù)解析地址,并將解析后的主機(jī)名(netloc)添加到節(jié)點(diǎn)集合中。
# 添加網(wǎng)絡(luò)節(jié)點(diǎn)
def add_node(self, address):
# 使用urlparse函數(shù)解析提供的地址,這個(gè)函數(shù)是Python內(nèi)置的url解析模塊urllib.parse中的一個(gè)函數(shù)
? ? ? ? parsed_url = urlparse(address)# 通過(guò)urlparse得到的parsed_url對(duì)象中,netloc屬性包含了解析后的網(wǎng)絡(luò)位置,通常是主機(jī)名(有時(shí)也包括端口號(hào))
# 例如,如果提供的地址是 'http://localhost:5000',那么parsed_url.netloc將會(huì)是 'localhost:5000'
# 將解析得到的網(wǎng)絡(luò)位置添加到self.nodes集合中 # self.nodes是一個(gè)集合(set),它自動(dòng)去除了重復(fù)的元素,并且保持了添加的順序無(wú)關(guān)性
? ? ? ? self.nodes.add(parsed_url.netloc)
3、替換鏈的方法(replace_chain函數(shù))
這個(gè)函數(shù)函數(shù)用于替換當(dāng)前的區(qū)塊鏈。它首先獲取網(wǎng)絡(luò)中的所有節(jié)點(diǎn),然后遍歷每個(gè)節(jié)點(diǎn),通過(guò)發(fā)送 HTTP 請(qǐng)求獲取其區(qū)塊鏈信息。如果收到有效的響應(yīng),并且該鏈的長(zhǎng)度大于當(dāng)前鏈的長(zhǎng)度且有效,則將最長(zhǎng)鏈替換為當(dāng)前鏈。最后,根據(jù)是否成功替換鏈,返回相應(yīng)的布爾值。
def replace_chain(self):
# 獲取當(dāng)前區(qū)塊鏈網(wǎng)絡(luò)中的所有節(jié)點(diǎn)
? ? ? ? network = self.nodes
# 初始化最長(zhǎng)鏈為None,表示尚未找到更長(zhǎng)的鏈
? ? ? ? longest_chain = None# 獲取當(dāng)前鏈的長(zhǎng)度
? ? ? ? max_length = len(self.chain)# 遍歷網(wǎng)絡(luò)中的每個(gè)節(jié)點(diǎn)
? ? ? ? for node in network:# 嘗試從每個(gè)節(jié)點(diǎn)獲取區(qū)塊鏈信息
? ? ? ? ? ? response = requests.get(f'http://127.0.0.1:5000/get_chain')# 如果請(qǐng)求成功(HTTP狀態(tài)碼為200)
? ? ? ? ? ? if response.status_code == 200:# 從響應(yīng)中獲取鏈的長(zhǎng)度和鏈數(shù)據(jù)
? ? ? ? ? ? ? ? length = response.json()['length']
? ? ? ? ? ? ? ? chain = response.json()['chain']# 如果獲取的鏈比當(dāng)前已知最長(zhǎng)鏈更長(zhǎng),并且驗(yàn)證該鏈?zhǔn)怯行У?br> ? ? ? ? ? ? ? ? if length > max_length and self.is_chain_valid(chain):
# 更新最長(zhǎng)鏈長(zhǎng)度和最長(zhǎng)鏈數(shù)據(jù)
? ? ? ? ? ? ? ? ? ? max_length = length
? ? ? ? ? ? ? ? ? ? longest_chain = chain# 如果找到了更長(zhǎng)的有效鏈,則用它替換當(dāng)前鏈,并返回True
? ? ? ? if longest_chain:
? ? ? ? ? ? self.chain = longest_chain
? ? ? ? ? ? return True# 如果沒(méi)有找到更長(zhǎng)的鏈,或者找到的鏈無(wú)效,則返回False
? ? ? ? return False文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-857568.html
總結(jié)
這段代碼定義了一個(gè)Blockchain
類(lèi),它包含了創(chuàng)建區(qū)塊、驗(yàn)證工作量證明、添加交易、添加網(wǎng)絡(luò)節(jié)點(diǎn)、替換鏈等方法。然后,使用Flask框架創(chuàng)建了一個(gè)Web應(yīng)用,通過(guò)定義路由來(lái)處理不同的HTTP請(qǐng)求,如挖掘新區(qū)塊、獲取區(qū)塊鏈信息、驗(yàn)證區(qū)塊鏈的有效性等。最后,啟動(dòng)了Flask應(yīng)用,使其在端口5000上監(jiān)聽(tīng)請(qǐng)求。文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-857568.html
到了這里,關(guān)于使用了Python語(yǔ)言和Flask框架。創(chuàng)建一個(gè)區(qū)塊鏈網(wǎng)絡(luò),允許用戶通過(guò)HTTP請(qǐng)求進(jìn)行交互,如包括創(chuàng)建區(qū)塊鏈、挖礦、驗(yàn)證區(qū)塊鏈等功能。的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!