JavaScript实现区块链(2)

在构造函数里,我通过创建一个包含创世块的数组来初始化整个链。第一个区块是特殊的,因为它不能指向前一个区块。我还添加了下面两个方法:

  • getLatestBlock() 返回我们区块链上最新的区块。
  • addBlock() 负责将新的区块添加到我们的链上。为此,我们将前一个区块的hash添加到我们新的区块中。这样我们就可以保持整个链的完整性。因为只要我们变更了最新区块的内容,我们就需要重新计算它的hash。当计算完成后,我将把这个区块推进链里(一个数组)。

最后,我创建一个 isChainValid() 来确保没有人篡改过区块链。它会遍历所有的区块来检查每个区块的hash是否正确。它会通过比较 previousHash 来检查每个区块是否指向正确的上一个区块。如果一切都没有问题它会返回 true 否则会返回 false 。

使用区块链

我们的区块链类已经写完啦,可以真正的开始使用它了!

let savjeeCoin = new Blockchain();
savjeeCoin.addBlock(new Block(1, "20/07/2017", { amount: 4 }));
savjeeCoin.addBlock(new Block(2, "20/07/2017", { amount: 8 }));

在这里我仅仅是创建了一个区块链的实例,并且命名它为SavjeeCoin!之后我在链上添加了一些区块。区块里可以包含任何你想要放的数据,不过在上面的代码里,我选择添加了一个带有 amount 属性的对象。

试着操作吧!

在介绍里我曾说过区块链是不可变的。一旦添加,区块就不可能再变更了。让我们试一下!

// 检查是否有效(将会返回true)
console.log('Blockchain valid? ' + savjeeCoin.isChainValid());
// 现在尝试操作变更数据
savjeeCoin.chain[1].data = { amount: 100 };
// 再次检查是否有效 (将会返回false)
console.log("Blockchain valid? " + savjeeCoin.isChainValid());

我会在一开始通过运行 isChainValid() 来验证整个链的完整性。我们操作过任何区块,所以它会返回true。

之后我将链上的第一个(索引为1)区块的数据进行了变更。之后我再次检查整个链的完整性,发现它返回了false。我们的整个链不再有效了。

结论

这个小栗子还远未达到完成的程度。它还没有实现POW(工作量证明机制)或P2P网络来与其它矿工来进行交流。

但他确实证明了区块链的工作原理。许多人认为原理会非常复杂,但这篇文章证明了区块链的基本概念是非常容易理解和实现的。

Part2:实现POW(proof-of-work:工作量证明)

在part1中我们用JavaScript创建了一个简单的区块链来演示区块链的工作原理。不过这个实现并不完整,很多人发现依旧可以篡改该系统。没错!我们的区块链需要另一种机制来抵御攻击。那么让我们来看看我们该如何做到这一点!