从零开始创建一个区块链,看看区块链内部如何运作的

01

做什么?

在本文中,我们将分析区块链技术背后的关键概念。我们将一起了解区块链的内部运作,并探索信息如何在服务器的分布式网络上公开存储。

02

怎么做?

这一切将通过从头开始构建一个简单的区块链来完成。我们将通过创建区块链的基本步骤,我将添加一些代码片段,以帮助你遵循 Python编程语言。但是,每一步都会有很好的记录,所以你可以用任何你喜欢的语言来进行操作。

本文中使用的源代码网址:https://github.com/jzsiggy/blockchain-from-scratch

图片[1]-从零开始创建一个区块链,看看区块链内部如何运作的-卡咪卡咪哈-一个博客
图片[2]-从零开始创建一个区块链,看看区块链内部如何运作的-卡咪卡咪哈-一个博客

第一章:区块链有什么了不起?

区块链在当今市场上越来越受欢迎。亚马逊、微软、谷歌和其他巨头公司已经开始提供区块链技术的相关服务。很多人经常将区块链与比特币等加密货币联系起来,但很多时候,事实并非如此。

现在,你可能会问自己,为什么区块链会得到这么多关注?有什么大不了的?

那么,事情是这样的–区块链允许我们创建安全的、公开的、分散的 “数据库 “来存储任何类型的信息。在区块链之前,大量的数据必须由某种形式的中间人或中介机构进行存储和验证。

就具有金融属性的数据而言,中介是银行、金融中介机构。我们依靠银行来跟踪我们所有的金融数据,我们相信他们不会以任何方式篡改或滥用我们的数据。这种方法是可行的,但是在这些机构的手中却拥有很大的权力。

区块链技术的核心思想是利用密码学和复杂的计算机算法,创造出一种安全透明的方法,将这些中介机构剔除出去,让数据由一个巨大的开放的服务器网络进行存储和验证。

让我们潜心研究,我们就会明白怎么做!

图片[3]-从零开始创建一个区块链,看看区块链内部如何运作的-卡咪卡咪哈-一个博客

第二章:数据是如何存储的?

区块是什么?

在我们开始之前–让我快速解释一下哈希函数(散列函数)。它们对我们的区块链工作非常非常重要!

哈希函数(散列函数)是一个函数,它接收一个任意长度的字符串作为输入,并返回一个固定长度的字符串,看起来非常随机,但不是随机的固定长度的字符串。每一个字符串都有它自己的输出哈希值,这个哈希值总是相同的。

字符串“ Hello world”的哈希如下所示:

图片[4]-从零开始创建一个区块链,看看区块链内部如何运作的-卡咪卡咪哈-一个博客

输入字符串 “Hello world “得到的SHA256哈希函数

需要注意的是,即使是对输入字符串的微小改动,输出的哈希值也是完全不同的。例如,我们少输入了一个“l”,如下所示:

图片[5]-从零开始创建一个区块链,看看区块链内部如何运作的-卡咪卡咪哈-一个博客

比较”Hello world “和”Helo world “两个字符串的哈希值

All right! Now let’s dive in!好了!让我们现在开始吧!

一个区块里有什么?

区块链中的一个区块存储了写入它的数据、前一个区块的哈希值和自己的哈希值。

图片[6]-从零开始创建一个区块链,看看区块链内部如何运作的-卡咪卡咪哈-一个博客

一旦数据写入区块,是很难更改的,因为每一个写入区块链的区块都会引用它之前区块的哈希值。这样一来,即使你轻描淡写地修改了一个区块,它的哈希值也会完全改变,所以后面的区块也要改变–因为它必须有前一个区块的哈希值–后面的区块以此类推。如果你修改了区块链的任何一个区块,你必须重写整个链。

图片[7]-从零开始创建一个区块链,看看区块链内部如何运作的-卡咪卡咪哈-一个博客

当我们把这个逻辑转化为代码时,在Python中,一个块的数据结构看起来就是现在这样的

图片[8]-从零开始创建一个区块链,看看区块链内部如何运作的-卡咪卡咪哈-一个博客

Python3中一个代码块的代码段

在我们的 Blockchain类的构造函数中,我们实例化了插入在块中的数据、前一个块的哈希值,我们对自己的块应用哈希函数,并将输出保存到哈希变量中。

我们还可以创建一个to_string方法,返回一个包含数据和前一个块的哈希值的字符串。

这意味着我们可以通过运行来创建一个块的数据结构。

图片[9]-从零开始创建一个区块链,看看区块链内部如何运作的-卡咪卡咪哈-一个博客

使用Python3中的Block类创建一个区块

在继续之前,让我指出每个区块链都必须有一个初始块,对吗?没有以前的块。此块称为“创世纪”块,通常将指向空哈希作为其前一个块。

图片[10]-从零开始创建一个区块链,看看区块链内部如何运作的-卡咪卡咪哈-一个博客

第三章:工作证明

为什么改写区块链如此困难?

在上一章中,我们了解到,如果要改变单个区块中的数据,我们必须从改变一个区块的点开始重写整个区块链。你可能会有疑问,既然不涉及复杂和耗时的操作,那么重写整个区块链的过程为什么会如此困难呢?

在本章中,我们将深入研究一个区块必须遵守的其他一些必要条件,这些条件使得区块非常难以伪造。

在开始之前,我们先回到我们的哈希函数。

这个函数还有一个重要的特性,我还没有提到,这个特性就是:无法进行反向计算。(区块链范式:散列函数是一个单项函数,这道函数题只能进行单项运算求解,无法进行逆向求值)

这意味着,虽然计算机从一个输入字符串中生成一个哈希是非常简单的,但仅仅通过知道输出结果来找到 “输入的字符串 “是非常困难的。实际上,除了猜测字符串并检查输出的哈希值是否是预期值之外,没有其他更好的方法来找到输入字符串。总而言之,要找到满足所需哈希值的输入字符串,需要2²⁵⁶次的猜测,即使对于计算机来说,这也只是一个无法形容的巨量猜测。

为了防止冒名顶替者修改区块并快速重写整个区块链,要成功伪造区块,其哈希必须遵循一个简单的规则:它必须以一定数量的零开头(零的位数决定了我们创建一个新的区块难度值「也就是挖矿的难度值」)。

举例,假设我们定义一个区块在我们的区块链中有效,它(哈希值)必须以 4个零开始。现在,每次我们想要向我们的区块链添加一个新的区块时,我们必须对其应用哈希函数,并查看输出的哈希是否以 4个零开始。如果不是,我们必须稍稍更改一下区块,然后重试。重复此过程,直到该块有效为止。

这就是工作证明背后的基本概念,也是为什么区块如此难以创建、篡改。该规则意味着要创建一个新块,需要花费大量的时间、精力和计算力。

这也意味着,在对块进行哈希处理时,我们必须添加其他信息:每次我们猜测时数字都会改变。这是确保每次猜测输入字符串都略有不同的必要条件,因此每次我们都有不同的哈希值。此数字称为Nonce(区块链范式:我们常说的随机数)。

挖矿

在进入代码之前,我们先来看看最后一个基础理论,以构成我们的区块链:区块挖矿。

如果你之前读过一篇关于区块链的深度文章,这个词肯定会出现。

在区块链网络上,粉碎这些计算复杂的算法以创建新区块的服务器被称为矿工。很多时候,在大型区块链中,这些矿工都是非常大的仓库,里面装满了服务器,24小时不眠不休地粉碎这些算法,以确保区块链的发展。

本章的理论就是这样!现在,让我们返回代码并修复 Blockchain类,以使其哈希服从我们的区块链规则,并以一定数量的零开始。

我们将 Blockchain类中添加一个新的方法,名为 calculate_valid_hash ,在这个方法中,我们将把 hash变量初始化为一个空字符串,nonce(随机数)为 0。当哈希值没有被 is_hash_valid 方法批准时,我们将递增 nonce值并再次尝试。当我们找到一个 nonce值,当它与块的数据进行哈希时,会被 is_hash_valid 方法批准,我们将停止循环,并将块的哈希值设置为我们计算的值。「区块链范式:本段大意为矿机不断循环的调整随机数来得出正确的哈希值」

我们将把这个新方法添加到我们的构造函数中。

图片[11]-从零开始创建一个区块链,看看区块链内部如何运作的-卡咪卡咪哈-一个博客

计算我们区块的有效哈希

通过这些修改,每次我们实例化一个新的区块时,我们都必须经过生成工作量证明的过程才能挖掘该块。

现在是时候创建一个新类:区块链。

当我们实例化 Blockchain类时,我们将把区块属性初始化为一个空数组。为此,我们将在构造函数中添加以下代码行。

图片[12]-从零开始创建一个区块链,看看区块链内部如何运作的-卡咪卡咪哈-一个博客

Blockchain类

现在,让我们在区块链类中添加一个方法来创建“创世区块”!这个方法将在我们区块链的构造函数中调用。

为此,我们必须创建 set_genesis_block 方法,并将数据变量初始化为 “创世块”(或任何你喜欢的变量)。我们还将初始化 prev_hash 变量为 64个零的字符串。现在我们将从这些数据中实例化一个区块,并将其添加为我们区块链的第一个区块。由于我们 Blockchain类的构造函数中的 calculate_valid_hash方法,我们可以保证这个区块将有一个有效的哈希值。

图片[13]-从零开始创建一个区块链,看看区块链内部如何运作的-卡咪卡咪哈-一个博客

初始化区块链时创建创世块

最后,为了完成我们的区块链,让我们添加一种方法来向我们的区块链添加一个块。这个方法将只接收区块中的输入数据。然后,它将获得上一个区块的哈希值,并根据先前的哈希和数据创建一个新块。与创世区块一样,由于 calculate_valid_hash方法的存在,我们可以保证新区块的哈希值是有效的。最后,我们将把新挖出的区块添加到我们的区块数组中。

图片[14]-从零开始创建一个区块链,看看区块链内部如何运作的-卡咪卡咪哈-一个博客

向我们的区块链添加一个新块

现在我们已经成功创建了整个区块链结构,我们可以像这样初始化!

图片[15]-从零开始创建一个区块链,看看区块链内部如何运作的-卡咪卡咪哈-一个博客

我们的主程序会初始化区块链并添加一些区块

我在 Blockchain类中创建了一个名为 get_blocks的可选方法,它可以返回一个包含所有区块的列表。这对我们调试、测试和可视化我们的区块链可能会很有趣。

当我们在终端或命令提示符上运行这段代码时,我们会得到这样的结果:

图片[16]-从零开始创建一个区块链,看看区块链内部如何运作的-卡咪卡咪哈-一个博客

main.py的输出

如果我们分析我们区块链中所有的区块哈希值,我们会发现它们都是以3个0开始的! 这向我们证明了这个区块确实是一个有效的区块,我们的机器必须做一些工作来挖掘这个区块。

比特币区块链中的区块哈希值是这样的:

图片[17]-从零开始创建一个区块链,看看区块链内部如何运作的-卡咪卡咪哈-一个博客

第四章:改进实施

我们已经成功地从头开始创建了一个完整的区块链,并在短时间内让它运行起来,但它仍然不是去中心化的,由许多节点组成。

将我们的区块链实现转换为去中心化的实现会稍微复杂一些,因此我将另一篇文章中解答,但是现在我们可以讨论必须考虑的其他一些因素。

目前,我们的电脑是这个区块链中唯一工作的节点。当我们调用 add_new_block方法时,所有的数据都来自我们的机器,我们的处理器也完成了所有的区块挖掘。

在分布式网络上的区块链,我们会有特定的节点进行挖矿。这些节点将监听网络中正在广播的新数据或交易,并将不断尝试找到使区块有效的随机数nonce。当一个矿工找到这个随机数值时,它将向网络中广播新的区块。网络中的所有其他节点很容易验证该区块是否有效,因为他们所要做的就是将散列函数应用到具有给定随机数的块上。如果区块以 X个零开始,那么这个区块就是有效的。

我们分布式网络上区块链的一个关键规则是,如果一个节点收到两个相互冲突的区块,并且两个区块都有有效的哈希值,则它必须信任具有最长历史记录的块(区块链范式:我们常说的最长链原则)。

这意味着,如果我们想在我们的区块链中插入一个带有欺诈信息的区块,我们不仅必须在网络开采一个真实的区块之前开采虚假区块,而且我们必须永远继续开采区块到我们伪造的这一条区块链上。

考虑到这一点,我们可以肯定,伪造一条区块链的唯一方法是拥有超过一半的网络算力。只有当你恰好拥有一半以上的网络算力时,你才会有必要的计算能力将伪造的区块插入链中,并从那里继续计算下去,添加新的区块,成为最长的那条链。

在像比特币或以太坊区块链这样的大型可信区块链网络中,拥有超过一半的网络实际上是不可能的,所以我们可以保证区块链是安全的。

    THE END
    喜欢就支持一下吧
    点赞9 分享
    评论 抢沙发
    头像
    欢迎您留下宝贵的见解!
    提交
    头像

    昵称

    取消
    昵称表情代码图片

      暂无评论内容