我仅用50 行 JavaScript 代码从头构建区块链,向你介绍区块链的工作原理

前端Q

共 3909字,需浏览 8分钟

 · 2021-12-11

点击上方 前端Q,关注公众号

回复加群,加入前端Q技术交流群


英文 | https://medium.com/geekculture/blockchain-explained-in-50-lines-of-code-1dbf4eda0201

翻译 | 杨小爱


区块链,区块链,区块链!在过去的十年里,我们一次又一次地听到这个技术流行语。它被认为是 21 世纪最重要的发明之一。
如果您听说过区块链但不完全了解它,那没关系!今天的文章中,我将通过仅使用 50 行 JavaScript 代码从头构建区块链,向您展示区块链的工作原理。
在我们开始之前,我想指出,如果您了解一些基本的编程知识,这篇文章会更容易理解。但是如果你没有编程知识,你也不要担心,因为我会尽力详细解释每一段代码。
现在,让我们开始吧!
首先,我们需要了解区块链是如何创建的。
区块链,顾名思义,是由多个区块链连接在一起形成的。

每个块通常包含以下信息:
  • 数据:这可以是交易数据之类的任何东西。

  • 哈希值:这基本上是块的 ID。

  • 前一个哈希值:这会跟踪前一个块 ID。现在,你只需要知道我们使用这个值在当前块和前一个块之间形成一个链。我将在本文后面解释为什么这个值很重要。

  • 时间戳:这告诉我们区块何时被创建。

  • 工作量证明:这是一个数字,显示了找到当前块的哈希值的努力。如果你听说过挖矿,这个值代表机器计算哈希值需要多长时间(以数字的形式)。

在现实世界中,块比这更复杂,但我想尽量保持简单:)
让我们进入有趣的部分,编码!
1、创建块类
让我们在一个空的 index.js 文件中创建一个名为“Block”的类。

此类的构造函数接受 2 个参数。第一个是前一个区块的哈希值,第二个是当前区块的数据。
在构造函数内部,我们使用构造函数参数初始化块数据。我们将 timeStamp 设置为当前时间,将 proofOfWork 设置为 0。
还记得我说过我们需要计算哈希值吗?是的,哈希值不仅仅是一个随机字符串,为了安全起见,我们需要根据当前数据和之前的哈希值来找到当前的哈希值。
如果黑客更改了一个区块的数据,他们还必须重新计算前面所有区块的哈希值以使链有效(如果他们和我使用同一台计算机,这可能需要数千年)
对于那些不了解哈希的人,它基本上是我们如何将数据转换为一堆随机字符。例如,单词“hello”可以散列成“e2d48e7bc...”。因为散列只在一个方向上起作用,所以很容易找到给定输入的散列输出,但很难从散列输出中预测输入。
我们来看一下calculateHash函数。

该函数基本上根据之前的哈希值、当前数据、当前时间戳和工作量证明的组合生成一个哈希值。
我们使用来自 crypto-js npm 包的哈希函数。这个包基本上允许我们使用几种散列方法。我们在本教程中使用安全哈希算法 256 (SHA 256)。如您所见,我们在文件顶部导入哈希。
我们来看看 Block 类的最终功能。mine功能。
这个mine函数不断增加,直到proofOfWork帮我们找到一个以我们想要的数字,如0开头的哈希值(我们称之为难度)。难度越高,创建哈希所需的时间就越长。这是因为从哈希输出中找到输入的唯一方法就是,不断尝试不同的输入。
有趣的事实:比特币区块的哈希值需要 18 个零,其区块链网络中的所有计算机大约需要 10 分钟才能创建。
如果您听说过人们谈论挖掘加密货币,这就是它的工作原理。他们投资超级机器来计算新区块的哈希值,并获得一些加密货币作为奖励。
你可能想知道为什么它必须那么复杂?
想象一下,如果创建哈希既简单又快速,那么存储在区块链中的数据将很容易被更改。因此,哈希值是以如此复杂的方式创建的,因此即使一个块被黑客入侵,也需要永远更新以下所有块。这就是区块链如此安全的原因。
如果你读到这里,请随意拍拍自己的后背,因为我们已经成功地在区块链中创建了一个区块。
下一部分是创建区块链来存储所有块。
2、创建区块链类
让我们创建Blockchain

我们的区块链存储 1 个名为 chain 的数组。我们还将向链中添加一个 genesisBlock。genesis block 它基本上是链中的第一个块。因此,我们可以传递“0”作为前一个哈希值,因为没有前一个块。
接下来,我们将实现 addBlock 函数,该函数将一个新块添加到链中。
该函数接受新数据作为参数,并根据该数据和前一个区块的哈希值创建一个新区块。

请记住,当我们创建一个新块时,我们必须使用 mine 函数计算其哈希值。为了使它更快,我只将 diffifulty 设置为 2,因此,新的哈希值必须以 2 个零开头。
找到哈希值后,我们只需要将新块添加到链中。
最后,我们需要 isValid 函数来验证当前链是否有效。
这个函数基本上遍历每个块(except the genesis one)并检查哈希值是否存在任何违规。如果没有违规,则返回 true。
恭喜!您已成功构建区块链。
让我们在下面的示例部分看看它是如何工作的。
3、使用示例
让我们尝试将包含转换信息的 2 个新块添加到我们的区块链。

添加这两个值后,我们的区块链将如下所示。

如果您注意到,每个块的 previousHash 与它之前的块的哈希完全相同。
你想象一下,作为第一笔交易的接收方的大卫,他想要更多的钱,并像这样修改区块的数据。

区块链将无效,因为第一个区块的新哈希值与其先前计算的哈希值不同。

很好的尝试,大卫!金额可能会改变,但对整个区块链是无效的。大卫必须重新计算每个块的哈希值,并以使其都有效。这在现实生活中是不可能实现的!
总结
以上就是我所要分享的文章内容。我希望对您想更多地了解区块链会有所帮助。如果您觉得今天内容对您有所帮助,也请您分享给您的朋友,也许也可以帮助到他。
如果您有任何问题,请在留言区给我留言,我知道的,一定都与您分享。
感谢您的阅读。
另外,一些是这本中的完整代码:
const hash = require("crypto-js/sha256");class Block {  constructor(previousHash, data) {    this.data = data;    this.hash = this.calculateHash();    this.previousHash = previousHash;    this.timeStamp = new Date();    this.proofOfWork = 0;  }
calculateHash() { return hash( this.previousHash + JSON.stringify(this.data) + this.timeStamp + this.proofOfWork ).toString(); }
mine(difficulty) { while (!this.hash.startsWith("0".repeat(difficulty))) { this.proofOfWork++; this.hash = this.calculateHash(); } }}
class Blockchain { constructor() { let genesisBlock = new Block("0", { isGenesis: true }); this.chain = [genesisBlock]; }
addBlock(data) { let lastBlock = this.chain[this.chain.length - 1]; let newBlock = new Block(lastBlock.hash, data); newBlock.mine(2); // find a hash for new block this.chain.push(newBlock); }
isValid() { for (let i = 1; i < this.chain.length; i++) { const currentBlock = this.chain[i]; const previousBlock = this.chain[i - 1]; if (currentBlock.hash != currentBlock.calculateHash()) return false; if (currentBlock.previousHash != previousBlock.hash) return false; } return true; }}

看,没有点击诱饵!它正好有 50 行😊

喜欢的话,请记得关注我,点赞我,非常感谢。


往期推荐


大厂面试过程复盘(微信/阿里/头条,附答案篇)
面试题:说说事件循环机制(满分答案来了)
专心工作只想搞钱的前端女程序员的2020



最后


  • 欢迎加我微信,拉你进技术群,长期交流学习...

  • 欢迎关注「前端Q」,认真学前端,做个专业的技术人...

点个在看支持我吧
浏览 26
点赞
评论
收藏
分享

手机扫一扫分享

举报
评论
图片
表情
推荐
点赞
评论
收藏
分享

手机扫一扫分享

举报