简单区块链Python实现

2023-05-16

什么是区块链

区块链是一种数据结构,也是一个分布式数据库。

从技术上来看:区块是一种记录交易的数据结构,反映了一笔交易的资金流向。系统中已经达成的交易的区块连接在一起形成了一条主链,所有参与计算的节点都记录了主链或主链的一部分。
在这里插入图片描述

组成

区块头

区块头主要包含的三组元数据分别是:(1)用于连接前面的区块、索引自父区块哈希值的数据;(2)挖矿难度、时间戳、Nonce(随机数,用于工作量证明算法的计数器,也可理解为记录解密该区块相关数学题的答案的值);(3)能够总结并快速归纳校验区块中所有交易数据的Merkle(默克尔)树根数据。当然区块头不仅仅包含这些元数据,还有其他比如:版本号、难度值等。
从这个结构来看,区块链的大部分功能都由区块头实现。

区块主体

区块主体所记录的交易信息是区块所承载的任务数据,具体包括交易双方的私钥、交易的数量、电子货币的数字签名等。

比特币系统大约每10分钟会创建一个区块,这个区块包含了这段时间里全网范围内发生的所有交易。每一个区块都保存了上一个区块的哈希值,使得每个区块都能找到其前一个区块,这样就将这些区块连接起来,形成了一个链式的结构。
在这里插入图片描述

区块字段

  • Difficulty 此区块的难度级别
  • ExtraData 与此区块相关的附加数据 在区块链早期使用比较多,现在用的很少
  • gasLimit 当前区块允许使用的最大gas, gas表示一种计算量, 使用的算力单位
  • gasUsed 当前区块已经使用的gas
  • Hash 当前区块的哈希值。如果区块没有被确认,这个字段会是null值
  • LogsBloom 由日志信息组成的一个Bloom过滤器 (数据结构),区块没被确认- 是值为null
  • Miner 取得该区块记账权的矿工
  • mixHash 一个Hash值,当与nonce组合时,证明此区块已经执行了足够的计算
  • nonce 一个Hash值,当与mixHash组合时,证明此区块已经执行了足够的计算
  • Number 当前区块的计数(创世纪块的区块序号为0,对于每个后续区块,区块序号都增加1)
  • parentHash 父区块头的Hash值(这也是使得区块变成区块链的原因)
  • receiptsRoot 包含此区块所列的所有交易收据的树的根节点Hash值
  • Sha3Uncles 数据块的哈希值
  • Size 当前区块的字节大小
  • stateRoot 区块状态树的根哈希
  • Timestamp 区块打包时的unix时间戳
  • totalDifficulty 区块链到当前区块的总难度
  • Transactions 交易的对象
  • transactionsRoot 区块的交易树的根哈希
  • Uncles 叔哈希数组 树区块详见 https://blog.csdn.net/weixin_42874184/article/details/81735695

在这里插入图片描述

Python实现

实现了工作量证明,难度计算,哈希部分

import hashlib
import datetime
import random
 
class Block:
    def __init__(self, index, transaction, pre_hash, difficulty, nonce):
        self.index = index
        self._timestamp = datetime.datetime.now()
        self._transaction = transaction
        self._pre_hash = pre_hash
        self._nonce = nonce
        self._difficulty = difficulty
        self.hash = self.gen_hash()
 
    @property
    def get_hash(self):
        return self.hash
 
    @property
    def get_index(self):
        return self.index
 
    @property
    def get_transaction(self):
        return self._transaction
 
    @property
    def get_difficulty(self):
        return self._difficulty
 
    @property
    def get_timestamp(self):
        return self._timestamp
 
    @property
    def get_pre_hash(self):
        return self._pre_hash
 
    @property
    def get_nonce(self):
        return self._nonce
 
    def gen_hash(self):
        sha = hashlib.sha256()
        data = str(self.index) + str(self._timestamp) + str(self._transaction) + str(self._pre_hash) + str(self._nonce) + str(self._difficulty)
        sha.update(data.encode("utf8"))
        return sha.hexdigest()
 
 
class Blockchain:
    def __init__(self, max_blocks):
        self._chain_list = [Block(0, "The First Block", '0', '1', random.randrange(0, 99999))]
        self._previous_block = self._chain_list[0]
        self._current_block = 1
        self.max_blocks = max_blocks
 
    @staticmethod
    def create_next_block(self):
        last_block = self._chain_list[self._current_block - 1]
        last_difficulty = last_block.get_difficulty
        this_index = last_block.index + 1
        this_transaction = "New Block " + str(this_index) + " has been generated successfully."
        nonce = random.randrange(0, 99999)
        this_difficulty = self.proof_of_work(nonce)
        pre_hash = last_block.hash
        self._chain_list.append(Block(this_index, this_transaction, pre_hash, this_difficulty, nonce))
        self._current_block += 1
 
    def last_block(self):
        return self._chain_list[-1]
 
    def proof_of_work(self, nonce):
        proof = 0
        while self.valid_proof(self, proof, nonce) is False:
            proof += 1
        return proof
 
    @staticmethod
    def valid_proof(self, proof, nonce):
        guess = f'{proof}{nonce}'.encode()
        guess_hash = hashlib.sha256(guess).hexdigest()
        pattern = "0000"
        return guess_hash[:len(pattern)] == pattern
 
    def run(self):
        for i in range(self.max_blocks):
            self.create_next_block(self)
 
    def show_block(self, index):
        print("----------------------------------------")
        print("ID: ", self._chain_list[index].get_index)
        print("Time", self._chain_list[index].get_transaction)
        print("Cur Hash", self._chain_list[index].get_hash)
        print("Pre Hash", self._chain_list[index].get_pre_hash)
        print("Difficulty", self._chain_list[index].get_difficulty)
        print("Trans", self._chain_list[index].get_transaction)
        print("Nonce", self._chain_list[index].get_nonce)
        print("----------------------------------------")
 
 
myBlockChain = Blockchain(100)
myBlockChain.run()
for i in range(myBlockChain.max_blocks):
    myBlockChain.show_block(i)

在这里插入图片描述

参考文献

https://segmentfault.com/a/1190000014483104
https://blog.csdn.net/qq874455953/article/details/83718022

更多内容访问 omegaxyz.com
网站所有代码采用Apache 2.0授权
网站文章采用知识共享许可协议BY-NC-SA4.0授权
© 2020 • OmegaXYZ-版权所有 转载请注明出处

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

简单区块链Python实现 的相关文章

  • ubuntu20.04系统安装谷歌浏览器

    1 百度搜索 谷歌浏览器官网 xff0c 然后在搜索界面点击如图所示图标进入谷歌浏览器下载界面 2 在谷歌浏览器下载界面 xff0c 点击 下载Chrome 3 在弹出的下载界面选择Ubuntu适用的64位下载包后点击 接受并安装 4 在下
  • 【Algorithm】单向链表模拟实现vector功能

    span class token function cmake minimum required span span class token punctuation span VERSION span class token number
  • ARCH INSTALL

    Arch Linux Install With UEFI Boot gdisk dev sdxy boot always uses less than 1G uses EF00 EFI System home uses 8302 mnt u
  • SQL Server 表注释&列注释

    添加表注释 表加注释 EXEC sys sp addextendedproperty 64 name 61 N 39 MS Description 39 64 value 61 N 39 注释内容 39 64 level0type 61 N
  • 在ubuntu14.04上安装或升级git

    git version git version 1 9 1 可以使用下面命令升级git xff08 如果不是root用户 xff0c 需在命令前加sudo xff09 xff1a add apt repository ppa git cor
  • C#串口数据处理--环形缓冲区-FIFO

    一 FIFO环形缓冲区初始化 static int MAX BUFFER LEN 61 1024 定义缓冲区大小 FIFO receiveBufferManager 61 new FIFO MAX BUFFER LEN 二 串口接收事件中添
  • IDEA 解决jar冲突问题

    在实际的 Maven 项目开发中 xff0c 由于项目引入的依赖过多 xff0c 遇到 jar 冲突算是一个很常见的问题了 如何使用 IntelliJ IDEA 解决 jar 包冲突的问题 xff01 简单粗暴 xff0c 直接上示例 xf
  • Ubuntu 18.04下安装Google Chrome

    Ubuntu 18 04下安装Google Chrome 进入Chrome官网下载地址 xff1a https www google cn intl zh CN chrome 点击 下载Chrome xff0c 进入下载页面 xff1a 如
  • css获取网页内所有标签的内容

    选择所有标签内的内容 包括script和style xff1a span class token punctuation span span class token punctuation span text 选择除script和style
  • Ubuntu 22.04 dektop 开启root并自动登录桌面

    1 设置root密码 span class token function sudo span span class token function passwd span root 2 解锁root span class token func
  • linux服务器之间的数据拷贝

    方法一 xff1a scp xff08 secure copy xff09 安全拷贝 xff08 1 xff09 scp定义 xff1a scp可以实现服务器与服务器之间的数据拷贝 xff08 from server1 to server2
  • Ubuntu桌面美化方法记录

    Ubuntu 20 04 1 LTS 桌面系统主题 xff0c 图标美化记录 Ubuntu使用的是Gnome Desktop xff0c 可以在 Gnome Look 寻找需要的主题 xff0c 图标 xff0c 插件等来丰富桌面系统 本文
  • spring mvc配置类简介及放静态资源释放

    配置文件ApplicationContext xml 基于spring的项目资源都是通过DispatcherServlet作为拦截器 xff0c DispatcherServlet是前置控制器 xff0c 配置在web xml文件中的 拦截
  • 【PVI-DSO】Leveraging Planar Regularities for Direct Sparse Visual-Inertial Odometry

    PVI DSO xff1a PVI DSO Leveraging Planar Regularities for Direct Sparse Visual Inertial Odometry 翻译 利用平面正则性进行直接稀疏视觉惯性里程计
  • SpringMvc源码分析--配置文件解析

    我们简单分析一下springmvc配置解析过程 xff0c 我个人认为理解这个过程对于后续学习是有帮助的 xff0c 毕竟配置文件是入口 一 认识springmvc xml配置文件 下面这个是springmvc中的配置 xff0c 与spr
  • SystemUI锁屏界面

    SystemUI 启动的时候启动各个SERVICE 这些Service不是四大组件的service 这个SERVICE继承SystemUI 实现了start 和onBootComplete方法 其中StatusBar加载了SystemUI几
  • Fastboot刷机

    Fastboot xff0c BootLoader xff0c Recovery详解 首先 xff0c 智能手机就是一台小电脑 xff0c 如果你恰好用的是linux系统 xff0c 那可以说两者在系统层面没有区别 因为android就是l
  • build 打包报错:Execution failed for task ‘,Run with --stacktrace option to get the stack trace.

    背景 xff1a 隔了很久的项目 xff0c 再次打开打包时报错 xff1a FAILURE Build completed with 2 failures 1 Task failed with an exception What went
  • oe_runmake failed

    记录在使用Petalinux编译uboot和linux内核的时候遇到的一个问题 xff0c 自己找了很久才找到解法 xff0c 贴出来给后来的兄弟们排排坑 问题 xff1a ERROR span class token operator s
  • python-图论最短路径算法

    python 图论最短路径算法 一 深度优先算法 广度优先算法区别 39 39 39 查找最短路径 定义 xff1a v 61 顶点 t 61 目标顶点 v1 61 子顶点 广度优先算法 xff1a 优先遍历 v 的所有邻接顶点 xff0c

随机推荐