广告
返回顶部
首页 > 资讯 > 后端开发 > Python >【Python】实现一个简单的区块链系统
  • 452
分享到

【Python】实现一个简单的区块链系统

区块链python共识算法 2023-09-22 12:09:14 452人浏览 八月长安

Python 官方文档:入门教程 => 点击学习

摘要

本文章利用 Python 实现一个简单的功能较为完善的区块链系统(包括区块链结构、账户、钱包、转账),采用的共识机制是 POW。 一、区块与区块链结构 Block.py import hashlibfrom datetime import

本文章利用 Python 实现一个简单的功能较为完善的区块链系统(包括区块链结构、账户、钱包、转账),采用的共识机制是 POW。

一、区块与区块链结构

Block.py

import hashlibfrom datetime import datetimeclass Block:    """        区块链结构:            prev_hash:      父区块哈希值            data:           区块内容            timestamp:      区块创建时间            hash:           区块哈希值    """    def __init__(self, data, prev_hash):        # 将传入的父区块哈希值和数据保存到变量中        self.prev_hash = prev_hash        self.data = data        # 获得当前的时间        self.timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S")        # 计算区块哈希值        # 获取哈希对象        message = hashlib.sha256()        # 先将数据内容转为字符串并进行编码,再将它们哈希        # 注意:update() 方法现在只接受 bytes 类型的数据,不接收 str 类型        message.update(str(self.prev_hash).encode('utf-8'))        message.update(str(self.prev_hash).encode('utf-8'))        message.update(str(self.prev_hash).encode('utf-8'))        # update() 更新 hash 对象,连续的调用该方法相当于连续的追加更新        # 返回字符串类型的消息摘要        self.hash = message.hexdigest()

 BlockChain.py

from Block import Blockclass BlockChain:    """        区块链结构体            blocks:         包含区块的列表    """    def __init__(self):        self.blocks = []    def add_block(self, block):        """        添加区块        :param block:        :return:        """        self.blocks.append(block)# 新建区块genesis_block = Block(data="创世区块", prev_hash="")new_block1 = Block(data="张三转给李四一个比特币", prev_hash=genesis_block.hash)new_block2 = Block(data="张三转给王五三个比特币", prev_hash=genesis_block.hash)# 新建一个区块链对象blockChain = BlockChain()# 将刚才新建的区块加入区块链blockChain.add_block(genesis_block)blockChain.add_block(new_block1)blockChain.add_block(new_block2)# 打印区块链信息print("区块链包含区块个数为:%d\n" % len(blockChain.blocks))blockHeight = 0for block in blockChain.blocks:    print(f"本区块高度为:{blockHeight}")    print(f"父区块哈希:{block.prev_hash}")    print(f"区块内容:{block.data}")    print(f"区块哈希:{block.hash}")    print()    blockHeight += 1

 测试结果 

二、加入工作量证明(POW)

将工作量证明加入到 Block.py 中

import hashlibfrom datetime import datetimefrom time import timeclass Block:    """        区块链结构:            prev_hash:      父区块哈希值            data:           区块内容            timestamp:      区块创建时间            hash:           区块哈希值            nonce:          随机数    """    def __init__(self, data, prev_hash):        # 将传入的父区块哈希值和数据保存到变量中        self.prev_hash = prev_hash        self.data = data        # 获得当前的时间        self.timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S")        # 设置随机数、哈希初始值为 None        self.nonce = None        self.hash = None    # 类的 __repr__() 方法定义了实例化对象的输出信息    def __repr__(self):        return f"区块内容:{self.data}\n区块哈希值:{self.hash}"class ProofOfWork:    """        工作量证明:            block:          区块            difficulty:     难度值    """    def __init__(self, block, difficult=5):        self.block = block        # 定义出块难度,默认为 5,表示有效哈希值以 5 个零开头        self.difficulty = difficult    def mine(self):        """        挖矿函数        :return:        """        i = 0        prefix = '0' * self.difficulty        while True:            message = hashlib.sha256()            message.update(str(self.block.prev_hash).encode('utf-8'))            message.update(str(self.block.data).encode('utf-8'))            message.update(str(self.block.timestamp).encode('utf-8'))            message.update(str(i).encode('utf-8'))            # digest() 返回摘要,作为二进制数据字符串值            # hexdigest() 返回摘要,作为十六进制数据字符串值            digest = message.hexdigest()            # str.startswith(prefix) 检测字符串是否是以 prefix(字符串)开头,返回布尔值            if digest.startswith(prefix):                # 幸运数字                self.block.nonce = i                # 区块哈希值为十六进制数据字符串摘要                self.block.hash = digest                return self.block            i += 1    def validate(self):        """        验证有效性        :return:        """        message = hashlib.sha256()        message.update(str(self.block.prev_hash).encode('utf-8'))        message.update(str(self.block.data).encode('utf-8'))        message.update(str(self.block.timestamp).encode('utf-8'))        message.update(str(self.block.nonce).encode('utf-8'))        digest = message.hexdigest()        prefix = '0' * self.difficulty        return digest.startswith(prefix)# ++++++++测试++++++++# 定义一个区块b = Block(data="测试", prev_hash="")# 定义一个工作量证明w = ProofOfWork(b)# 开始时间start_time = time()# 挖矿,并统计函数执行时间print("+++开始挖矿+++")valid_block = w.mine()# 结束时间end_time = time()print(f"挖矿花费时间:{end_time - start_time}秒")# 验证区块print(f"区块哈希值是否符合规则:{w.validate()}")print(f"区块哈希值为:{b.hash}")

测试结果

更新 BlockChain.py

from Block import Block, ProofOfWorkclass BlockChain:    """        区块链结构体            blocks:         包含区块的列表    """    def __init__(self):        self.blocks = []    def add_block(self, block):        """        添加区块        :param block:        :return:        """        self.blocks.append(block)# 新建一个区块链对象blockChain = BlockChain()# 新建区块block1 = Block(data="创世区块", prev_hash="")w1 = ProofOfWork(block1)genesis_block = w1.mine()blockChain.add_block(genesis_block)block2 = Block(data="张三转给李四一个比特币", prev_hash=genesis_block.hash)w2 = ProofOfWork(block2)block = w2.mine()blockChain.add_block(block)block3 = Block(data="张三转给王五三个比特币", prev_hash=block.hash)w3 = ProofOfWork(block3)block = w3.mine()blockChain.add_block(block)# 打印区块链信息print("区块链包含区块个数为:%d\n" % len(blockChain.blocks))blockHeight = 0for block in blockChain.blocks:    print(f"本区块高度为:{blockHeight}")    print(f"父区块哈希:{block.prev_hash}")    print(f"区块内容:{block.data}")    print(f"区块哈希:{block.hash}")    print()    blockHeight += 1    

 测试结果

三、实现钱包、账户、交易功能

 实现钱包、账户、交易功能要先安装非对称加密算法库 ecdsa。如果网速慢,引用下面这个网站

-i https://pypi.tuna.tsinghua.edu.cn/simple

添加钱包、账户功能 Wallet.py

import base64import binasciifrom hashlib import sha256# 导入椭圆曲线算法from ecdsa import SigningKey, SECP256k1, VerifyingKeyclass Wallet:    """        钱包    """    def __init__(self):        """            钱包初始化时基于椭圆曲线生成一个唯一的秘钥对,代表区块链上一个唯一的账户        """        # 生成私钥        self._private_key = SigningKey.generate(curve=SECP256k1)        # 基于私钥生成公钥        self._public_key = self._private_key.get_verifying_key()    @property    def address(self):        """            这里通过公钥生成地址        """        h = sha256(self._public_key.to_pem())        # 地址先由公钥进行哈希算法,再进行 Base64 计算而成        return base64.b64encode(h.digest())    @property    def pubkey(self):        """            返回公钥字符串        """        return self._public_key.to_pem()    def sign(self, message):        """            生成数字签名        """        h = sha256(message.encode('utf8'))        # 利用私钥生成签名        # 签名生成的是一串二进制字符串,为了便于查看,这里转换为 ASCII 字符串进行输出        return binascii.hexlify(self._private_key.sign(h.digest()))def verify_sign(pubkey, message, signature):    """        验证签名    """    verifier = VerifyingKey.from_pem(pubkey)    h = sha256(message.encode('utf8'))    return verifier.verify(binascii.unhexlify(signature), h.digest())

实现转账功能 Transaction.py

import JSONclass Transaction:    """        交易的结构    """    def __init__(self, sender, recipient, amount):        """            初始化交易,设置交易的发送方、接收方和交易数量        """        # 交易发送者的公钥        self.pubkey = None        # 交易的数字签名        self.signature = None        if isinstance(sender, bytes):            sender = sender.decode('utf-8')        self.sender = sender        # 发送方        if isinstance(recipient, bytes):            recipient = recipient.decode('utf-8')        self.recipient = recipient  # 接收方        self.amount = amount        # 交易数量    def set_sign(self, signature, pubkey):        """            为了便于验证这个交易的可靠性,需要发送方输入他的公钥和签名        """        self.signature = signature  # 签名        self.pubkey = pubkey  # 发送方公钥    def __repr__(self):        """            交易大致可分为两种,一是挖矿所得,而是转账交易            挖矿所得无发送方,以此进行区分显示不同内容        """        if self.sender:            s = f"从{self.sender}转自{self.recipient}{self.amount}个加密货币"        elif self.recipient:            s = f"{self.recipient}挖矿所得{self.amount}个加密货币"        else:            s = "error"        return sclass TransactionEncoder(json.JSONEncoder):    """        定义Json的编码类,用来序列化Transaction    """    def default(self, obj):        if isinstance(obj, Transaction):            return obj.__dict__        else:            return json.JSONEncoder.default(self, obj)            # return super(TransactionEncoder, self).default(obj)

更新 Block.py

import hashlibimport jsonfrom datetime import datetimefrom Transaction import Transaction, TransactionEncoderclass Block:    """        区块结构            prev_hash:      父区块哈希值            transactions:   交易对            timestamp:      区块创建时间            hash:           区块哈希值            Nonce:          随机数    """    def __init__(self, transactions, prev_hash):        # 将传入的父哈希值和数据保存到类变量中        self.prev_hash = prev_hash        # 交易列表        self.transactions = transactions        # 获取当前时间        self.timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S")        # 设置Nonce和哈希的初始值为None        self.nonce = None        self.hash = None    # 类的 __repr__() 方法定义了实例化对象的输出信息    def __repr__(self):        return f"区块内容:{self.transactions}\n区块哈希值:{self.hash}"class ProofOfWork:    """        工作量证明            block:          区块            difficulty:     难度值    """    def __init__(self, block, miner, difficult=5):        self.block = block        self.miner = miner        # 定义工作量难度,默认为5,表示有效的哈希值以5个“0”开头        self.difficulty = difficult        # 添加挖矿奖励        self.reward_amount = 1    def mine(self):        """            挖矿函数        """        i = 0        prefix = '0' * self.difficulty        # 设置挖矿自动生成交易信息,添加挖矿奖励        t = Transaction(            sender="",            recipient=self.miner.address,            amount=self.reward_amount,        )        sig = self.miner.sign(json.dumps(t, cls=TransactionEncoder))        t.set_sign(sig, self.miner.pubkey)        self.block.transactions.append(t)        while True:            message = hashlib.sha256()            message.update(str(self.block.prev_hash).encode('utf-8'))            # 更新区块中的交易数据            # message.update(str(self.block.data).encode('utf-8'))            message.update(str(self.block.transactions).encode('utf-8'))            message.update(str(self.block.timestamp).encode('utf-8'))            message.update(str(i).encode("utf-8"))            digest = message.hexdigest()            if digest.startswith(prefix):                self.block.nonce = i                self.block.hash = digest                return self.block            i += 1    def validate(self):        """            验证有效性        """        message = hashlib.sha256()        message.update(str(self.block.prev_hash).encode('utf-8'))        # 更新区块中的交易数据        # message.update(str(self.block.data).encode('utf-8'))        message.update(json.dumps(self.block.transactions).encode('utf-8'))        message.update(str(self.block.timestamp).encode('utf-8'))        message.update(str(self.block.nonce).encode('utf-8'))        digest = message.hexdigest()        prefix = '0' * self.difficulty        return digest.startswith(prefix)

更新 BlockChain.py

from Block import Block, ProofOfWorkfrom Transaction import Transactionfrom Wallet import Wallet, verify_signclass BlockChain:    """        区块链结构体            blocks:        包含的区块列表    """    def __init__(self):        self.blocks = []    def add_block(self, block):        """            添加区块        """        self.blocks.append(block)    def print_list(self):        print(f"区块链包含个数为:{len(self.blocks)}")        for block in self.blocks:            height = 0            print(f"区块链高度为:{height}")            print(f"父区块为:{block.prev_hash}")            print(f"区块内容为:{block.transactions}")            print(f"区块哈希值为:{block.hash}")            height += 1            print()

为了方便我们对区块链进行操作,我们可以在 BlockChain.py 中补充一些方法

# 传入用户和区块链,返回用户的“余额”def get_balance(user, blockchain):    balance = 0    for block in blockchain.blocks:        for t in block.transactions:            if t.sender == user.address.decode():                balance -= t.amount            elif t.recipient == user.address.decode():                balance += t.amount    return balance# user生成创世区块(新建区块链),并添加到区块链中def generate_genesis_block(user):    blockchain = BlockChain()    new_block = Block(transactions=[], prev_hash="")    w = ProofOfWork(new_block, user)    genesis_block = w.mine()    blockchain.add_block(genesis_block)    # 返回创世区块    return blockchain# 用户之间进行交易并记入交易列表def add_transaction(sender, recipient, amount):    # 新建交易    new_transaction = Transaction(        sender=sender.address,        recipient=recipient.address,        amount=amount    )    # 生成数字签名    sig = sender.sign(str(new_transaction))    # 传入付款方的公钥和签名    new_transaction.set_sign(sig, sender.pubkey)    return new_transaction# 验证交易,若验证成功则加入交易列表def verify_new_transaction(new_transaction, transactions):    if verify_sign(new_transaction.pubkey,                   str(new_transaction),                   new_transaction.signature                   ):        # 验证交易签名没问题,加入交易列表        print("交易验证成功")        transactions.append(new_transaction)    else:        print("交易验证失败")# 矿工将全部验证成功的交易列表打包出块def generate_block(miner, transactions, blockchain):    new_block = Block(transactions=transactions,                      prev_hash=blockchain.blocks[len(blockchain.blocks) - 1].hash)    print("生成新的区块...")    # 挖矿    w = ProofOfWork(new_block, miner)    block = w.mine()    print("将新区块添加到区块链中")    blockchain.add_block(block)

进行测试

# 新建交易列表transactions = []# 创建 3 个用户alice = Wallet()tom = Wallet()bob = Wallet()print("alice创建创世区块...")blockchain = generate_genesis_block(alice)print()print(f"alice 的余额为{get_balance(alice, blockchain)}个比特币")print(f"tom 的余额为{get_balance(tom, blockchain)}个比特币")print(f"bob 的余额为{get_balance(bob, blockchain)}个比特币")print()# 打印区块链信息blockchain.print_list()print("新增交易:alice 转账 0.5 比特币给 tom")nt = add_transaction(alice, tom, 0.5)print()verify_new_transaction(nt, transactions)print(f"矿工 bob 将全部验证成功的交易列表打包出块...")generate_block(bob, transactions, blockchain)print("添加完成\n")# 打印区块链信息blockchain.print_list()

测试结果

来源地址:https://blog.csdn.net/ottolsq/article/details/130469241

--结束END--

本文标题: 【Python】实现一个简单的区块链系统

本文链接: https://www.lsjlt.com/news/415249.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • 【Python】实现一个简单的区块链系统
    本文章利用 Python 实现一个简单的功能较为完善的区块链系统(包括区块链结构、账户、钱包、转账),采用的共识机制是 POW。 一、区块与区块链结构 Block.py import hashlibfrom datetime import ...
    99+
    2023-09-22
    区块链 python 共识算法
  • 如何实现一个简单的区块链
    这篇文章将为大家详细讲解有关如何实现一个简单的区块链,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。区块链的基础概念很简单:一个分布式数据库,...
    99+
    2022-10-18
  • 如何使用MongoDB开发一个简单的区块链系统
    如何使用MongoDB开发一个简单的区块链系统区块链技术近年来备受关注,因其去中心化、安全性高等特点,被广泛用于加密货币、合约管理等领域。本文将介绍如何使用MongoDB开发一个简单的区块链系统,并提供相应的代码示例。1.安装和配置Mong...
    99+
    2023-10-22
    开发 区块链 MongoDB
  • go语言区块链实战实现简单的区块与区块链
    目录区块链实战Version 1区块相关:区块链相关区块链实战 字节 字段 说...
    99+
    2022-11-12
  • 详解python实现简单区块链结构
    区块链 比特币从诞生到现在已经10年了,最近接触到了区块链相关的技术,为了揭开其背后的神秘面纱,我就从头开始构建一个简单的区块链。 从技术上来看:区块是一种记录交易的数据结构,反映了...
    99+
    2022-11-12
  • 怎么用go语言区块链实战实现简单的区块与区块链
    本篇内容介绍了“怎么用go语言区块链实战实现简单的区块与区块链”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!区块链实战字节字段说明4版本区块...
    99+
    2023-06-25
  • 用Python实现一个简单的用户系统
    目录前言正文总结前言  如标题所说,这是一个非常简单的程序,并不涉及任何高深的学问,更适合一些刚入手Python的新人研究一下基础内容的用法,此案列对于有些编程经验的人来讲...
    99+
    2022-11-13
  • python区块链地址的简版实现
    说明 本文根据https://github.com/liuchengxu/blockchain-tutorial 的内容,用python实现的,但根据个人的理解进行了一些修改,大量引...
    99+
    2022-11-11
  • python区块链实现简版网络
    目录说明引言区块链网络kademlia发现协议简化协议消息TCP服务端TCP客户端P2P服务器连接节点RPC测试区块同步方式问题总结说明 本文根据https://github.com...
    99+
    2022-11-11
  • Java如何实现简单的区块链程序
    本篇内容主要讲解“Java如何实现简单的区块链程序”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Java如何实现简单的区块链程序”吧!什么是区块链?那么,让我们先来了解一下区块链到底是什么…好吧...
    99+
    2023-06-14
  • 使用python怎么实现一个区块链结构
    这期内容当中小编将会给大家带来有关使用python怎么实现一个区块链结构,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。python的数据类型有哪些python的数据类型:1. 数字类型,包括int(整型)...
    99+
    2023-06-14
  • 基于Python实现一个简单的学生管理系统
    目录序言代码实战效果展示序言 小学妹说要毕业了,学了一学期Python等于没学,现在要做毕设做不出来,让我帮帮她,晚上去她家吃夜宵。 当时我心想,这不是分分钟的事情,还要去她家,男孩...
    99+
    2022-12-31
    Python实现学生管理系统 Python学生管理系统 Python管理系统
  • python实现一个简单的dnspod
    实现一个简单的dnspod解析api:dnspod api地址:https://www.dnspod.cn/docs/records.html#record-create #!/usr/bin/env python # -*- coding...
    99+
    2023-01-31
    简单 python dnspod
  • 使用Java实现简单的区块链程序的方法
    在本文中,我们将学习区块链技术的基本概念。我们还将用Java实现一个基本的应用程序,重点介绍这些概念。 此外,我们还将讨论该技术的一些先进概念和实际应用。 什么是区块链? 那么,让我...
    99+
    2022-11-12
  • 用Python实现一个简单的WebSoc
    ubuntu下python2.76 windows python 2.79, chrome37 firefox35通过 代码是在别人(cddn有人提问)基础上改的, 主要改动了parsedata和sendmessage这2个函数. 改代码...
    99+
    2023-01-31
    简单 Python WebSoc
  • 基于C++实现一个简单的音乐系统
    目录一、前言二、实现步骤三、代码实现四、讲解程序一、前言 2022临近尾声,2023即将来临。 过去的一年,我们同努力,我们共欢笑.。 每一次成功都蕴藏着我们辛勤的劳动。 新的一年即...
    99+
    2022-12-29
    C++音乐系统 C++声音系统 C++ Beep
  • python区块链简易版交易实现示例
    目录说明引言比特币交易交易输出发送币余额查看总结说明 本文根据https://github.com/liuchengxu/blockchain-tutorial的内容,用python...
    99+
    2022-11-11
  • python区块链实现简版工作量证明
    目录说明回顾工作量证明哈希计算Hashcash实现说明 本文根据https://github.com/liuchengxu/blockchain-tutorial的内容,用pytho...
    99+
    2022-11-11
  • 实现一个简单得数据响应系统
    目录1、Dep2、了解 obverser3、了解 watch 和 observer4、触发依赖5、总结一下流程1、Dep 其实,这就是一个依赖收集的容器, depend 收集依赖, ...
    99+
    2022-11-12
  • 如何使用MySQL和Python实现一个简单的博客系统
    要使用MySQL和Python实现一个简单的博客系统,可以按照以下步骤进行:1. 安装MySQL数据库和Python的MySQL库:...
    99+
    2023-10-20
    MySQL
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作