代码编织梦想

用Python实现一条区块链

点击链接获取可执行文件

本文使用 python 实现了一条简单的区块链。主要分两个模块:实现每个区块的结构和相关的方法、实现整条区块链的结构和相关的方法。下面是对这两个模块的描述。

每个区块主要包括两个成员:区块头和区块体。其中,区块头存储和区块本身相关的一些信息,例如索引值、时间戳、前驱区块的哈希值、本区块的哈希值等;区块体存储交易序列,用一个 list 结构来表示。区块中的方法主要包括两个:根据交易序列获取哈希值、结构化打印本区块的信息。

区块的整体结构如下所示:

在这里插入图片描述

# 实现每个区块的结构和相关的方法
import json
from datetime import datetime


# 区块链中每一个block的结构
class Block():
    def __init__(self, index=0, timestamp=0, previous_hash=0, 
                 merkle_root=0, nonce=0, transactions=None):
        self.block_header = {'index': index, 
                             'timestamp': datetime.timestamp(datetime.now()), 
                             'previous_hash': previous_hash,
                             'merkle root': merkle_root, 'nonce': nonce}
        self.transactions = transactions
        
        # 根据交易信息来计算merkle_root
        self.block_header['merkle root'] = self.get_merkle_root().hash_value
    
    
    # merkle tree中的结点
    class MerkleNode:
        def __init__(self, node_value, node_id):
            self.left = None
            self.right = None
            self.node_value = node_value
            self.node_id = node_id
            self.hash_value = hashlib.sha256(str(node_value).encode('utf-8')).hexdigest()

    # 获取merkle tree根节点的哈希值
    def get_merkle_root(self):
        node_id = 0
        nodes = []
        for transaction in self.transactions:
            nodes.append(self.MerkleNode(transaction, node_id))
            node_id += 1
        while len(nodes) != 1:
            # 为当前层的结点创建父结点
            parent_nodes = []
            # 为每一对node生成一个parent
            for i in range(0, len(nodes), 2):
                left_node = nodes[i]
                if i + 1 < len(nodes):
                    right_node = nodes[i + 1]
                else:
                    parent_nodes.append(nodes[i])
                    break
                combined_hash_value = left_node.hash_value + right_node.hash_value
                parent_node = self.MerkleNode(combined_hash_value, node_id)
                node_id += 1
                parent_node.left = left_node
                parent_node.right = right_node
                parent_nodes.append(parent_node)
            # 进行下一层结点哈希值的计算
            nodes = parent_nodes
        return nodes[0]
    
    # 打印本区块的信息
    def print_block(self):
        print_format = {'block header': self.block_header, 
                        'transactions': self.transactions}
        print(json.dumps(print_format, indent=4))

整条区块链主要包括五个成员变量,分别用于定义各区块的容量、存储总的交易序列、存储每一个区块的数据结构、存储新构建的当前区块、挖矿难度。

创世区块产生的逻辑为:当用户初始化一条区块链后,此时区块链中的数据变量也初始化了,但还没有一个实例化的区块。随着交易的累积,到达产生新块的阈值后,区块链会构造出它的第一个新区块,称为创世区块。相比于别的区块,它的特殊点仅仅在于nonce初始值为10,且不需要工作量证明操作,而后续区块的nonce值都根据前驱区块的nonce值计算出来。

新区块产生的逻辑为:每当交易池达到阈值后,分布式网络上的矿工会根据前驱区块的nonce值来不断寻找一个符合要求的数值。当成功找到该值后,该矿工会可以获得构造新块的权力,并将该值作为nonce存储在当前区块中。

工作量证明算法的逻辑为:记前驱区块的nonce值为p,矿工随机选取一个数值p’(本实验中假设该值均为0),循环计算target=hash(p*p’),直到target[0:k]都是0为止(k是设置的挖矿难度)。当成功找到该值后,矿工获得构造新块的权力,并将该值作为nonce存储到新块中。

# 实现整条区块链的结构和相关的方法
class Blockchain(object):
    def __init__(self, block_transaction_capacity, difficulty):
        """
        创建交易池、本地区块链并添加创世区块
        """
        # 每个区块最多储存block_transaction_capacity笔交易
        self.block_transaction_capacity = block_transaction_capacity
        self.transaction_pool = []
        self.chain = []
        # TODO: 创建创世区块并加入区块链
        self.current_block = None
        # 挖矿难度
        self.difficulty = difficulty

    def add_block(self, proof, previous_hash=None):
        self.current_block = Block(nonce=proof, transactions=self.transaction_pool
                                   [-self.block_transaction_capacity:], previous_hash=previous_hash, 
                                   index=len(self.chain))
        self.chain.append(self.current_block)


    def add_transaction(self, sender, receiver, amount):
        transaction = str(sender) + ' ' + str(receiver) + ' ' + str(amount)
        self.transaction_pool.append(transaction)
        
        pool_size = len(self.transaction_pool)

        # 交易池就绪,应该创建新区块
        if pool_size % self.block_transaction_capacity == 0:
            # 先处理创世块
            if len(self.chain) == 0:
                self.current_block = Block(nonce=100, transactions=self.transaction_pool
                                           [-self.block_transaction_capacity:])
                self.chain.append(self.current_block)
            else:
                # 获取当前块的哈希值
                current_block_hash = self.__last_block()
                # 执行计算任务,并获取工作量证明
                pre_proof = self.current_block.block_header['nonce']
                proof = self.proof_of_work(pre_proof)
                # 计算完成,添加区块
                self.add_block(proof, current_block_hash)
            
        return True


    def __last_block(self):
        return self.current_block.block_header['merkle root']


    def __hash(block):
        block_string = json.dumps(block, sort_keys=True).encode()
        return hashlib.sha256(block_string).hexdigest()


    def proof_of_work(self, pre_proof):
        p = 0
        target = '1' * 100
        
        while not target[0:difficulty] == '0' * self.difficulty:
            target = hashlib.sha256(str(p * pre_proof).encode('utf-8')).hexdigest()
            p += 1
        return p


    def print(self):
        print('\033[1;31m', 
              len(self.chain), 'blocks and', len(self.transaction_pool),
              'transactions in this private chain:', 
              ':\033[0m')
        idx = 0
        for block in self.chain:
            print('\033[1;31m', 'Block', idx, ':\033[0m')
            idx += 1
            block.print_block()
        pending_num = len(self.transaction_pool) % self.block_transaction_capacity
        if pending_num == 0:
            print('\033[1;31m',
                  '0 pending transactions in this private chain.'
                  '\033[0m')
        else:
            print('\033[1;31m',
                  pending_num, ' pending transactions in this private chain:'
                  '\033[0m')
            print(self.transaction_pool[-pending_num:])

下面是测试部分。首先定义好区块链的结构后,随机生成交易双方的用户名和交易额,不断将这些交易信息输入到区块链中,最后打印整条区块链的结构。

import random


# 定义每个块所能存储的交易数
block_transaction_capacity = 4
# 定义总的交易数量
num_all_transactions = 9
# 定义挖矿难度(为k表示要求哈希前k位为0)
difficulty = 5
# 初始化本地区块链
blockchain = Blockchain(block_transaction_capacity, difficulty)

seed = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWX0123456789'

def generate_transactions(num_all_transactions):
    for i in range(num_all_transactions):
        random_sender, random_receiver = [], []
        for i in range(6):
            random_sender.append(random.choice(seed))
            random_receiver.append(random.choice(seed))
        random_sender = ''.join(random_sender)
        random_receiver = ''.join(random_receiver)
        yield random_sender, random_receiver, random.uniform(0, 100000)


for sender, receiver, amount in generate_transactions(num_all_transactions):
    blockchain.add_transaction(sender, receiver, amount)

# 打印区块链结构
blockchain.print()

程序运行结果为:

在这里插入图片描述

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/Elford/article/details/128005227

区块链很难吗? 40行python开发一个区块链_coxie带你学编程的博客-爱代码爱编程

尽管有人认为区块链目前还是个不成熟的解决方案,但它无疑称得上是计算机发展历史上的一个奇迹。但是,到底区块链是什么呢? 我们将通过动手实现一个迷你的区块链来帮你真正理解区块链技术的核心原理。python源代码保存在Github。 区块链 区块链是一个公开的数字账本,它按时间顺序记录比特币或其他加密货币发生的交易。 更一般的讲,区块链是一个公共数据库,

使用 python 从零开始开发区块链应用程序_链客区块链技术问答社区的博客-爱代码爱编程

链客,专为开发者而生,有问必答! 此文章来自区块链技术社区,未经允许拒绝转载。 “区块链”是什么? 区块链是一种存储数字数据的方式。数据可以是任何内容。对于比特币,它是事务(在帐户之间转移比特币),它甚至可以是文件;

python区块链开发_Fabric区块链Python开发详解-爱代码爱编程

Hyperledger Fabric是最流行的联盟区块链平台。Fabric区块链Python开发详解课程 涵盖Fabric区块链的核心概念、Fabric网络搭建、Node链码开发、Python应用开发等, 并提供关键知识点的预置代码,适合Python工程师快速掌握Fabric区块链应用开发技能。 访问网址:Fabric区块链Python开发详解。 1、Fa

python区块链开发_Python区块链终极指南:第1部分-爱代码爱编程

“Python是一种具有动态语义的解释性,面向对象的高级编程语言。它的高级内置数据结构与动态类型和动态绑定相结合,使其对于快速应用程序开发以及用作将现有组件连接在一起的脚本或粘合语言非常有吸引力。” Python区块链终极指南:第1部分 Python是目前最流行,功能最强大的语言之一。它不仅对初学者极为友好,而且在许多不同领域也发现了应用。实际上,根据IE

python区块链开发_10个值得收藏的Python区块链开源项目-爱代码爱编程

Python不是主流的区块链底层平台开发语言,但是在DApp开发、区块链仿真与数据分析、智能合约安全分析等领域,Python依然是不错的选择。本文介绍了10个最流行的Python区块链项并提供了相应的源代码下载地址。 1、web3.py - 以太坊的Python开发接口 web3.py是访问以太坊区块链及相关生态的Python接口,可以视为web3.js的

python区块链开发_10个开源的Python区块链项目-爱代码爱编程

Python不是主流的区块链底层平台开发语言,但是在DApp开发、区块链仿真与数据分析、智能合约安全分析等领域,Python依然是不错的选择。本文介绍了10个最流行的Python区块链项并提供了相应的源代码下载地址。 1、web3.py - 以太坊的Python开发接口 web3.py是访问以太坊区块链及相关生态的Python接口,可以视为web3

python 区块链开发包_python语言-区块链开发-爱代码爱编程

以太坊是区块链开发领域最好的编程平台,而truffle是以太坊(Ethereum)最受欢迎的一个开发框架,这是我们第一篇区块链技术文章介绍truffle的原因,实战是最重要的事情,这篇文章不讲原理,只搭建环境,运行第一个区块链程序(Dapp)。 安装truffle $ npm install -g truffle 依赖环境 NodeJS 访问ht

python适合开发区块链吗_python语言-区块链开发-爱代码爱编程

以太坊是区块链开发领域最好的编程平台,而truffle是以太坊(Ethereum)最受欢迎的一个开发框架,这是我们第一篇区块链技术文章介绍truffle的原因,实战是最重要的事情,这篇文章不讲原理,只搭建环境,运行第一个区块链程序(Dapp)。 安装truffle $ npm install -g truffle 依赖环境 NodeJS 访问ht

python适合开发区块链吗_区块链入门开发语言选择 python适合开发区块链吗-爱代码爱编程

区块链用什么需要开发?在哪可以了解? 从现在各个公有链的使用情况来看,来一代的都是参考Bitcoin,使用C 开发,而新一代的区块链技术使用的语言则是Go,Python,C#和JavaScript。以太坊自己使用的是Solidity,语法接近于JavaScript,但是有所不同。 这些公有链项目,自身就是开发平台,如果要选择的话,现在以太坊是接

从0编写区块链:用python解释区块链最基本原理-爱代码爱编程

人工智能和区块链诞生至今已经有了十几年,当这些技术出现时,人们都说他们会改变世界,但至今为止,这两项技术对现实的影响依然有限。从技术上看人工智能的原理其实是从大量数据中寻找规律或模式,但区块链的技术原理是什么呢?在我看来区块链的原理一直处于云里雾里,有很多近乎玄学的解释将其笼罩,有人从经济学解释,有人从社会学解释,从”人文“角度解释的区块链总是过于夸大其词

大势所趋——区块链(Python代码实现)-爱代码爱编程

目录 1 区块链和人工智能 2 区块链的相关概念及流程 2.1 官方定义 2.2 普通区块&创世区块 2.3  区块的工作流程  3 区块链Python代码实现  4 致谢  1 区块链和人工智能 人工智能和区块链诞生至今已经有了十几年,当这些技术出现时,人们都说他们会改变世界,但至今为止,这两项技术对现实的影响依然有限