感谢关注天善智能,走好数据之路↑↑↑
欢迎关注天善智能,我们是专注于商业智能BI,大数据,数据分析领域的垂直社区,学习,问答、求职一站式搞定!
本文将简单介绍区块链(BlockChain)并用Python做一简单实现。
什么是区块链
简单来说,区块链就是把加密数据(区块)按照时间顺序进行叠加(链)生成的永久、不可逆向修改的记录。具体来说,它区块链是由一串使用密码学方法产生的数据块组成的,每一个区块都包含了上一个区块的哈希值(hash),从创始区块(genesis block)开始连接到当前区块,形成块链。每一个区块都确保按照时间顺序在上一个区块之后产生,否则前一个区块的哈希值是未知的。它是比特币的一个重要概念。
特点
区块链有如下特点:
去中心化:区块链不依赖于某个中心节点,而是依赖于分布式的各个节点。
无须信任系统:区块链中基于密码学算法,数据需要网络内其他用户的批准,所以不需要一套第三方中介结构或信任机构背书。
不可篡改和加密安全性:区块链采取单向哈希算法,同时每个新产生的区块严格按照时间线形顺序推进,时间的不可逆性导致任何试图入侵篡改区块链内数据 信息的行为都很容易被追溯,导致被其他节点的排斥,从而可以限制相关不法行为。
以上特点使得区块链在银行、证券市场和金融等诸多领域有着越来越多的应用。
区块链工作原理
区块链式一系列加密的数据块。这些区块由一个包含元数据的区块头和紧跟其后的构成区块主体的一长串交易组成。比特币中的区块结构如下:
请点击此处输入图片描述
区块头
区块头中包含了与区块链中其它区块中的连接信息、时间戳和nonce等信息,具体如下:
请点击此处输入图片描述
区块标识符
区块有两个标示符,一是区块头的哈希值,二是区块高度。区块头的哈希值是通过SHA256算法对区块头进行二次哈希计算而得到的数字。区块哈希值可以唯一、明确地标识一个区块,并且任何节点通过简单地对区块头进行哈希计算都可以独立地获取该区块哈希值。区块高度是指该区块在区块链中的位置。区块高度并不是唯一的标识符。虽然一个单一的区块总是会有一个明确的、固定的区块高度,但反过来却并不成立,一个区块高度并不总是识别一个单一的区块。两个或两个以上的区块可能有相同的区块高度,在区块链里争夺同一位置。
了解了以上基础后下面开始用Python实现一个简单的区块链。
区块链的Python实现
一、定义区块结构
In [16]:
# block.pyimport hashlibimport uuidclassBlock(object):def__init__(self,data=None,previous_hash=None):self.identifier = uuid.uuid4().hex # 产生唯一标示self.nonce = None # nonce值self.data = data # 区块内容self.previous_hash = previous_hash # 父节点哈希值defhash(self,nonce=None):'''计算区块的哈希值'''message = hashlib.sha256()message.update(self.identifier.encode('utf-8'))message.update(str(nonce).encode('utf-8'))message.update(str(self.data).encode('utf-8'))message.update(str(self.previous_hash).encode('utf-8'))return message.hexdigest()defhash_is_valid(self,the_hash):'''校验区块哈希值有否有效'''return the_hash.startswith('0000')def__repr__(self):return 'Block'.format(self.hash(), self.nonce)
以上就是一个区块结构,这里实现的是一个简化版,没有完全对应比特币中的区块。这里的区块包含一个唯一标识符、父节点的哈希值、nonce值和该区块的内容字段。可以看到一个区块的哈希值必须满足一定的条件才是有效的,比如以0000开始。下面对这个区块结构进行初始化。
In [37]:
# 创建一个内容为hello world的内容块block = Block('Hello World')block
Out[37]:
Block
以上一个区块虽然创建完成,但其哈希值不是有效的。
In [38]:
block.hash_is_valid(block.hash())
Out[38]:
False
改变nonce的值就可以得到一个新的哈希值。
In [39]:
block.hash(1)
Out[39]:
'a6431938ba10270dfcfdf7a2371312446914fedadf79632c2c0adb3b463f4838'
哈希值更新了,但还不是有效的哈希值。为了得到有效哈希值,是一个不断更新nonce值的过程,或者说一个挖矿(mine)过程。下面添加一个mine函数用来得到一个合适的nonce值。
In [78]:
# block.pyimport hashlibimport uuidclassBlock(object):def__init__(self,data=None,previous_hash=None):self.identifier = uuid.uuid4().hex # 产生唯一标示self.nonce = None # nonce值self.data = data # 区块内容self.previous_hash = previous_hash # 父节点哈希值defhash(self,nonce=None):'''计算区块的哈希值'''message = hashlib.sha256()message.update(self.identifier.encode('utf-8'))message.update(str(nonce).encode('utf-8'))message.update(str(self.data).encode('utf-8'))message.update(str(self.previous_hash).encode('utf-8'))return message.hexdigest()defhash_is_valid(self,the_hash):'''校验区块哈希值有否有效'''return the_hash.startswith('0000')def__repr__(self):return 'Block'.format(self.hash(self.nonce), self.nonce)'''新增挖矿函数'''defmine(self):# 初始化nonce为0cur_nonce = self.nonce or 0# 循环直到生成一个有效的哈希值while True:the_hash = self.hash(nonce=cur_nonce)if self.hash_is_valid(the_hash): # 如果生成的哈希值有效self.nonce = cur_nonce # 保持当前nonce值break # 并退出else:cur_nonce += 1 # 若当前哈希值无效,更新nonce值,进行加1操作
In [75]:
block = Block('Hello World')# 挖矿,循环直至找到合适的nonceblock.mine()# 打印block
Out[75]:
Block
至此,第一个有效的区块生成完成,下面开始定义区块链。
二、定义区块链结构
In [81]:
classBlockChain(object):def__init__(self):self.head = None # 指向最新的一个区块self.blocks = {} # 包含所有区块的一个字典'''添加区块函数'''defadd_block(self,new_block):previous_hash = self.head.hash() if self.head else Nonenew_block.previous_hash = previous_hashself.blocks[new_block.identifier] = {'block': new_block,'previous_hash': previous_hash,'previous': self.head,}self.head = new_blockdef__repr__(self):num_existing_blocks = len(self.blocks)return 'Blockchain<{} Blocks, Head: {}>'.format(num_existing_blocks,self.head.identifier if self.head else None)
定义好区块链结构后,下面就开始初始化一条区块链。
In [82]:
# 初始化chain = BlockChain()# 打印chain
Out[82]:
Blockchain<0 Blocks, Head: None>
In [83]:
# 添加区块chain.add_block(block)# 打印chain
Out[83]:
Blockchain<1 Blocks, Head: 364c0cf963384ca28a2763499a140405>
In [84]:
# 添加更多的区块foriinrange(6):new_block= Block(i)new_block.mine()chain.add_block(new_block)# 打印chain
Out[84]:
Blockchain<7 Blocks, Head: e7cb24ec7acd42a4aaebe7faee9e0713>
以上就是一个简单区块链,后面还会涉及到区块链的有效性。当区块链中一个区块被改变后,这个区块的哈希就会改变,从而影响到这块区块之后的区块,致使这个区块链不再有效。这些将在后续继续深入。
本文作者:天善智能社区 101python
原文链接:https://ask.hellobi.com/blog/101python/8978
天善学院svip正火爆报名中!包含Excel BI、Python3爬虫案例、Python机器学习、Python数据科学家、大数据体系、数据分析报告、数据分析师体系、深度学习、R语言案例共10套课程,其他课程只需五折即可,欢迎大家关注报名!详情可见:https://www.hellobi.com/svip