python区块链基本原型简版实现示例

 更新时间:2022年5月24日 21:10  点击:295 作者:晓彬_

说明

本文根据https://github.com/liuchengxu/blockchain-tutorial的内容,用python实现的,但根据个人的理解进行了一些修改,大量引用了原文的内容。文章末尾有"本节完整源码实现地址"。

引言

区块链是 21 世纪最具革命性的技术之一,它仍然处于不断成长的阶段,而且还有很多潜力尚未显现。 本质上,区块链只是一个分布式数据库而已。 不过,使它独一无二的是,区块链是一个公开的数据库,而不是一个私人数据库,也就是说,每个使用它的人都有一个完整或部分的副本。 只有经过其他“数据库管理员”的同意,才能向数据库中添加新的记录。 此外,也正是由于区块链,才使得加密货币和智能合约成为现实。

在本系列文章中,我们将实现一个简化版的区块链,并基于它来构建一个简化版的加密货币。

区块

首先从 “区块” 谈起。在区块链中,真正存储有效信息的是区块(block)。而在比特币中,真正有价值的信息就是交易(transaction)。实际上,交易信息是所有加密货币的价值所在。除此以外,区块还包含了一些技术实现的相关信息,比如版本,当前时间戳和前一个区块的哈希。

不过,我们要实现的是一个简化版的区块链,而不是一个像比特币技术规范所描述那样成熟完备的区块链。所以在我们目前的实现中,区块仅包含了部分关键信息,它的数据结构如下:

class Block(object):
    """A Block
    Attributes:
        _magic_no (int): Magic number
        _block_header (Block): Header of the previous Block.
        _transactions (Transaction): transactions of the current Block.
    """
    MAGIC_NO = 0xBCBCBCBC
    def __init__(self, block_header, transactions):
        self._magic_no = self.MAGIC_NO
        self._block_header = block_header
        self._transactions = transactions

字段解释
_magic_no魔数
_block_header区块头
_transactions交易

这里的_magic_no, _block_header, _transactions, 也是比特币区块的构成部分,这里我们简化了一部分信息。在真正的比特币中,区块 的数据结构如下:

FieldDescriptionSize
Magic novalue always 0xD9B4BEF94 bytes
Blocksizenumber of bytes following up to end of block4 bytes
Blockheaderconsists of 6 items80 bytes
Transaction counterpositive integer VI = VarInt1 - 9 bytes
transactionsthe (non empty) list of transactions-many transactions

区块头

class BlockHeader(object):
    """ A BlockHeader
    Attributes:
        timestamp (str): Creation timestamp of Block
        prev_block_hash (str): Hash of the previous Block.
        hash (str): Hash of the current Block.
        hash_merkle_root(str): Hash of the merkle_root.
        height (int): Height of Block
        nonce (int): A 32 bit arbitrary random number that is typically used once.
    """
    def __init__(self, hash_merkle_root, height, pre_block_hash=''):
        self.timestamp = str(time.time())
        self.prev_block_hash = pre_block_hash
        self.hash = None
        self.hash_merkle_root = hash_merkle_root
        self.height = height
        self.nonce = None

字段解释
timestamp当前时间戳,也就是区块创建的时间
prev_block_hash前一个块的哈希,即父哈希
hash当前块头的哈希
hash_merkle_root区块存储的交易的merkle树的根哈希

我们这里的 timestamp,prev_block_hash, Hash,hash_merkle_root, 在比特币技术规范中属于区块头(block header),区块头是一个单独的数据结构。
完整的 比特币的区块头(block header)结构 如下:

FieldPurposeUpdated when…Size (Bytes)
VersionBlock version numberYou upgrade the software and it specifies a new version4
hashPrevBlock256-bit hash of the previous block headerA new block comes in32
hashMerkleRoot256-bit hash based on all of the transactions in the blockA transaction is accepted32
TimeCurrent timestamp as seconds since 1970-01-01T00:00 UTCEvery few seconds4
BitsCurrent target in compact formatThe difficulty is adjusted4
Nonce32-bit number (starts at 0)A hash is tried (increments)4

我们的简化版的区块头里,hash和hash_merkle_root是需要计算的。hash_merkle_root暂且不管留空,它是由区块中的交易信息生成的merkle树的根哈希。
而hash的计算如下:

    def set_hash(self):
        """
        Set hash of the header
        """
        data_list = [str(self.timestamp),
                     str(self.prev_block_hash),
                     str(self.hash_merkle_root),
                     str(self.height),
                     str(self.nonce)]
        data = ''.join(data_list)
        self.hash = sum256_hex(data)

区块链

有了区块,下面让我们来实现区块链。本质上,区块链就是一个有着特定结构的数据库,是一个有序,每一个块都连接到前一个块的链表。也就是说,区块按照插入的顺序进行存储,每个块都与前一个块相连。这样的结构,能够让我们快速地获取链上的最新块,并且高效地通过哈希来检索一个块。

class BlockChain(object):
    def __init__(self):
        self.blocks = []

这就是我们的第一个区块链!就是一个list。
我们还需要一个添加区块的函数:

    def add_block(self, transactions):
        """
        add a block to block_chain
        """
        last_block = self.blocks[-1]
        prev_hash = last_block.get_header_hash()
        height = len(self.blocks)
        block_header = BlockHeader('', height, prev_hash)
        block = Block(block_header, transactions)
        block.set_header_hash()
        self.blocks.append(block)

为了加入一个新的块,我们必须要有一个已有的块,但是,初始状态下,我们的链是空的,一个块都没有!所以,在任何一个区块链中,都必须至少有一个块。这个块,也就是链中的第一个块,通常叫做创世块(genesis block). 让我们实现一个方法来创建创世块:

    # class BlockChain
    def new_genesis_block(self):
        if not self.blocks:
            genesis_block = Block.new_genesis_block('genesis_block')
            genesis_block.set_header_hash()
            self.blocks.append(genesis_block)
    # class Block
    @classmethod
    def new_genesis_block(cls, coin_base_tx):
        block_header = BlockHeader.new_genesis_block_header()
        return cls(block_header, coin_base_tx)
    # class BlockHeader
    @classmethod
    def new_genesis_block_header(cls):
        """
        NewGenesisBlock creates and returns genesis Block
        """
        return cls('', 0, '')

上面分别对应三个函数分别对应链中创世块生成,创世块生成,和创世块头的生成。

创世块高度为0。这里我们暂时还没有交易类,交易暂时用字符串代替。prev_block_hash和hash_merkle_root都暂时留空。

让BlockChain支持迭代

    # class BlockChain
    def __getitem__(self, index):
        if index < len(self.blocks):
            return self.blocks[index]
        else:
            raise IndexError('Index is out of range')

最后再进行简单的测试:

def main():
    bc = BlockChain()
    bc.new_genesis_block()
    bc.add_block('Send 1 BTC to B')
    bc.add_block('Send 2 BTC to B')
    for block in bc:
        print(block)
if __name__ == "__main__":
    main()

输出:

Block(_block_header=BlockHeader(timestamp='1548150457.22', hash_merkle_root='', prev_block_hash='', hash='f91f638a9a2b4caf241112d3bc92c9168cc9d52207a5580b3a549ed5343e2ed3', nonce=None, height=0))
Block(_block_header=BlockHeader(timestamp='1548150457.22', hash_merkle_root='', prev_block_hash='f91f638a9a2b4caf241112d3bc92c9168cc9d52207a5580b3a549ed5343e2ed3', hash='d21570e36f0c6f75c112d98416ca4ffae14e5cf02492bea5a7f8c398c1d458ca', nonce=None, height=1))
Block(_block_header=BlockHeader(timestamp='1548150457.22', hash_merkle_root='', prev_block_hash='d21570e36f0c6f75c112d98416ca4ffae14e5cf02492bea5a7f8c398c1d458ca', hash='9c78f38ec78a0d492a27e69ab04a3e0ba07d70d31a1ef96d581e8198d9781bc0', nonce=None, height=2))

总结

我们创建了一个非常简单的区块链原型:它仅仅是一个数组构成的一系列区块,每个块都与前一个块相关联。真实的区块链要比这复杂得多。在我们的区块链中,加入新的块非常简单,也很快,但是在真实的区块链中,加入新的块需要很多工作:你必须要经过十分繁重的计算(这个机制叫做工作量证明),来获得添加一个新块的权力。并且,区块链是一个分布式数据库,并且没有单一决策者。因此,要加入一个新块,必须要被网络的其他参与者确认和同意(这个机制叫做共识(consensus))。还有一点,我们的区块链还没有任何的交易!

参考:
[1] basic-prototype

[2] 完整实现源码

以上就是python区块链基本原型简版实现示例的详细内容,更多关于python区块链基本原型的资料请关注猪先飞其它相关文章!

原文出处:https://blog.csdn.net/xiaobing1994/article/details/87967291

[!--infotagslink--]

相关文章

  • python opencv 画外接矩形框的完整代码

    这篇文章主要介绍了python-opencv-画外接矩形框的实例代码,代码简单易懂,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下...2021-09-04
  • Python astype(np.float)函数使用方法解析

    这篇文章主要介绍了Python astype(np.float)函数使用方法解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下...2020-06-08
  • 最炫Python烟花代码全解析

    2022虎年新年即将来临,小编为大家带来了一个利用Python编写的虎年烟花特效,堪称全网最绚烂,文中的示例代码简洁易懂,感兴趣的同学可以动手试一试...2022-02-14
  • python中numpy.empty()函数实例讲解

    在本篇文章里小编给大家分享的是一篇关于python中numpy.empty()函数实例讲解内容,对此有兴趣的朋友们可以学习下。...2021-02-06
  • python-for x in range的用法(注意要点、细节)

    这篇文章主要介绍了python-for x in range的用法,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2021-05-10
  • Python 图片转数组,二进制互转操作

    这篇文章主要介绍了Python 图片转数组,二进制互转操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2021-03-09
  • Python中的imread()函数用法说明

    这篇文章主要介绍了Python中的imread()函数用法说明,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2021-03-16
  • python实现b站直播自动发送弹幕功能

    这篇文章主要介绍了python如何实现b站直播自动发送弹幕,帮助大家更好的理解和学习使用python,感兴趣的朋友可以了解下...2021-02-20
  • python Matplotlib基础--如何添加文本和标注

    这篇文章主要介绍了python Matplotlib基础--如何添加文本和标注,帮助大家更好的利用Matplotlib绘制图表,感兴趣的朋友可以了解下...2021-01-26
  • 解决python 使用openpyxl读写大文件的坑

    这篇文章主要介绍了解决python 使用openpyxl读写大文件的坑,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2021-03-13
  • python 计算方位角实例(根据两点的坐标计算)

    今天小编就为大家分享一篇python 计算方位角实例(根据两点的坐标计算),具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2020-04-27
  • python实现双色球随机选号

    这篇文章主要为大家详细介绍了python实现双色球随机选号,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2020-05-02
  • python中使用np.delete()的实例方法

    在本篇文章里小编给大家整理的是一篇关于python中使用np.delete()的实例方法,对此有兴趣的朋友们可以学习参考下。...2021-02-01
  • 使用Python的pencolor函数实现渐变色功能

    这篇文章主要介绍了使用Python的pencolor函数实现渐变色功能,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下...2021-03-09
  • Python getsizeof()和getsize()区分详解

    这篇文章主要介绍了Python getsizeof()和getsize()区分详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2020-11-20
  • python自动化办公操作PPT的实现

    这篇文章主要介绍了python自动化办公操作PPT的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2021-02-05
  • 解决python 两个时间戳相减出现结果错误的问题

    这篇文章主要介绍了解决python 两个时间戳相减出现结果错误的问题,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2021-03-12
  • python实现学生通讯录管理系统

    这篇文章主要为大家详细介绍了python实现学生通讯录管理系统,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2021-02-25
  • PyTorch一小时掌握之迁移学习篇

    这篇文章主要介绍了PyTorch一小时掌握之迁移学习篇,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下...2021-09-08
  • Python绘制的爱心树与表白代码(完整代码)

    这篇文章主要介绍了Python绘制的爱心树与表白代码,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下...2021-04-06