Python实现简易区块链:从原理到代码详解
本文详细介绍区块链的基本概念、核心特点及工作原理,并基于Python语言逐步实现一个简化版区块链。内容涵盖区块定义、哈希计算、Nonce值寻找(挖矿)以及区块链链式结构的构建,帮助开发者理解区块链底层逻辑。
前言
本文旨在简要介绍区块链(BlockChain)的基础知识,并通过Python代码进行简单实现。以下是详细的内容解析。
什么是区块链
简而言之,区块链是将加密数据(即区块)按时间顺序叠加(形成链)所生成的永久且不可逆向修改的记录。具体而言,区块链由一系列通过密码学方法生成的数据块组成,每个区块都包含前一个区块的哈希值(hash),从创始区块(genesis block)开始,一直链接到当前区块,形成一条链。每个区块必须按照时间顺序在前一个区块之后生成,否则前一个区块的哈希值将未知。区块链是比特币的核心概念之一。
特点
区块链具备以下主要特征:
- 去中心化:区块链不依赖单一的中心节点,而是依赖于分布式的各个节点共同维护。
- 无须信任系统:基于密码学算法,数据需要网络内其他用户的验证和批准,因此无需第三方中介结构或信任机构背书。
- 不可篡改与加密安全性:区块链采用单向哈希算法,且每个新产生的区块严格按照时间顺序推进。时间的不可逆性使得任何试图入侵或篡改区块链内数据的行为都容易被追溯,并导致该行为被其他节点排斥,从而限制不法行为。
上述特点使得区块链在银行、证券市场及金融等多个领域拥有越来越多的应用场景。
区块链工作原理
区块链是一系列加密数据块的集合。这些区块由包含元数据的区块头(block header)和紧随其后的构成区块主体的一长串交易组成。比特币中的区块结构如下:

区块头
区块头包含了与其他区块的连接信息、时间戳以及nonce值等,具体细节如下:

区块标识符
区块有两个标识符:一是区块头的哈希值,二是区块高度。区块头的哈希值是通过SHA256算法对区块头进行二次哈希计算得到的数字。区块哈希值可以唯一且明确地标识一个区块,任何节点只需对区块头进行哈希计算即可独立获取该哈希值。区块高度是指该区块在区块链中的位置。区块高度并非唯一标识符。虽然单一区块总是有明确且固定的区块高度,但反之不成立,即一个区块高度并不总是识别单一区块。在区块链中,两个或更多区块可能拥有相同的区块高度,从而争夺同一位置。
了解上述基础后,下面开始使用Python实现一个简单的区块链。
区块链的Python实现
一、定义区块结构
In [16]:
# block.py
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):
'''
计算区块的哈希值
'''
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):
'''
校验区块哈希值有否有效
'''
return the_hash.startswith('0000')
def __repr__(self):
return 'Block<Hash: {}, Nonce: {}>'.format(self.hash(), self.nonce)
以上展示了一个区块结构,这里实现的是简化版,并未完全对应比特币中的区块。该区块包含唯一标识符、父节点哈希值、nonce值以及区块内容字段。可以看到,一个区块的哈希值必须满足特定条件(例如以0000开头)才是有效的。接下来对该区块结构进行初始化。
In [37]:
# 创建一个内容为hello world的内容块
block = Block('Hello World')
block
Out[37]:
Block<Hash: 238a65a101c8829d7fc406eb78a71cfc19ad702b437e2c1be8d9061ddb81e900, Nonce: None>
以上区块虽然创建完成,但其哈希值尚未有效。
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.py
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):
'''
计算区块的哈希值
'''
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):
'''
校验区块哈希值有否有效
'''
return the_hash.startswith('0000')
def __repr__(self):
return 'Block<Hash: {}, Nonce: {}>'.format(self.hash(self.nonce), self.nonce)
'''
新增挖矿函数
'''
def mine(self):
# 初始化nonce为0
cur_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')
# 挖矿,循环直至找到合适的nonce
block.mine()
# 打印
block
Out[75]:
Block<Hash: 000087359d5264153d624556f0a0c6f25cba06e453975c1c02587862e823911b, Nonce: 64751>
至此,第一个有效区块生成完成,接下来开始定义区块链。
二、定义区块链结构
In [81]:
class BlockChain(object):
def __init__(self):
self.head = None # 指向最新的一个区块
self.blocks = {} # 包含所有区块的一个字典
'''
添加区块函数
'''
def add_block(self, new_block):
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
)
定义好区块链结构后,下面开始初始化一条区块链。
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]:
# 添加更多的区块 for i in range(6): new_block = Block(i) new_block.mine() chain.add_block(new_block) # 打印 chain
Out[84]:
Blockchain<7 Blocks, Head: e7cb24ec7acd42a4aaebe7faee9e0713>
以上是一个简单区块链,后续还将涉及区块链的有效性验证。当区块链中一个区块被改变后,该区块的哈希值会随之改变,进而影响该区块之后的所有区块,致使整个区块链失效。这些内容将在后续深入探讨。
总结
以上就是本文的全部内容,希望本文的内容对大家的学习或工作能带来一定的帮助。如果有疑问,欢迎留言交流,感谢大家对本站的支持。
本站声明
本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。













