主页 > imtoken钱包正确的下载地址 > Python 区块链入门,揭秘比特币
Python 区块链入门,揭秘比特币
个人博客:
本文将简单介绍区块链(BlockChain),并用Python做一个简单的实现,从中可以了解比特币的原理。
什么是区块链
简单来说,区块链是通过加密数据(区块)按时间顺序(链)叠加生成的永久不可逆的记录。 具体来说,其区块链由一系列使用密码学生成的数据块组成。 每个区块都包含前一个区块的哈希值(hash),从创世区块(genesis block)开始连接到当前区块,形成区块链。 每个区块保证按时间顺序在前一个区块之后生成,否则前一个区块的哈希值未知。 这是比特币的一个重要概念。
特征
区块链具有以下特点:
去中心化:区块链不依赖于一个中心节点,而是依赖于分布式节点。
无需信任系统:区块链基于密码算法,数据需要经过网络中其他用户的认可,因此不需要第三方中介结构或信任机构背书。
不可篡改和加密安全:区块链采用单向哈希算法,每个新产生的区块严格按时间线性顺序推进。 时间的不可逆性导致任何企图侵入和篡改区块链中数据信息的行为。 容易被追踪,导致被其他节点排斥,可以限制相关的不当行为。
以上特点使得区块链在银行、证券市场、金融等诸多领域有着越来越多的应用。
区块链如何运作
区块链是一系列加密的数据块。 这些区块由一个包含元数据的区块头组成,后跟一长串构成区块主体的交易。 比特币中的区块结构如下:
块头
区块头包含与区块链中其他区块的连接信息、时间戳和nonce信息,如下:
块标识符
区块有两个标识,一个是区块头的哈希值,一个是区块高度。 区块头的哈希值是通过SHA256算法对区块头进行二次哈希计算得到的数字。 区块哈希值可以唯一、无歧义地标识一个区块,任何节点都可以通过简单地对区块头进行哈希处理来独立获得区块哈希值。 区块高度是指区块在区块链中的位置。 块高度不是唯一标识符。 虽然单个块将始终具有确定的、固定的块高度,但反之则不然,块高度并不总是标识单个块。 两个或多个区块可能具有相同的区块高度并竞争区块链中的相同位置。
了解了以上基础知识后,我们就开始用Python实现一个简单的区块链吧。
区块链的Python实现
1.定义块结构
import hashlib
import uuid
class Block(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 # 父节点哈希值
def hash(self, nonce=None):
"""
计算区块的哈希值
:param nonce:
:return:
"""
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()
def hash_is_valid(self, the_hash):
"""
校验区块哈希值有否有效
:param the_hash:
:return:
"""
return the_hash.startswith('0000')
def __repr__(self):
return 'Block' .\
format(self.hash(self.nonce), self.nonce)
上面是块结构。 这里实现的是简化版,并不完全对应比特币中的区块。 这里的块包含一个唯一标识符、父节点的哈希值、nonce 值和块的内容字段。 可见,一个区块的哈希值必须满足一定的条件才有效,比如从0000开始。下面初始化区块结构。
首先用内容 hello world 创建一个内容块
block = Block('Hello World')
打印块,结果如下:
堵塞
虽然创建了上述区块,但其哈希值无效且不是以 0000 开头。
block.hash_is_valid(block.hash())
以上结果为假。
您可以更改 nonce 值以获得新的哈希值。 例如:
block.hash(1)
哈希变为:
3873835623b4cfd65938c723360da82360485765f3796bb5fd6f56e127556868
哈希已更新,但还不是有效的哈希。 为了得到一个有效的哈希值,是一个不断更新nonce值的过程,或者说是一个挖矿(mine)的过程。 下面添加一个挖矿函数,得到一个合适的nonce值。
def mine(self):
"""
新增挖矿函数
:return:
"""
# 初始化nonce为0
cur_nonce = self.nonce or 0
# 循环直到生成一个有效的哈希值
while True:
the_hash = self.hash(nonce=cur_nonce)
# 如果生成的哈希值有效
if self.hash_is_valid(the_hash):
# 保持当前nonce值
self.nonce = cur_nonce
# 并退出
break
else:
# 若当前哈希值无效,更新nonce值,进行加1操作
cur_nonce += 1
所以你可以挖矿:
block = Block('Hello World')
# 挖矿,循环直至找到合适的nonce
block.mine()
>>> block
可以找到满足条件的区块:
堵塞
至此,第一个有效区块生成,下面定义区块链。
2.定义区块链结构
class BlockChain(object):
def __init__(self):
self.head = None # 指向最新的一个区块
self.blocks = {} # 包含所有区块的一个字典
def add_block(self, new_block):
"""
添加区块函数
:param new_block:
:return:
"""
previous_hash = self.head.hash() \
if self.head else None
new_block.previous_hash = previous_hash
self.blocks[new_block.identifier] = {
'block': new_block,
'previous_hash': previous_hash,
'previous': self.head,
}
self.head = new_block
def __repr__(self):
num_existing_blocks = len(self.blocks)
return 'Blockchain<{} Blocks, Head: {}>'.format(
num_existing_blocks,
self.head.identifier if self.head else None
)
定义好区块链结构后,下面开始初始化一个区块链。
# 初始化
chain = BlockChain()
>>> chain
结果是:区块链
我们可以向区块链添加块:
# 添加区块
chain.add_block(block)
>>> chain
结果是:
区块链
也可以添加更多块:
for i in range(6):
new_block = Block(i)
new_block.mine()
chain.add_block(new_block)
>>> chain
结果是:
区块链
以上是一个简单的区块链比特币基础教学,后面会涉及到区块链的有效性。 当区块链中的一个区块发生变化时,该区块的哈希值会发生变化,从而影响该区块之后的区块,使区块链不再有效。 这些将在后续进一步探讨。
看完这篇文章你有什么收获吗?欢迎转发分享给更多的人
关注《Python 那些事儿》比特币基础教学,提升你的 Python 技能