![cover](https://img-blog.csdnimg.cn/img_convert/fad536e972e14ce4b37803185dc3b00c.png)
创建一个简单的区块链,并使用 Flask 框架提供一个简单的 Web 接口来与区块链交互。(持续更新)
本文演示了如何创建一个简单的区块链,并使用 Flask 框架提供一个简单的 Web 接口来与区块链交互。一、代码展示#时间戳#Flask可以定义Web应用的路由(URL到Python函数的映射),并处理HTTP请求和响应。jsonify是一个函数,用于将Python对象转换为JSON格式的响应。当你在Flask路由函数中返回一个jsonify对象时,Flask会自动将该对象对应的数据转换为JSON
目录
1.简单的区块链模拟实现,这段代码定义了一个简单的区块链类,可以创建一个新的区块链,并能够添加新的区块到链上,同时获取最新的区块信息。这个模拟的区块链可以用于教学或演示区块链的基本概念。
5、这段代码展示了如何使用 Flask 框架创建一个简单的 Web 应用程序,并结合之前定义的 Blockchain 类和相关方法来实现一个区块链挖矿的功能。
6、这段代码定义了一个 Flask 应用程序的路由处理函数,用于响应客户端对 /get_chain 路径的 GET 请求。当这个路径被访问时,这个函数将返回当前区块链的完整数据和一个表示链长度的计数。
7、这段代码是Flask应用中的一个路由处理函数,用于检查区块链的完整性和有效性
8、这行代码是 Flask 应用程序的启动命令,它会启动一个本地开发服务器,使得应用程序能够响应外部的 HTTP 请求
前言
本文演示了如何创建一个简单的区块链,并使用 Flask 框架提供一个简单的 Web 接口来与区块链交互。
一、代码展示
# Module 1 -Create a Blockchain
#时间戳
import datetime
import hashlib
import json
#Flask可以定义Web应用的路由(URL到Python函数的映射),并处理HTTP请求和响应。jsonify是一个函数,用于将Python对象转换为JSON格式的响应。当你在Flask路由函数中返回一个jsonify对象时,Flask会自动将该对象对应的数据转换为JSON格式,并设置合适的HTTP响应头,以便客户端可以正确解析响应内容。
from flask import Flask, jsonify
# 1******
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_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
#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
app.run(host='0.0.0.0',port=5000)
二、代码注释
1.简单的区块链模拟实现,这段代码定义了一个简单的区块链类,可以创建一个新的区块链,并能够添加新的区块到链上,同时获取最新的区块信息。这个模拟的区块链可以用于教学或演示区块链的基本概念。
#这行代码导入了Python的datetime模块,用于处理日期和时间。
import datetime
#这行代码导入了hashlib模块,用于生成哈希值,但在这段代码中并未使用到。
import hashlib
#用于处理JSON数据格式,但在这段代码中并未使用到
import json
#从flask模块中导入了Flask和jsonify两个对象。Flask是一个轻量级的Web应用框架,jsonify是一个函数,用于将Python对象转换为JSON格式的响应。
from flask import Flask,jsonify
#定义了一个名为Blockchain的类,用于模拟区块链的基本功能。
class Blockchain:
#这是Blockchain类的构造函数,用于初始化区块链实例。在这个函数中,创建了一个空字典self.chain来存储区块链中的区块,并通过调用self.create_block()方法创建了第一个区块。
def __init__(self):
self.chain=[]
#,创建了区块链的第一个区块。proof参数设置为1,previous_hash参数设置为字符串'0'。
self.create_block(proof=1,previous_hash='0')
#这是Blockchain类的一个方法,用于创建一个新的区块并将其添加到区块链中。方法接收两个参数:proof(工作量证明值)和previous_hash(前一个区块的哈希值)。
def create_block(self,proof,previous_hash):
#这行代码创建了一个新的字典block,它代表一个新的区块。index键对应的值是当前区块链中区块的数量加1,即新创建的区块的索引。
block={'index':len(self.chain)+1,
'timetamp':str(datetime.datetime.now()),
#block字典添加了proof键,其值是创建区块时提供的工作量证明值。
'proof':proof,
'previous_hash':previous_hash}
#新创建的区块添加到self.chain字典列表中,从而将新区块添加到区块链中。
self.blain.append(block)
#返回新创建的区块,可以用于验证或显示新区块的信息。
return block
#这是Blockchain类的一个方法,用于获取区块链中的最后一个区块。
def get_previous_block(self):
#这行代码返回self.chain列表中的最后一个元素,即最新的区块
return self.chain[-1]
2.这段代码是一个简单的工作量证明(Proof of Work)算法的实现,它是区块链技术中的一个关键概念。工作量证明是一种用来防止网络滥用和垃圾信息的机制,它要求用户在进行某些操作(如创建新区块)之前,必须完成一项计算工作。这个计算工作通常是解决一个难题,而解决这个难题的“答案”就是工作量证明。
#这行代码定义了一个名为proof_of_work的方法,它属于之前定义的Blockchain类。这个方法接收一个参数previous_proof,它代表前一个区块的工作量证明值。
def_proof_of_work(self,previous_proof)
#这行代码初始化一个新的变量new_proof,它的初始值设为1。这个变量将用于生成新的工作量证明。
new_proof=1
#初始化一个布尔变量check_proof,用于检查新生成的工作量证明是否满足条件。初始值设为False,表示还没有找到满足条件的工作量证明。
check_proof=False
#它会一直执行,直到check_proof变量的值为True,即找到了满足条件的工作量证明。
while check_proof is False:
#这行代码执行了核心的哈希计算操作。首先,它计算new_proof的平方减去previous_proof的平方的结果,然后将这个结果转换为字符串,并进行SHA-256哈希运算。hashlib.sha256()是Python中用于SHA-256算法的函数,.encode()将字符串转换为字节流,以便进行哈希运算。.hexdigest()将哈希结果转换为十六进制字符串。
hash_oparation=hashlib.sha256(str(new_proof**2-previous_proof**2).encode()).hexdigest()
#检查哈希结果的前四个字符是否为'0000'。这是工作量证明的条件,意味着新生成的工作量证明必须满足这个条件才能被接受。
if hash_oparation[:4]='0000':
check_proof=Ture
else
new_proof+=1
return new_proof
3.这段代码定义了一个名为 hash
的方法,它属于 Blockchain
类,用于计算区块链中某个区块的哈希值。哈希值是区块内容的唯一表示,它是通过哈希函数对区块数据进行计算得到的。在区块链中,哈希值用于确保数据的完整性和不可篡改性。
#它接收一个参数 block,这个参数代表一个区块的数据。在区块链的上下文中,一个区块通常包含多个字段,如 index、timestamp、proof、previous_hash 等。
def_hash(self,block):
#首先使用 json.dumps() 函数将区块数据 block 转换为 JSON 格式的字符串。sort_keys=True 参数确保 JSON 字符串的输出是键值对排序后的格式,这有助于生成一致的哈希值。接着,.encode() 方法将 JSON 字符串转换为字节串,这是因为哈希函数需要一个字节串作为输入。
encode_block=json.dumps(block,sort_keys=True).encode()
#使用 hashlib.sha256() 函数对字节串 encode_block 进行 SHA-256 哈希计算。SHA-256 是一种加密哈希函数,它可以将任意长度的输入数据转换为固定长度(256位)的哈希值。.hexdigest() 方法将计算得到的哈希值转换为十六进制字符串形式,并返回这个字符串作为区块的哈希值。
return hashlib.sha256(encode_block).hexdigest()
4、这段代码定义了一个名为 is_chain_valid
的方法,它用于验证一个区块链的有效性。具体来说,它检查链中的每个区块的 previous_hash
值是否与其前一个区块的哈希值相匹配,以及每个区块的工作量证明(Proof of Work)是否满足特定条件。
def is_chain_valid(self,chain):
#将区块链中的第一个区块赋值给变量 previous_block。这个区块是初始的“创世区块”,它的 previous_hash 通常设置为一个特定的值(如 '0' 或 '0000' 等)。
previous_block=chain[0]
#码初始化一个变量 block_index,用于跟踪当前正在验证的区块在区块链中的索引位置。由于 previous_block 是第一个区块,所以从索引 1 开始。
block_index=1
#用于遍历区块链中的每个区块。循环条件是 block_index 小于区块链的长度,确保每个区块都被检查。
while block_index<len(chain):
#根据 block_index 的值获取当前正在验证的区块。
block=chain[block_index]
#检查当前区块的 previous_hash 字段是否与 previous_block 经过 self.hash() 方法计算后的哈希值相匹配。如果不匹配,说明区块链的连续性被破坏,即某个区块被篡改或替换,因此返回 False。
if block['previous_hash'] !=self.hash(previous_block):
return False
#获取 previous_block 的 proof 字段值,并将其赋值给变量 previous_proof。
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。
previous_block=block
#增加 block_index 的值,以便在下一次循环中验证下一个区块。
block_index+=1
return True
这个方法是区块链安全性的一个重要保障,确保了区块链的不可篡改性和数据的完整性。通过验证每个区块的哈希值和工作量证明,可以确保区块链的每个区块都是按照正确的顺序和规则添加的。
5、这段代码展示了如何使用 Flask 框架创建一个简单的 Web 应用程序,并结合之前定义的 Blockchain
类和相关方法来实现一个区块链挖矿的功能。
#创建了一个 Flask 应用程序实例
app=Flask(__name__)
#创建了一个 Blockchain 类的实例,这个实例将用于管理区块链数据。
blockchain=Blockchain()
#这是一个装饰器,用于定义 Flask 应用程序的路由。当用户访问 /mine_block 路径时,并且请求方法为 GET,就会调用 mine_block 函数。
@app.route('mine_block',methods=['GET'])
#定义了一个名为 mine_block 的函数,它是 /mine_block 路径的处理函数。
def mine_block():
#这行代码调用 blockchain 实例的 get_previous_block 方法来获取区块链中最后一个区块的信息。
previous_block=blockchain.get_previous_block()
#这行代码从上一个区块中提取 proof(工作量证明)值。
previous_proof=previous_block['proof']
#这行代码调用 blockchain 实例的 proof_of_work 方法来计算新的工作量证明值。
proof=blockchain.proof_of_work(previous_proof)
#这行代码调用 blockchain 实例的 hash 方法来获取上一个区块的哈希值。
previous_hash=blockchain.hash(previous_block)
#这行代码调用 blockchain 实例的 create_block 方法来创建一个新的区块,新的区块包含新的工作量证明值和上一个区块的哈希值。
block=blockchain.create_block(proof, previous_hash)
#这行代码创建了一个字典 response,用于存储响应信息。这个字典包含了恭喜消息、新挖矿区块的索引、时间戳、工作量证明值和前一个区块的哈希值。
response={'message':'Congratulation,you just mined a block',
'index':block['index'],
'timestamp':block['timestamp'],
'proof':block['proof'],
'previous_hash':block['previous_hash']}
#这行代码使用 Flask 的 jsonify 函数将 response 字典转换为 JSON 格式的响应,并返回状态码 200。200 表示请求成功。
return jsonify(response),200
这段代码通过 Flask 创建了一个 Web 应用程序,用户可以通过访问 /mine_block
路径来触发挖矿过程。应用程序将执行工作量证明算法来创建一个新的区块,并将其添加到区块链中。然后,它会向用户返回新挖矿区块的相关信息。这是一个简单但有效的区块链挖矿 Web 应用程序的实现。
6、这段代码定义了一个 Flask 应用程序的路由处理函数,用于响应客户端对 /get_chain
路径的 GET
请求。当这个路径被访问时,这个函数将返回当前区块链的完整数据和一个表示链长度的计数。
@app.route('/get_chain',methods=['GET'])
def get_chain():
#在 get_chain 函数内部,创建了一个名为 response 的字典,它包含两个键值对。第一个键值对是 'chain',它的值是 blockchain 实例的 chain 属性,这是一个包含区块链中所有区块的列表。第二个键值对是 'length',它的值是 blockchain.chain 的长度,即区块链中区块的数量。
response={'chain':blockchain.chain,
'length':len(blockchain.chain)}
return jsonify(response),200
客户端(如 Web 浏览器或其他 HTTP 客户端)向 Flask 应用程序发送一个 GET
请求到 /get_chain
路径时,应用程序将调用 get_chain
函数,并将当前区块链的完整数据和区块数量作为 JSON 响应返回给客户端。这样,客户端就可以查看和验证区块链的状态。这个功能对于区块链的透明度和可审计性是非常重要的。
7、这段代码是Flask应用中的一个路由处理函数,用于检查区块链的完整性和有效性
#Checking if the Blockchain
@app.route('/is_valid',methods=['GET'])
定义了一个名为get_valid的函数,它是当访问/is_valid路由时被调用的。
def get_valid():
这一行调用了Blockchain类的一个方法is_chain_valid,传入了blockchain.chain作为参数。blockchain.chain是存储区块链数据的数据结构(在这个例子中是一个列表)。is_chain_valid方法会检查区块链的每个区块,确保它们的哈希值和前一个区块的哈希值是正确的,以及每个区块的工作量证明(Proof of Work)也是正确的。如果所有检查都通过,它会返回True,表示区块链是有效的;
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
8、这行代码是 Flask 应用程序的启动命令,它会启动一个本地开发服务器,使得应用程序能够响应外部的 HTTP 请求
app.run(host='0.0.0.0',port=5000)
三、扩展(postman测试)
运行成功以后
1、模拟挖矿过程,并在区块链上创建一个新的区块:在postman输入http://127.0.0.1:5000/mine_block(网址得看你运行成功以后给出的是什么,我给出的是这个)
2、查看当前区块链的状态,包括所有已经挖掘的区块和区块链的总长度:在postman中输入“http://127.0.0.1:5000/get_chain”
3、验证区块链是否有效:输入“http://127.0.0.1:5000/is_valid”
总结
总的来说,这段代码演示了如何创建一个简单的区块链,并使用 Flask 框架提供一个简单的 Web 接口来与区块链交互。用户可以通过 GET 请求来挖矿、获取区块链信息和验证区块链的有效性。这个示例展示了区块链技术的基本概念和 Flask Web 应用的创建与路由处理。
更多推荐
所有评论(0)