Python区块链 创建矿工


为了启用挖矿,我们需要开发一个挖矿功能。挖掘功能需要对给定的消息字符串生成摘要并提供工作量证明。让我们在本章讨论这个问题。

消息摘要功能


我们将编写一个实用函数,称为 sha256 为给定消息创建摘要:

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

The sha256 函数需要一个 message 作为参数,将其编码为 ASCII,生成十六进制摘要并将值返回给调用者。

挖矿功能


我们现在开发 mine 实现我们自己的挖矿策略的函数。在这种情况下,我们的策略是在给定消息上生成一个以给定数量 1 为前缀的散列。给定数量的 1 被指定为参数 mine 指定为难度级别的函数。

例如,如果你指定难度级别为 2,则在给定消息上生成的哈希应该以两个 1 开头 - 例如 11xxxxxxxx。如果难度级别为 3,则生成的哈希应该以三个 1 开头 - 例如 111xxxxxxxx。鉴于这些要求,我们现在将开发挖掘功能,如下面给出的步骤所示。

步骤 1

挖掘函数有两个参数——消息和难度级别。

def mine(message, difficulty=1):

步骤 2

难度级别需要大于或等于 1,我们使用以下断言语句来确保这一点:

assert difficulty >= 1

步骤 3

我们创建一个 prefix 变量使用设定的难度级别。

prefix = '1' * difficulty

请注意,如果难度级别为 2,则前缀为“11”,如果难度级别为 3,则前缀为“111”,依此类推。我们将检查该前缀是否存在于生成的消息摘要中。为了消化消息本身,我们使用以下两行代码:

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

我们继续添加一个新号码 i 到每次迭代中的消息哈希,并在组合消息上生成一个新的摘要。作为输入 sha256 每次迭代函数都会发生变化, digest 值也会改变。我们检查这是否 digest 价值高于设定 prefix .

if digest.startswith(prefix):

如果条件满足,我们将终止 for 循环并返回 digest 对调用者的价值。

整个 mine 代码如下:

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

为了你的理解,我们添加了 print 打印摘要值和从函数返回之前满足条件所花费的迭代次数的语句。

测试挖矿功能

要测试我们的挖矿功能,只需执行以下语句:

mine ("test message", 2)

当你运行上面的代码时,你会看到类似下面的输出:

after 138 iterations found nonce:
11008a740eb2fa6bf8d55baecda42a41993ca65ce66b2d3889477e6bfad1484c

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

现在,我们准备向我们的区块链添加更多块。让我们在下一章学习这一点。