[区块链] 持久化运行区块链 | 并通过HTTP访问

实验目标

以Web服务的形式持久化运行区块链,并通过HTTP接口的形式实现对区块链的操作。

实验内容

  • 构建区块链的区块对象和区块链对象。
  • 使用Flask等Web服务框架运行持久化的进程,实现基于HTTP接口实现新区块的添加功能以及传递区块索引查询区块链中的区块功能。

实验步骤

1、创建项目以及依赖

1)打开PyCharm创建一个项目simple_blockchain,存储在桌面上,采用IDE的虚拟环境。

2)安装相关依赖包,json、hashlib、datetime以及flask(执行pip install flask)

2、创建区块对象和区块链对象

  1. 区块由区块头和区块体两个部分构成,且通过哈希链以JSON格式相互链接在一起。

于是创建区块对象的代码应包括如下三部分:

class Block(object):
def init(self, index, prev_hash, data, timestamp, bits):
"""
区块的初始化方法,在创建一个区块需传入包括索引号等相关信息

:param index: 区块索引号
:param prev_hash: 前一区块的哈希值
:param data: 区块中需保存的记录
:param timestamp: 区块生成的时间戳
:param bits: 区块需传入的比特值(预留)
"""
def to_json(self):
"""
将区块内容以JSON的形式输出
:return:
"""
def calc_block_hash(self):
"""
生成区块对应的哈希值
:return:
"""

2)在区块链系统中,数据的存储以账本的方式实现,账本中包含许多区块,区块间以链式的方式两两相连。

于是创建区块链对象的代码应包括如下五部分:

class Blockchain(object):
def init(self):
"""
初始化区块链对象,操作包括:
1、定义一个以chain命名的区块链数组
2、在链中加入创世区块(genesis block)
"""
def add_block(self, block):
"""

将新的区块加入区块链chain中,该方法将不被外界调用
:param block: 新加入的区块
:return:
"""
def query_block_info(self, index=0):
"""
通过索引值查询区块链chain中的区块信息
:param index: 查询区块的索引值
:return:
"""
def create_genesis_block(self):
"""
创建创世区块,创世区块内容如下:
index -> 设置为0,代表第一个区块
prev_hash -> 设置为64个"0"作为默认参数
data -> 存储一段字符串
:return:
"""
def add_new_block(self, data):
"""
可供调用的方法,用于添加新的区块
:param data:
:return:
"""

3、编写与实现相应HTTP接口,实现账本添加和查询功能。

1)将第2步创建好的区块对象和区块链对象作为区块链账本系统模型models,并测试该模型是否构建成功,测试代码test.py如下:

import models

blockchain = models.Blockchain()

print(blockchain.query_block_info(0))

from time import sleep

sleep(1)

blockchain.add_new_block("新增的区块")

print(blockchain.query_block_info(1))

执行输出结果如下:

  1. 在app.py文件中加入区块添加和区块查询的HTTP请求响应,一定要引用models

@app.route('/add', methods=['POST'])

def add():

"""

区块链添加功能API

:return:

"""

body = request.json

index = blockchain.add_new_block(body['data'])

return json.dumps({

'code':200,

'data':index

})

4、使用Postman进行验证接口正确性

1)区块添加功能

2)区块查询功能

实验

  1. 以寝室为单位,创建一个姓名区块链。(运行截图)

比如一个寝室4个人,张三------李四------王五------钱六

python 复制代码
import hashlib
import json
import time

class Block:
    def __init__(self, index, data, prev_hash):
        self.index = index
        self.timestamp = time.strftime("%Y/%m/%d %H:%M:%S")
        self.data = data  # 寝室成员姓名
        self.prev_hash = prev_hash
        self.nonce = "00000000"
        self.bits = "1e777777"
        self.hash = self.calculate_hash()

    def calculate_hash(self):
        # 计算区块的哈希值
        block_string = json.dumps({
            "index": self.index,
            "timestamp": self.timestamp,
            "data": self.data,
            "prev_hash": self.prev_hash,
            "nonce": self.nonce,
            "bits": self.bits
        }, sort_keys=True).encode()
        
        return hashlib.sha256(block_string).hexdigest()

class Blockchain:
    def __init__(self):
        # 创建创世区块
        self.chain = [self.create_genesis_block()]

    def create_genesis_block(self):
        # 创建创世区块
        return Block(0, "这是第一个区块(创世区块)", "0" * 64)

    def get_latest_block(self):
        # 获取最新的区块
        return self.chain[-1]

    def add_block(self, data):
        # 添加新区块
        prev_block = self.get_latest_block()
        new_block = Block(prev_block.index + 1, data, prev_block.hash)
        self.chain.append(new_block)

    def is_chain_valid(self):
        # 验证区块链的完整性
        for i in range(1, len(self.chain)):
            current_block = self.chain[i]
            prev_block = self.chain[i-1]

            # 验证当前区块的哈希值
            if current_block.hash != current_block.calculate_hash():
                return False

            # 验证区块链的连续性
            if current_block.prev_hash != prev_block.hash:
                return False

        return True

    def display_chain(self):
        # 显示区块链的所有区块
        for block in self.chain:
            print(json.dumps({
                "index": block.index,
                "timestamp": block.timestamp,
                "data": block.data,
                "hash": block.hash,
                "prev_hash": block.prev_hash,
                "nonce": block.nonce,
                "bits": block.bits
            }, indent=2, ensure_ascii=False))
            print()

# 创建区块链并添加寝室成员
def main():
    # 创建区块链实例
    dorm_chain = Blockchain()

    # 添加寝室成员
    members = [..."lvy"]
    
    # 将每个成员添加到区块链中
    for member in members:
        dorm_chain.add_block(member)

    # 显示整个区块链
    print("寝室成员区块链:")
    print("=" * 50)
    dorm_chain.display_chain()

    # 验证区块链的完整性
    print(f"区块链是否有效: {dorm_chain.is_chain_valid()}")

if __name__ == "__main__":
    main() 
  1. 利用HTTP接口实现GET查询"学号+姓名"的信息。(运行截图)
python 复制代码
from flask import Flask, jsonify
from blockchain import Blockchain

app = Flask(__name__)

# 创建区块链实例
blockchain = Blockchain()

# 初始化区块链数据
def init_blockchain():
    # 添加寝室成员(学号+姓名)
    members = [
        "000000000000+lvy",
        "111111111111+张三",
        "222222222222+李四",
        "333333333333+王五"
    ]
    
    # 将每个成员添加到区块链中
    for member in members:
        blockchain.add_block(member)

# 初始化区块链
init_blockchain()

@app.route('/get_chain', methods=['GET'])
def get_chain():
    """获取完整的区块链"""
    response = {
        'chain': [],
        'length': len(blockchain.chain)
    }
    
    for block in blockchain.chain:
        response['chain'].append({
            'index': block.index,
            'timestamp': block.timestamp,
            'data': block.data,
            'hash': block.hash,
            'prev_hash': block.prev_hash,
            'nonce': block.nonce,
            'bits': block.bits
        })
    
    return jsonify(response), 200

@app.route('/get_member/<student_id>', methods=['GET'])
def get_member(student_id):
    """根据学号查询成员信息"""
    for block in blockchain.chain:
        if block.data.startswith(student_id):
            return jsonify({
                'status': 'success',
                'data': block.data,
                'block_info': {
                    'index': block.index,
                    'timestamp': block.timestamp,
                    'hash': block.hash
                }
            }), 200
    
    return jsonify({
        'status': 'error',
        'message': '未找到该学号对应的信息'
    }), 404

if __name__ == '__main__':
    app.run(debug=True, port=5000) 
相关推荐
这儿有一堆花5 小时前
什么是智能合约?区块链上的自动化契约
自动化·区块链·智能合约
Sui_Network9 小时前
Sui 上线两周年,掀起增长「海啸」
人工智能·物联网·游戏·web3·区块链·智能合约
数据与人工智能律师1 天前
互联网法院在NFT、元宇宙等新兴领域的规则创新
大数据·网络·人工智能·算法·区块链
九章云极AladdinEdu1 天前
算力经济模型推演:从中心化到去中心化算力市场的转变(区块链+智能合约的算力交易原型设计)
人工智能·机器学习·去中心化·区块链·智能合约·gpu算力·量子计算
这个懒人1 天前
第一节:Web3开发概述
web3·区块链
wdip151 天前
医疗健康软件专利:给生命科学装个 “智能防盗门“
大数据·人工智能·系统架构·区块链·软件工程·健康医疗·模块测试
常州北格数字孪生2 天前
宁德时代区块链+数字孪生专利解析:去中心化身份认证重构产业安全底座
区块链·数字孪生·身份认证·宁德时代·专利技术
giszz2 天前
【Web3】上市公司利用RWA模式融资和促进业务发展案例
人工智能·web3·区块链
胡耀超2 天前
哈希函数详解(SHA-2系列、SHA-3系列、SM3国密)案例:构建简单的区块链——密码学基础
区块链·密码学·哈希算法·数据安全·sha·sm3
尽-欢2 天前
以太坊智能合约开发框架:Hardhat v2 核心功能从入门到基础教程
单元测试·区块链·智能合约