使用了Python语言和Flask框架。创建一个区块链网络,允许用户通过HTTP请求进行交互,如包括创建区块链、挖矿、验证区块链等功能。(持续更新)

本文主要是介绍使用了Python语言和Flask框架。创建一个区块链网络,允许用户通过HTTP请求进行交互,如包括创建区块链、挖矿、验证区块链等功能。(持续更新),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

目录

大概来说:

二、代码注释

1.添加交易方法(add_transaction函数)

2.添加新的节点(add_node 函数)

3、替换链的方法(replace_chain函数)

总结


大概来说:

  1. 定义了一个名为Blockchain的类,用于构建区块链。
  2. 在Blockchain类中,定义了创建区块、获取上一个区块、工作量证明、哈希计算、验证区块链等方法。
  3. 使用Flask框架创建了一个Web应用,提供了挖矿、获取整个区块链和验证区块链的API接口。
  4. 运行Web应用,监听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

# 时间戳
import datetime
import hashlib
import json

# Flask可以定义Web应用的路由(URL到Python函数的映射),并处理HTTP请求和响应。
# jsonify是一个函数,用于将Python对象转换为JSON格式的响应。
# 当你在Flask路由函数中返回一个jsonify对象时,Flask会自动将该对象对应的数据转换为JSON格式,
# 并设置合适的HTTP响应头,以便客户端可以正确解析响应内容。
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]

    # 工作量证明(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

    # 哈希函数,用于计算区块的哈希值
    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':
                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 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

# 运行Flask应用
app.run(host='0.0.0.0', port=5000)

二、代码注释

注:下面对三个函数进行讲解,其他函数的详解在我的另外一篇我的文章里“创建一个简单的区块链,并使用 Flask 框架提供一个简单的 Web 接口来与区块链交互。-CSDN博客”add_transaction 函数、add_node 函数、replace_chain 函数

1.添加交易方法(add_transaction函数)

这个函数用于向区块链中添加交易记录。它接受三个参数:发送者(sender)、接收者(receiver)和交易金额(amount)。该函数将交易信息以字典的形式添加到当前区块的交易列表中,并返回下一个区块的索引值。

  # 添加交易
#创建一个字典,包含发送者、接收者和金额信息,然后将这个字典添加到self.transactions
列表中。def add_transaction(self, sender, receiver, amount):self.transactions.append({'sender': sender,'receiver': receiver,'amount': amount})
#获取当前区块链的最后一个区块,并返回它的索引加1,这个索引加1将是下一个区块的索引。        previous_block = self.get_previous_block()return previous_block['index'] + 1

2.添加新的节点(add_node 函数)

这个函数用于向网络中添加新的节点。它接受一个参数:节点地址(address)。该函数使用 urlparse 函数解析地址,并将解析后的主机名(netloc)添加到节点集合中。

# 添加网络节点

def add_node(self, address):

# 使用urlparse函数解析提供的地址,这个函数是Python内置的url解析模块urllib.parse中的一个函数
        parsed_url = urlparse(address)

# 通过urlparse得到的parsed_url对象中,netloc属性包含了解析后的网络位置,通常是主机名(有时也包括端口号)

# 例如,如果提供的地址是 'http://localhost:5000',那么parsed_url.netloc将会是 'localhost:5000'

# 将解析得到的网络位置添加到self.nodes集合中 # self.nodes是一个集合(set),它自动去除了重复的元素,并且保持了添加的顺序无关性
        self.nodes.add(parsed_url.netloc)

3、替换链的方法(replace_chain函数)

这个函数函数用于替换当前的区块链。它首先获取网络中的所有节点,然后遍历每个节点,通过发送 HTTP 请求获取其区块链信息。如果收到有效的响应,并且该链的长度大于当前链的长度且有效,则将最长链替换为当前链。最后,根据是否成功替换链,返回相应的布尔值。

def replace_chain(self):
    # 获取当前区块链网络中所有节点的集合
    network = self.nodes
    
    # 初始化最长链为 None,表示我们尚未找到比当前链更长的链
    longest_chain = None
    
    # 获取当前链的长度,用于比较
    max_length = len(self.chain)
    
    # 遍历网络中的每个节点
    for node in network:
        try:
            # 尝试从每个节点获取区块链信息
            response = requests.get(f'http://{node}/get_chain')
            # 如果请求成功,但没有返回成功的状态码(如200),将抛出异常
            response.raise_for_status()
        except requests.exceptions.RequestException as e:
            # 如果请求失败(例如,节点不可达或网络问题),打印错误并继续下一个节点
            print(f"Failed to get the chain from {node}. Exception: {e}")
            continue
    
        # 如果请求成功且状态码为200
        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  # 返回 True 表示链已被替换
    else:
        return False  # 如果没有找到更长的链,返回 False 表示链没有被替换


总结

这段代码定义了一个Blockchain类,它包含了创建区块、验证工作量证明、添加交易、添加网络节点、替换链等方法。然后,使用Flask框架创建了一个Web应用,通过定义路由来处理不同的HTTP请求,如挖掘新区块、获取区块链信息、验证区块链的有效性等。最后,启动了Flask应用,使其在端口5000上监听请求。

这篇关于使用了Python语言和Flask框架。创建一个区块链网络,允许用户通过HTTP请求进行交互,如包括创建区块链、挖矿、验证区块链等功能。(持续更新)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/939400

相关文章

GIN框架_会话

会话 会话控制涉及到cookie和session的使用 1. cookie HTTP是无状态协议,服务器不能记录浏览器的访问状态,也就是说服务器不能区分两次请求是否由同一个客户端发出Cookie就是解决HTTP协议无状态的方案之一Cookie实际上就是服务器保存在浏览器上的一段信息。浏览器有了Cookie之后,每次向服务器发送请求时都会同时将该信息发送给服务器,服务器收到请求后,就可以根据该

虚拟化技术 使用vSphere Web Client管理ESXi主机

一、实验内容 通过vSphere Web Client将ESXi主机连接到iSCSI共享存储通过vSphere Web Client,使用共享存储创建虚拟机并安装windows 2008 R2操作系统通过vSphere Web Client,为虚拟机创建快照 二、、实验主要仪器设备及材料 安装有64位Windows操作系统的台式电脑或笔记本电脑,建议4C8G或以上配置已安装VMware Wo

作业优化——在step中使用异步操作

异步处理就是:如果一条数据正在处理,后面又来了一条数据,可以不用等前面的数据处理完进行处理。异步处理也是用多线程实现的,但与上章节在step中使用多线程有所不同,多线程方式:每个线程处理一批数据,互不干扰,开辟晚的线程有可能比开辟早的线程先执行完毕;异步方式:异步方式按读取数据的先后顺序执行,读取一批数据后交给线程处理,又读取一批数据后,如果前面的数据还没执行完毕,可以不用等待,从线程池中拿新的线

作业优化——在step中使用多线程

假设一个step中要执行一项读数据、然后处理数据,最后写数据的任务,如果数据非常大,需要很长的一段的时间才能处理完,此种情况下就可以创建多个线程来同时执行该任务,缩短任务的执行时间。但是要在读的任务上加 Synchronized 标识,保证同一个时刻只有一个线程在读,使每个线程读取的数据不一样。如果不加Synchronized,有可能两个线程在同时读数据,读的数据会有部分重叠,影响数据的处理。

Python操作Redis(连接方式、通用操作、字符串操作、Hash操作、List操作)

Python操作Redis 目录 Python操作Redis普通连接连接池连接通用操作字符串操作Hash操作List操作 安装:pip install redis 普通连接 每次连接都会创建新的连接 import redisconn = redis.Redis(host='127.0.0.1',port=6379,db=0, # 数据库编号(Redis支持多数据库)pas

用户研究方法论中定性研究的优缺点分析

定性研究是一种探索性研究方法,它侧重于理解用户的感受、态度、动机和行为背后的原因。以下是定性研究的一些优缺点: 优点: 深入理解:定性研究能够提供对用户行为和态度的深入理解,帮助研究者捕捉到用户的真实感受和动机。 探索性:它允许研究者探索未知的领域,发现新的问题和见解,而不是仅仅验证已知的假设。 灵活性:定性研究通常具有较高的灵活性,研究者可以根据研究过程中出现的新信息调整研究方向。

C语言 | Leetcode C语言题解之第92题反转链表II

题目: 题解: struct ListNode *reverseBetween(struct ListNode *head, int left, int right) {// 因为头节点有可能发生变化,使用虚拟头节点可以避免复杂的分类讨论struct ListNode *dummyNode = malloc(sizeof(struct ListNode));dummyNode->val =

web前端框架设计第十课-自定义指令

web前端框架设计第十课-自定义指令 一.预习笔记 1.注册全局指令(先注册在使用) 2.注册局部指令(要找标签有的属性) 3.钩子函数 4.binding对象参数 二.课堂笔记 三.课后回顾 –行动是治愈恐惧的良药,犹豫拖延将不断滋养恐惧

cachetools,一个超酷的 Python 库!

更多Python学习内容:ipengtao.com 大家好,今天为大家分享一个超酷的 Python 库 - cachetools。 Github地址:https://github.com/tkem/cachetools 在数据密集型应用中,缓存是优化性能和响应速度的关键技术之一。Python的cachetools库提供了一套灵活且强大的工具,用于在Python项目中实现缓存机制。本文将全面介

创建空List的两种方法

之前一直使用: List<String> list = new ArrayList<String>(); 后来学到了一个新的方法: List<String> list = Collections.emptyList(); 如果不准备对list进行修改,只用来返回值。那么第二个方法更好。因为第二个方法生成的空list有三个优点: 不可修改(immutable);效率高(more effic