zhcn 金融科技 个人贷款 非公開: 如何用Python创建区块链?

如何用Python创建区块链?

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

如何用Python创建区块链?
如何用Python创建区块链?

什么是区块链?

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

区块链技术
区块链技术

简而言之,区块链是一种共享的、不可变的数字分类账,将交易存储在分布式计算机网络上。

区块链可以分为两个简单的术语。

  • 区块:存储交易的空间
  • 链:一组链接的记录

它将区块链定义为链接块的链,其中每个块存储使用某些参数进行的交易。

每个区块都建立在另一个区块之上,创建不可逆转的区块链。换句话说,每个块都依赖于另一个块。这创建了一个强大的、不可变的系统,任何具有适当权限的人都可以验证其完整性。

区块链引入了一组有趣的功能。

  • 历史的不变性
  • 信息的持久性
  • 保存的数据没有错误

目前许多系统都依赖于区块链,包括加密货币、资产转移(NFT),或许在不久的将来还会进行投票。

请注意,Python 区块链不一定是具有数千行代码的复杂程序。其核心是相互关联的交易列表。

当然,这是一个简短的解释,但如果您想要完整的指南,我们为初学者创建了一个完整的区块链教程。请检查一下。

让我们开始使用 Python 构建一个简单的区块链。

如何用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 来实现它?

许多人正在通过加密货币积累财富。想象一下,如果您自己创建的话,您会做什么! 🤑

继续编码! 👨‍💻

如何用Python创建区块链?
如何用Python创建区块链?

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

如何用Python创建区块链?
如何用Python创建区块链?

什么是区块链?

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

区块链技术
区块链技术

简而言之,区块链是一种共享的、不可变的数字分类账,将交易存储在分布式计算机网络上。

区块链可以分为两个简单的术语。

  • 区块:存储交易的空间
  • 链:一组链接的记录

它将区块链定义为链接块的链,其中每个块存储使用某些参数进行的交易。

每个区块都建立在另一个区块之上,创建不可逆转的区块链。换句话说,每个块都依赖于另一个块。这创建了一个强大的、不可变的系统,任何具有适当权限的人都可以验证其完整性。

区块链引入了一组有趣的功能。

  • 历史的不变性
  • 信息的持久性
  • 保存的数据没有错误

目前许多系统都依赖于区块链,包括加密货币、资产转移(NFT),或许在不久的将来还会进行投票。

请注意,Python 区块链不一定是具有数千行代码的复杂程序。其核心是相互关联的交易列表。

当然,这是一个简短的解释,但如果您想要完整的指南,我们为初学者创建了一个完整的区块链教程。请检查一下。

让我们开始使用 Python 构建一个简单的区块链。

如何用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 来实现它?

许多人正在通过加密货币积累财富。想象一下,如果您自己创建的话,您会做什么! 🤑

继续编码! 👨‍💻

如何用Python创建区块链?
如何用Python创建区块链?