用 JavaScript 写一个区块链 - Go语言中文社区

用 JavaScript 写一个区块链


英文:Xavier Decuyper   译文:百度外卖前端/JeLewine

zhuanlan.zhihu.com/p/34522746



几乎每个人都听说过像比特币和以太币这样的加密货币,但是只有极少数人懂得隐藏在它们背后的技术。在这篇博客中,我将会用JavaScript来创建一个简单的区块链来演示它们的内部究竟是如何工作的。我将会称之为SavjeeCoin!全文分为三个部分:


  • 实现一个基本的区块链

  • 实现 POW

  • 交易与挖矿奖励


实现一个基本的区块链

区块链

区块链是由一个个任何人都可以访问的区块构成的公共数据库。这好像没什么特别的,不过它们有一个有趣的属性:它们是不可变的。


一旦一个区块被添加到区块链中,除非让剩余的其余区块失效,否则它是不会再被改变的。


这就是为什么加密货币是基于区块链的原因。你肯定不希望人们在交易完成后再变更交易!


创造一个区块

区块链是由许许多多的区块链接在一起的(这听上去好像没毛病..)。链上的区块通过某种方式允许我们检测到是否有人操纵了之前的任何区块。


那么我们如何确保数据的完整性呢?每个区块都包含一个基于其内容计算出来的 hash。同时也包含了前一个区块的 hash。


下面是一个区块类用 JavaScript 写出来大致的样子:


const SHA256 = require("crypto-js/sha256");
class Block {
 constructor
(index, timestamp, data, previousHash = '') {
   
this.index = index;
   
this.previousHash = previousHash;
   
this.timestamp = timestamp;
   
this.data = data;
   
this.hash = this.calculateHash();
 
}
 calculateHash
() {
   
return SHA256(this.index + this.previousHash + this.timestamp + JSON.stringify(this.data)).toString();
 
}
}

因为 JavaScript 中并不支持 sha256 所以我引入了 crypto-js 库。然后我定义了一个构造函数来初始化区块的属性。


每一个区块上都被赋予了 index 属性来告知我们这个区块在整个链上的位置。我们同时也生成了一个时间戳,以及需要在区块里存储的一些数据。最后是前一个区块的 hash。


创造一个链

现在我们可以在 Blockchain 类中将区块链接起来了。下面是用 JavaScript 实现的代码:


class Blockchain{
 constructor
() {
   
this.chain = [this.createGenesisBlock()];
 
}
 createGenesisBlock
() {
   
return new Block(0, "01/01/2017", "Genesis block", "0");
 
}
 getLatestBlock
() {
   
return this.chain[this.chain.length - 1];
 
}
 addBlock
(newBlock) {
   newBlock
.previousHash = this.getLatestBlock().hash;
   newBlock
.hash = newBlock.calculateHash();
   
this.chain.push(newBlock);
 
}
 isChainValid
() {
   
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;
 
}
}

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


我还添加了下面两个方法:

  • getLatestBlock() 返回我们区块链上最新的区块。

  • addBlock() 负责将新的区块添加到我们的链上。


为此,我们将前一个区块的 hash 添加到我们新的区块中。这样,我们就可以保持整个链的完整性。


版权声明:本文来源CSDN,感谢博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。
原文链接:https://blog.csdn.net/tTU1EvLDeLFq5btqiK/article/details/79907897
站方申明:本站部分内容来自社区用户分享,若涉及侵权,请联系站方删除。

  • 发表于 2020-05-07 22:02:03
  • 阅读 ( 1435 )
  • 分类:区块链

0 条评论

请先 登录 后评论

官方社群

GO教程

猜你喜欢