如果我们看看前几年的趋势,我们一直都听说过区块链,但具体细节并不多。
我们都知道,比特币、以太坊、狗狗币、Matic 等加密货币都依赖于区块链技术。 区块链引领了 2021 年为众多行业带来革命性变革的重大事件,并为取得新成就铺平了道路。
区块链是一种以难以或不可能编辑、破解或欺骗的方式存储数据的方法。 它是交易的数字分类账,在区块链的整个计算机系统网络中复制和传播。
它是一种突破性的数据库技术,几乎为所有加密货币提供支持。 区块链通过在整个网络中传播相同的数据库副本,使得破解或欺骗系统变得异常困难。
虽然比特币现在是区块链最突出的用途,但该技术可以服务于非常广泛的应用。
近年来,加密货币和区块链越来越受欢迎,预计这一趋势将持续下去。
在本教程中,我们将使用 JavaScript 制作一个简单的区块链。 它将让您对区块链的工作原理有一个基本的了解。
让我们称之为 MelodyCoin 并开始行动吧!
创建块
首先,我们将创建一个新的 JavaScript 文件,我们将在其中放置所有代码。
让我们将其称为 main.js,并从描述区块链和块的外观开始。
创建一个 Block 类并给它一个函数 Object() { [native code] } 开始。
创建新区块时,您必须给出日期和前一个区块的哈希值:
以下是每个属性的定义:
- 时间戳表示块的创建时间。 您可以使用您选择的任何格式(在本例中为 UNIX 时间戳)。
- 您希望连接到此块的任何形式的数据都可以包含在 data 参数中。 如果您希望创建加密货币,您可以在此处保留交易数据,例如发送方/接收方和转移的金额。
- previousHash 是一个保存前一个区块哈希的字符串。 这将生成区块链,这对于以后提供我们区块链的完整性至关重要。
创建哈希
每个块链接到前一个块(因此是 previousHash 属性)。 也就是说,每个块都需要一个哈希。 哈希类似于指纹。 每个块都是不同的。
一个区块的哈希值可以通过一个哈希函数传递它的所有内容来计算。
所以,让我们从实现一个计算当前块哈希的函数开始。
所以,在 Block 类下,我们定义了 calculateHash 函数:
但是,JavaScript 不支持 SHA256 哈希,必须从外部库中获取。
Crypto-js 是一个很棒的包,其中包括几个哈希算法的安全实现。
然后我们可以将它导入到我们的 main.js 代码中。
现在我们有了 calculateHash() 函数,让我们在 Block 的函数中使用它:
在描述了区块的外观之后,我们可以定义区块链应该是什么样子。 所以让我们创建一个新类。
在这种情况下,区块链是一个非常简单的具有属性链的对象。 这是一个包含链上所有块的数组。
在我们添加区块之前,我们必须首先创建所谓的“创世区块”。 这是链中的第一个块,它的独特之处在于它不能指向先前的块(它是第一个!)。
因此,为了构建创世区块,我将在我们的类中添加一个名为 createGenesisBlock () 的函数。 回到我们区块链类的函数 Object() { [native code] }。
我们现在可以在任何时候构建新的区块链实例时包含创世块:
区块链方法
现在,让我们向我们的 Blockchain 类添加方法,这将允许我们执行诸如添加新块和获取最新块之类的操作。
getLatestBlock 函数是最基本的。 它只是返回链数组的最后一个成员:
addBlock 技术涉及更多一点。
在我们可以向我们的链中添加一个新块之前,我们必须首先适当地设置该块的 previousHash 字段。
它必须设置为我们链中最近添加的块的哈希值。 我们还需要计算新块的哈希:
测试
让我们看看我们的 MelodyCoin 是如何诞生的。
创建一个区块链实例来完成此操作。 让我们再添加几个块:
我们在那里制作了两个新街区。 让我们来看看我们的区块链目前的样子。
MelodyCoin 将被字符串化并格式化为四个空格:
验证区块链的完整性
区块链很棒,因为一旦添加了一个块,就不能在不使链的其余部分失效的情况下对其进行修改。
但是,我没有办法通过这个实现来检查我们区块链的完整性。
让我们在我们的区块链中引入一个 isChainValid 函数。 如果链是合法的,它将返回 true; 否则,它将返回 false:
测试完整性
我们现在可以测试我们的区块链的完整性。 如果我们现在执行它,它将确认我们的链是真实的。
现在让我们尝试篡改我们的区块链。 让我们更改块 2 并覆盖其内容(假设我们转移了 100 个硬币而不是 XNUMX 个)。
当我们执行此操作时,我们可以看到软件识别出我们篡改链的努力。
但是,您可以相信我还有另一种方法可以干预。 我更改了块中的内容,但没有重新计算哈希。 所以你可以试着聪明一点,重新计算同一个区块的哈希值。
这就是我们小型区块链设置的全部内容! 它使我们能够添加新块并检测链中数据的篡改。
我们的小型区块链有两个问题需要解决:
- 现代计算机速度非常快,可以在几秒钟内将数千个区块添加到我们的链中。 我们显然不希望任何人向我们的区块链发送垃圾邮件。
- 我们的区块链仍然容易被篡改。 您可以更新块的内容,然后简单地重新计算所有后续块的哈希(和先前的哈希)。 即使你把它弄乱了,你最终也会得到一个合法的链条。
为了解决这些问题,区块链使用了一种称为“工作量证明”的技术。 您必须证明您使用大量计算资源来使用这种方法创建块。 这也被称为 采矿.
工作量证明要求块的哈希以特定数量的零开头。 但是你怎么知道你的哈希是否符合这个规则呢?
一个块的内容决定了它的哈希值。 所以我们总是获得相同的哈希,只要我们不修改内容。
每个块都应该添加一个随机值作为解决方案。 这本质上是一些我们可以更新的随机数据,直到我们的块的哈希以足够的零开始。 因为您无法更改哈希函数的输出,所以您必须测试许多不同的组合并希望获得最好的结果。
将挖矿引入区块链
让我们首先在我们的 Block 类中包含一个 nonce。 nonce 是我们块中的单个值,我们可以修改它以影响块的哈希值。
我们无法更改时间戳或数据。
接下来,让我们编写一个 mineBlock() 函数来实际挖掘一个块。 该函数将作为参数发送所需的难度,并将继续执行,直到我们的块的哈希以足够的零开始。
我刚刚做了一个基本的 while 循环,它会一直运行到我们的哈希以足够的零开始。 我们使用难度来确定需要多少个零。 在难度为 5 的情况下,我们的哈希必须以 5 个零开头。
当我们的散列不包含足够的零时,我们将随机数加一并重新计算散列。 如果我们找到与难度相对应的哈希值,我们会将其记录到控制台。
我们还需要做一件事。 我们在 calculateHash 方法中并没有真正考虑 nonce 变量,所以这里是:
区块链类
让我们在我们的区块链类中测试这种新方法,看看它是如何进行的。
首先,我将在函数 Object() 中定义我们区块链的难度。 我们在这里定义它,因为我们以后可以在某个地方使用它。
然后必须修改 addBlock 函数,以便在将块添加到我们的链中之前对其进行挖掘。
使用区块链
现在,让我们将我们的新区块链与工作量证明算法一起使用。 在这里,添加几个 console.log 语句。
当我们执行这段代码时,我们可以观察到挖矿过程不再特别快。
该算法需要一些时间来生成具有以三个零开头的散列(由难度配置)的块。
这就是我们基本的区块链设置的结束。
由于工作量证明机制,我们可以控制将新块添加到我们的区块链的速度。
这是区块链上最重要的安全功能。 现在您了解了它的工作原理,开始创建您自己的吧!
发表评论