Python区块链教程(三)


来源  https://zhuanlan.zhihu.com/p/142725671

1. 简介

此区块链教程将详细介绍区块链背后的理论;讨论比特币的复杂性,全面解释区块链架构,并建立我们自己的区块链;介绍如何构建上述系统,并在市场上推出自己的数字货币。

整个区块链项目开发包括3个主要部分:客户(Client)、矿工(Miners)、区块链(Blockchain)。

2. 创建矿工

为了启用挖掘,需要开发挖掘功能。 挖掘功能需要在给定的消息字符串上生成摘要,并提供工作量证明。

2.1 Message Digest函数

在给定消息上创建摘要:

def sha256(message):
    return hashlib.sha256(message.encode('ascii')).hexdigest()

sha256函数将消息作为参数,将其编码为ASCII,生成十六进制摘要并返回。

2.2 挖矿函数

下面开发挖矿函数, 我们的策略是在给定消息上生成哈希值,该哈希值以给定数字1开头。 给定的数字1为挖矿函数的参数,表示难度级别。例如,如果将难度级别指定为2,则给定消息上生成的哈希值应以2个1(例如11xxxxxxxx)开头。 如果难度级别为3,则生成的哈希值应以3个1(例如111xxxxxxxx)开头。

(1) 挖矿函数接受2个参数:消息和难度级别:

def mine(message, difficulty=1):

(2) 难度级别需要大于或等于1,使用断言语句来保证要求:

assert difficulty >= 1

(3) 设置难度等级:

prefix = '1' * difficulty

注意:如果难度级别为2,则前缀为“11”;如果难度级别为3,则前缀为“111”,依此类推。 我们需要检查生成的消息摘要中是否存在此前缀。

for i in range(1000):
    digest = sha256(str(hash(message)) + str(i))

每次迭代中,持续向消息哈希中添加新的数字i,并在合并后的消息上生成新的摘要。随着 sha256函数的输入在每次迭代中都发生变化,摘要值也会发生变化。 检查此摘要值是否具有上面设置的前缀。

if digest.startswith(prefix):

如果条件满足,终止for循环并将摘要值返回给调用方。

mine函数的全部代码:

def mine(message, difficulty=1):
    assert difficulty >= 1
    prefix = '1' * difficulty
    for i in range(10000):
        digest = sha256(str(hash(message)) + str(i))
        if digest.startswith(prefix):
            print("after " + str(i) + " iterations found nonce: "+ digest)
            return digest

2.3 测试函数

mine("test message", 2)
after 116 iterations found nonce: 11aada3a305070f018eeb6ba827f1febfb4c4152ee509c1730366201788d0ba7

注意:生成的摘要以“11”开头。 如果将难度级别更改为3,则生成的摘要将以“111”开头,当然,它可能需要更多的迭代次数。具有更高处理能力的矿工将能够更早地挖掘到给定消息。 这就是矿工相互竞争以赚取收入的方式。

下面准备向我们的区块链添加更多的块。

3. 添加Blocks

每个矿工从先前创建的交易池中提取交易。 要跟踪已挖掘的消息数,需要创建一个全局变量:

last_transaction_index = 0

将第1个矿工添加一个块到区块链。

3.1 添加第一个块

要添加一个新块,首先创建block类的一个实例。

block = Block()

从队列中取出前3个交易:

for i in range(3):
    temp_transaction = transactions[last_transaction_index]
    # 验证交易

将交易添加到区块前,矿工需要验证交易的有效性。交易的有效性通过测试发送方提供的哈希值与矿工使用发送方的公钥生成的哈希值是否相等来验证。此外,矿工将验证发件方是否有足够的余额来支付当前交易。

为简便起见,本教程中未包含此功能。 验证交易之后,将其添加到区块实例的verify_transactions列表中。

block.verified_transactions.append(temp_transaction)

增加最后一个交易的索引,以便下一个矿工在队列中提取后续的交易。

last_transaction_index += 1

将3个交易添加到该块。 完成此操作后,将初始化Block类的其余实例变量。 首先添加最后一个块的哈希值。

block.previous_block_hash = last_block_hash

以难度等级2来开采这个块。

block.Nonce = mine(block, 2)

注意:mine函数的第1个参数是二进制对象。对整个块进行哈希处理并在其上创建摘要。

digest = hash(block)

将创建的块添加到区块链,并重新初始化全局变量last_block_hash以便在下一个块中使用。

添加块的整个代码如下:

block = Block()
for i in range(3):
    temp_transaction = transactions[last_transaction_index]
    # 验证交易
    # 若有效
    block.verified_transactions.append(temp_transaction)
    last_transaction_index += 1

block.previous_block_hash = last_block_hash
block.Nonce = mine(block, 2)
digest = hash(block)
TPCoins.append(block)
last_block_hash = digest

3.2 添加更多块

将向区块链添加另外两个块:

# Miner 2 adds a block
block = Block()
for i in range(3):
    temp_transaction = transactions[last_transaction_index]
    # 验证交易,if valid
    block.verified_transactions.append (temp_transaction)
    last_transaction_index += 1
block.previous_block_hash = last_block_hash
block.Nonce = mine(block, 2)
digest = hash(block)
TPCoins.append (block)
last_block_hash = digest

# Miner 3 adds a block
block = Block()
for i in range(3):
   temp_transaction = transactions[last_transaction_index]
   # validate transaction, if valid
   block.verified_transactions.append (temp_transaction)
   last_transaction_index += 1

block.previous_block_hash = last_block_hash
block.Nonce = mine(block, 2)
digest = hash(block)
TPCoins.append(block)
last_block_hash = digest

当添加这两个块时,还将看到找到Nonce所需的迭代次数。 至此,我们的区块链总共包括初始区块在内共4个区块。

3.3 整个区块链

验证整个区块链的内容:

dump_blockchain(TPCoins)

输出为:

Number of blocks in the chain: 4
block # 0
sender: Genesis
--------------------
recipient: 30819f300d06092a864886f70d010101050003818d0030818902818100b8c7cfaa8289d0ad11fe87e774931407ff0b67578004727b3c6b3a84f86691fe826f04f919c805e8b5153ce84619863c103a5278cf6ed7ee94ae3fc23a37c3ef4fb267c1ae6a6309fde009e29faf4151fdbb23cc4b44c3ad89e71536d3f50d6556bcff7da90f2d8e45398d14d716ffe91e1119b451d37a52eadc2b94d0f29a090203010001
--------------------
value: 500.0
--------------------
time: 2020-05-22 09:35:51.722081
--------------------
----------
========================================
block # 1
sender: 30819f300d06092a864886f70d010101050003818d0030818902818100b410329e898d3b3681eefc6e4394f59e21009e7ad2328a4fa65e8fa299a53cc9855995e4037b7d36b25a17c57a25ecb4b031312523d977faca311669f11c6eb2388147279b6baf7562d0dd46428fe85bb5535a83055c8ed664ea2d3fb63caaeff81c4d08a5e2dfb97535026793479904e77b4f52b34a475f9e678036f53b8e650203010001
--------------------
recipient: 30819f300d06092a864886f70d010101050003818d0030818902818100b9ef942ac0562e6416780a628d12afb24264cc03bb5f7dda579e173bd8d65961f5735415c74ffa44cb6900094ac87fab5c5c3b4afbbb128809439e2a72e7831e6035c8413167b5fcf666b3dea9fda7d1f107b319320972e5ed3954843d8133bd832d03452a2915727a96dec77c01afd93ef957820436ae5d16c1ea27312e924f0203010001
--------------------
value: 5.0
--------------------
time: 2020-05-22 09:35:51.415112
--------------------
----------
sender: 30819f300d06092a864886f70d010101050003818d0030818902818100b410329e898d3b3681eefc6e4394f59e21009e7ad2328a4fa65e8fa299a53cc9855995e4037b7d36b25a17c57a25ecb4b031312523d977faca311669f11c6eb2388147279b6baf7562d0dd46428fe85bb5535a83055c8ed664ea2d3fb63caaeff81c4d08a5e2dfb97535026793479904e77b4f52b34a475f9e678036f53b8e650203010001
--------------------
recipient: 30819f300d06092a864886f70d010101050003818d0030818902818100d7797c2585d8787ef6d08c107ed25e03de15f06683fdbf9819499a5116a26a17e11a3b8eca13d11dd764723a8cd4590ea67af3e0785433bbad16052ba4f709be6d15fdf279be0f619d5c054aef1aef30a29038393d28c742e80fb64ceb31151060ef1103e1c54da356817265f9a04a185011e51fbdaeb76ec8ea1eb1b2bccda30203010001
--------------------
value: 6.0
--------------------
time: 2020-05-22 09:35:51.419113
--------------------
----------
sender: 30819f300d06092a864886f70d010101050003818d0030818902818100b9ef942ac0562e6416780a628d12afb24264cc03bb5f7dda579e173bd8d65961f5735415c74ffa44cb6900094ac87fab5c5c3b4afbbb128809439e2a72e7831e6035c8413167b5fcf666b3dea9fda7d1f107b319320972e5ed3954843d8133bd832d03452a2915727a96dec77c01afd93ef957820436ae5d16c1ea27312e924f0203010001
--------------------
recipient: 30819f300d06092a864886f70d010101050003818d0030818902818100a8ae95c886a44e9ec6ce49e04eac295d6bc22fab06783d62e5c3d8e893a85e301d427ee435ab216c8442043c9c2ee981d3a90ba65269b3208b1d9f581b81d165f4589626d00090ad81081b2be721fb2b37ca89a597c2de4b00283ed7cb65de21312e90e0d9f9059aab038090b4649299b9fbf592cd1cab88efd71b869e907bcb0203010001
--------------------
value: 2.0
--------------------
time: 2020-05-22 09:35:51.421112
--------------------
----------
========================================
block # 2
sender: 30819f300d06092a864886f70d010101050003818d0030818902818100d7797c2585d8787ef6d08c107ed25e03de15f06683fdbf9819499a5116a26a17e11a3b8eca13d11dd764723a8cd4590ea67af3e0785433bbad16052ba4f709be6d15fdf279be0f619d5c054aef1aef30a29038393d28c742e80fb64ceb31151060ef1103e1c54da356817265f9a04a185011e51fbdaeb76ec8ea1eb1b2bccda30203010001
--------------------
recipient: 30819f300d06092a864886f70d010101050003818d0030818902818100b9ef942ac0562e6416780a628d12afb24264cc03bb5f7dda579e173bd8d65961f5735415c74ffa44cb6900094ac87fab5c5c3b4afbbb128809439e2a72e7831e6035c8413167b5fcf666b3dea9fda7d1f107b319320972e5ed3954843d8133bd832d03452a2915727a96dec77c01afd93ef957820436ae5d16c1ea27312e924f0203010001
--------------------
value: 4.0
--------------------
time: 2020-05-22 09:35:51.424114
--------------------
----------
sender: 30819f300d06092a864886f70d010101050003818d0030818902818100a8ae95c886a44e9ec6ce49e04eac295d6bc22fab06783d62e5c3d8e893a85e301d427ee435ab216c8442043c9c2ee981d3a90ba65269b3208b1d9f581b81d165f4589626d00090ad81081b2be721fb2b37ca89a597c2de4b00283ed7cb65de21312e90e0d9f9059aab038090b4649299b9fbf592cd1cab88efd71b869e907bcb0203010001
--------------------
recipient: 30819f300d06092a864886f70d010101050003818d0030818902818100d7797c2585d8787ef6d08c107ed25e03de15f06683fdbf9819499a5116a26a17e11a3b8eca13d11dd764723a8cd4590ea67af3e0785433bbad16052ba4f709be6d15fdf279be0f619d5c054aef1aef30a29038393d28c742e80fb64ceb31151060ef1103e1c54da356817265f9a04a185011e51fbdaeb76ec8ea1eb1b2bccda30203010001
--------------------
value: 7.0
--------------------
time: 2020-05-22 09:35:51.427113
--------------------
----------
sender: 30819f300d06092a864886f70d010101050003818d0030818902818100b9ef942ac0562e6416780a628d12afb24264cc03bb5f7dda579e173bd8d65961f5735415c74ffa44cb6900094ac87fab5c5c3b4afbbb128809439e2a72e7831e6035c8413167b5fcf666b3dea9fda7d1f107b319320972e5ed3954843d8133bd832d03452a2915727a96dec77c01afd93ef957820436ae5d16c1ea27312e924f0203010001
--------------------
recipient: 30819f300d06092a864886f70d010101050003818d0030818902818100d7797c2585d8787ef6d08c107ed25e03de15f06683fdbf9819499a5116a26a17e11a3b8eca13d11dd764723a8cd4590ea67af3e0785433bbad16052ba4f709be6d15fdf279be0f619d5c054aef1aef30a29038393d28c742e80fb64ceb31151060ef1103e1c54da356817265f9a04a185011e51fbdaeb76ec8ea1eb1b2bccda30203010001
--------------------
value: 3.0
--------------------
time: 2020-05-22 09:35:51.430113
--------------------
----------
========================================
block # 3
sender: 30819f300d06092a864886f70d010101050003818d0030818902818100d7797c2585d8787ef6d08c107ed25e03de15f06683fdbf9819499a5116a26a17e11a3b8eca13d11dd764723a8cd4590ea67af3e0785433bbad16052ba4f709be6d15fdf279be0f619d5c054aef1aef30a29038393d28c742e80fb64ceb31151060ef1103e1c54da356817265f9a04a185011e51fbdaeb76ec8ea1eb1b2bccda30203010001
--------------------
recipient: 30819f300d06092a864886f70d010101050003818d0030818902818100b410329e898d3b3681eefc6e4394f59e21009e7ad2328a4fa65e8fa299a53cc9855995e4037b7d36b25a17c57a25ecb4b031312523d977faca311669f11c6eb2388147279b6baf7562d0dd46428fe85bb5535a83055c8ed664ea2d3fb63caaeff81c4d08a5e2dfb97535026793479904e77b4f52b34a475f9e678036f53b8e650203010001
--------------------
value: 8.0
--------------------
time: 2020-05-22 09:35:51.433089
--------------------
----------
sender: 30819f300d06092a864886f70d010101050003818d0030818902818100d7797c2585d8787ef6d08c107ed25e03de15f06683fdbf9819499a5116a26a17e11a3b8eca13d11dd764723a8cd4590ea67af3e0785433bbad16052ba4f709be6d15fdf279be0f619d5c054aef1aef30a29038393d28c742e80fb64ceb31151060ef1103e1c54da356817265f9a04a185011e51fbdaeb76ec8ea1eb1b2bccda30203010001
--------------------
recipient: 30819f300d06092a864886f70d010101050003818d0030818902818100b9ef942ac0562e6416780a628d12afb24264cc03bb5f7dda579e173bd8d65961f5735415c74ffa44cb6900094ac87fab5c5c3b4afbbb128809439e2a72e7831e6035c8413167b5fcf666b3dea9fda7d1f107b319320972e5ed3954843d8133bd832d03452a2915727a96dec77c01afd93ef957820436ae5d16c1ea27312e924f0203010001
--------------------
value: 1.0
--------------------
time: 2020-05-22 09:35:51.436084
--------------------
----------
sender: 30819f300d06092a864886f70d010101050003818d0030818902818100a8ae95c886a44e9ec6ce49e04eac295d6bc22fab06783d62e5c3d8e893a85e301d427ee435ab216c8442043c9c2ee981d3a90ba65269b3208b1d9f581b81d165f4589626d00090ad81081b2be721fb2b37ca89a597c2de4b00283ed7cb65de21312e90e0d9f9059aab038090b4649299b9fbf592cd1cab88efd71b869e907bcb0203010001
--------------------
recipient: 30819f300d06092a864886f70d010101050003818d0030818902818100b410329e898d3b3681eefc6e4394f59e21009e7ad2328a4fa65e8fa299a53cc9855995e4037b7d36b25a17c57a25ecb4b031312523d977faca311669f11c6eb2388147279b6baf7562d0dd46428fe85bb5535a83055c8ed664ea2d3fb63caaeff81c4d08a5e2dfb97535026793479904e77b4f52b34a475f9e678036f53b8e650203010001
--------------------
value: 5.0
--------------------
time: 2020-05-22 09:35:51.439083
--------------------
----------
========================================

4. 总结

学习了如何在Python中构建区块链项目。你需要在许多领域中为该项目添加更多功能。

例如,需要编写用于管理事务队列的函数。在交易被开采并且被开采的区块被系统接受之后,它们不再需要被存储。

另外,矿工当然更愿意以最高的费用进行交易。同时,你将必须确保收费低或不收费的交易不会永远饿死。

你将需要开发用于管理队列的算法。另外,当前教程不包含客户端接口代码。你将需要为普通客户和矿工开发此工具。

相关