您知道比特币是建立在区块链上的吗?今天我们将使用 Python 从头开始构建区块链。

什么是区块链?
2008 年,一位名叫中本聪 (Satoshi Nakamoto) 的不知名个人或团体发表了一篇比特币论文。比特币作为电子货币的点对点版本出现,允许在没有中央机构(银行)的情况下进行交易。大多数人不知道,在同一篇论文中,中本聪定义了一种去中心化的信息存储方法,今天称为区块链。

简而言之,区块链是一种共享的、不可变的数字分类账,将交易存储在分布式计算机网络上。
区块链可以分为两个简单的术语。
- 区块:存储交易的空间
- 链:一组链接的记录
它将区块链定义为链接块的链,其中每个块存储使用某些参数进行的交易。
每个区块都建立在另一个区块之上,创建不可逆转的区块链。换句话说,每个块都依赖于另一个块。这创建了一个强大的、不可变的系统,任何具有适当权限的人都可以验证其完整性。
区块链引入了一组有趣的功能。
- 历史的不变性
- 信息的持久性
- 保存的数据没有错误
目前许多系统都依赖于区块链,包括加密货币、资产转移(NFT),或许在不久的将来还会进行投票。
请注意,Python 区块链不一定是具有数千行代码的复杂程序。其核心是相互关联的交易列表。
当然,这是一个简短的解释,但如果您想要完整的指南,我们为初学者创建了一个完整的区块链教程。请检查一下。
让我们开始使用 Python 构建一个简单的区块链。

使用 Python 构建区块链
在开始之前,让我们定义一下我们将在本教程中做什么。
- 构建一个用Python编写的简单区块链系统
- 使用区块链和以字符串表示的预先建立的交易
- 测试区块链的不变性
使用 Python 列表而不是 JSON。这简化了流程,让您能够专注于应用关键的区块链概念。
学习本教程需要满足以下条件:
- 了解 Python 类和方法
- 命令行的基本使用
创建块类
打开您最喜欢的代码编辑器并创建一个main.py文件。这将是您将要使用的文件。
接下来,导入hashlib ,这是一个允许您创建单向加密消息的模块。通过哈希等加密技术,区块链创建安全交易。
哈希函数是一种获取数据(通常是编码字符串)并返回唯一标识符(通常称为“摘要”或“签名”)的算法。最后一部分非常重要。在哈希函数中,输入中的微小差异会产生完全不同的标识符作为输出。稍后我们会看看实际情况。
这里我们只导入内置模块hashlib。
# main.py file
"""
A simple Blockchain in Python
"""
import hashlib该模块包含您需要的大部分哈希算法。请注意,它使用hashlib.sha256()函数。
现在我们来谈谈GeekCoinBlock,一个完全原创的区块链名称。
class GeekCoinBlock:
def __init__(self, previous_block_hash, transaction_list):
self.previous_block_hash = previous_block_hash
self.transaction_list = transaction_list
self.block_data = f"{' - '.join(transaction_list)} - {previous_block_hash}"
self.block_hash = hashlib.sha256(self.block_data.encode()).hexdigest()我知道这会使您的代码变得笨拙。让我们在接下来的部分中仔细研究每个部分。
极客币块描述
首先,创建一个名为GeekCoinBlock的类,它是具有某些特征(属性)和行为(方法)的对象的包装器。
接下来,定义一个 __init__方法(也称为构造函数),每当创建 GeekCoinBlock 对象时都会调用该方法。
该方法有三个参数。
- self (每个对象的实例)
- previous_block_hash (引用前一个块)
- transaction_list (当前块中进行的交易列表)。
保存以前的哈希值和交易的列表,并创建一个实例变量block_data作为字符串。真正的加密货币不会发生这种情况。加密货币将此类数据存储为单独的哈希值,但为了简单起见,我们将每个数据块存储为字符串。
最后,创建一个 block_hash,其他块将使用它来继续链。这就是 hashlib 派上用场的地方。您可以使用预构建的sha256来创建不可变块,而不是创建自定义哈希函数。
该函数采用编码字符串(或字节)作为参数。这就是我使用block_data.encode()方法的原因。然后调用hexdigest()以十六进制格式返回编码后的数据。
完成所有这些可能会很痛苦,所以让我们尝试在 Python shell 中使用 hashlib。
In [1]: import hashlib
In [2]: message = "Python is great"
In [3]: h1 = hashlib.sha256(message.encode())
In [4]: h1
Out[4]: <sha256 ... object @ 0x7efcd55bfbf0>
In [5]: h1.hexdigest()
Out[5]: 'a40cf9cca ... 42ab97'
In [6]: h2 = hashlib.sha256(b"Python is not great")
In [7]: h2
Out[7]: <sha256 ... object @ 0x7efcd55bfc90>
In [8]: h2.hexdigest()
Out[8]: 'fefe510a6a ... 97e010c0ea34'正如您所看到的,稍微改变输入,例如从“Python 很棒”到“Python 很糟糕”,可以产生完全不同的哈希值。这一切都关系到区块链的完整性。对区块链进行微小的改变将极大地改变它的哈希值。这就是为什么“你不能破坏区块链”这句格言是正确的。
使用块类
稍后我们将构建整个 Blockchain 类,但现在让我们使用 Block 类来创建区块链(Blockchain)。
在同一文件中,创建多个由存储在变量中的简单字符串组成的事务。例如:
class GeekCoinBlock:
...
t1 = "Noah sends 5 GC to Mark"
t2 = "Mark sends 2.3 GC to James"
t3 = "James sends 4.2 GC to Alisson"
t4 = "Alisson sends 1.1 GC to Noah"
当然,GC指的是GeekCoin。
接下来,我们使用 GeekCoinBlock 类构造区块链的第一个块并打印其属性。考虑创世块(其他块之前的第一个块)的previous_hash参数始终是任意字符串或哈希(在本例中为“firstblock”)。
block1 = GeekCoinBlock('firstblock', [t1, t2])
print(f"Block 1 data: {block1.block_data}")
print(f"Block 1 hash: {block1.block_hash}")然后对第二个块执行相同的操作,但将第一个块的哈希值作为previous_hash参数传递。
block2 = GeekCoinBlock(block1.block_hash, [t3, t4])
print(f"Block 2 data: {block2.block_data}")
print(f"Block 2 hash: {block2.block_hash}")让我们运行并分析这段代码的输出。再次输入终端。
❯ python main.py
Block 1 data: Noah sends 5 GC to Mark - Mark sends 2.3 GC to James - firstblock
Block 1 hash: 01e4e15242a9601725f4a86ca01fbddaaec7105b442955bb0efcadbfc759806d
Block 2 data: James sends 4.2 GC to Alisson - Alisson sends 1.1 GC to Noah - 01e4e15242a9601725f4a86ca01fbddaaec7105b442955bb0efcadbfc759806d
Block 2 hash: 448c4306caf7f6937b0307f92f27fbea3bb73b3470363dee5026a1209dadcfa8目前,只有文本和一些 64 字符哈希可见,但这大致复制了区块链机制。
我们从创世区块开始,它是所有其他区块的基础。
区块链是一个非常安全的系统,因为任何人都可以验证链的完整性。例如,如果您稍微更改交易的内容,它将如下所示:
t2 = "Mark sends 2.3 GC to James" -> t2 = "Mark sends 3.2 GC to James" 我们看到区块的哈希值发生了巨大的变化。
Block 1 data: Noah sends 5 GC to Mark - Mark sends 3.2 GC to James - firstblock
Block 1 hash: 7a990bf1d70230bf2dad6160496c0b3046da7a17b1281fd1d4c63d4eac58e78c
Block 2 data: James sends 4.2 GC to Alisson - Alisson sends 1.1 GC to Noah - 7a990bf1d70230bf2dad6160496c0b3046da7a17b1281fd1d4c63d4eac58e78c
Block 2 hash: 569b977306ce88b53e001dca7ba00c03a51c60d6df4650e7657dcd136f2da0ac当前项目可以在此GitHub 存储库中找到。
区块链编码
基于手动编码变量建立系统完整性并不是很明智,因此需要采用不同的方法。
有块。是时候构建一个将它们连接到区块链的类了。
首先,我们删除之前的交易和区块对象,然后使用下面的代码。
# main.py
class Blockchain:
def __init__(self):
self.chain = []
self.generate_genesis_block()
def generate_genesis_block(self):
self.chain.append(GeekCoinBlock("0", ['Genesis Block']))
def create_block_from_transaction(self, transaction_list):
previous_block_hash = self.last_block.block_hash
self.chain.append(GeekCoinBlock(previous_block_hash, transaction_list))
def display_chain(self):
for i in range(len(self.chain)):
print(f"Data {i + 1}: {self.chain[i].block_data}")
print(f"Hash {i + 1}: {self.chain[i].block_hash}\n")
@property
def last_block(self):
return self.chain[-1]这也是一大段代码。让我们分解每个部分。
- self.chain — 列出所有区块的记录位置。每个块都可以通过列表索引来访问。
- generate_genesis_block — 将创世块或第一个块添加到链中。该块之前的哈希值是“0”,交易列表只是“创世块”。
- create_block_from_transaction — 这允许您仅使用交易列表将块添加到链中。每次想要记录交易时都手动创建一个区块是非常繁琐的。
- display_chain — 使用 for 循环打印块链。
- last_block — 允许访问链的最后一个元素的属性。我在create_block_from_transaction方法中使用了它。
让我们测试一下这个区块链。
# main.py
import hashlib
class GeekCoinBlock:
...
class Blockchain:
...
t1 = "George sends 3.1 GC to Joe"
t2 = "Joe sends 2.5 GC to Adam"
t3 = "Adam sends 1.2 GC to Bob"
t4 = "Bob sends 0.5 GC to Charlie"
t5 = "Charlie sends 0.2 GC to David"
t6 = "David sends 0.1 GC to Eric"
myblockchain = Blockchain()
myblockchain.create_block_from_transaction([t1, t2])
myblockchain.create_block_from_transaction([t3, t4])
myblockchain.create_block_from_transaction([t5, t6])
myblockchain.display_chain()接下来,运行main.py文件。
Data 1: Genesis Block - 0
Hash 1: 39331a6a2ea1cf31a5014b2a7c9e8dfad82df0b0666e81ce04cf8173cc5aed3e
Data 2: George sends 3.1 GC to Joe - Joe sends 2.5 GC to Adam - 39331a6a2ea1cf31a5014b2a7c9e8dfad82df0b0666e81ce04cf8173cc5aed3e
Hash 2: 98cf363aecb33989aea0425a3c1287268bd86f63851bc08c0734a31db08506d5
Data 3: Adam sends 1.2 GC to Bob - Bob sends 0.5 GC to Charlie - 98cf363aecb33989aea0425a3c1287268bd86f63851bc08c0734a31db08506d5
Hash 3: 6f1cfcc3082488b97db8fdf8ed33f9ac7519be3e285a37a6fcc2f1904f373589
Data 4: Charlie sends 0.2 GC to David - David sends 0.1 GC to Eric - 6f1cfcc3082488b97db8fdf8ed33f9ac7519be3e285a37a6fcc2f1904f373589
Hash 4: 869df2f03c9860767d35b30a46233fbeea89a3000ae5019d1491e3829d1ab929恭喜! 🙌 我们从头开始创建了一个简单的 Python 区块链。
Getter 和 Setter 现在可用于强制区块链不变性并实现其他功能,例如工作量证明、挖矿或比特币挖矿基础知识 Ta 中讨论的其他概念。
结论
区块链是比特币、以太坊和所有其他加密货币背后的技术。在本文中,您学习了如何使用sha256等哈希算法、类和对象在 Python 中创建区块链。
您的任务是创建一个采矿系统。为什么不使用 Django 或 Flask 等框架通过 REST API 来实现它?
许多人正在通过加密货币积累财富。想象一下,如果您自己创建的话,您会做什么! 🤑
继续编码! 👨💻




![2021 年如何设置 Raspberry Pi Web 服务器 [指南]](https://i0.wp.com/pcmanabu.com/wp-content/uploads/2019/10/web-server-02-309x198.png?w=1200&resize=1200,0&ssl=1)

