写点什么

去了解一下区块链

用户头像
空城机
关注
发布于: 2021 年 03 月 22 日
去了解一下区块链

区块链由一个一个区块组成,通过 chain 来将一个个 block 区块链接起来

人们可以把区块链看成人人都可以信任的分布式账簿 




区块 block

一个区块大体上面可以被分为三个部分:

  • 数据

  • 哈希值   ---  区块的哈希(hash)相当于人类的指纹

  • 前区块哈希值 --- 除了自己区块的哈希值,还会存储之前区块的哈希值

一旦数据被更改,那么哈希值就会发生变化,这样人们就能通过哈希值来发现数据的更改。



区块链的第一个区块没有前哈希值,可以被叫做祖先区块(Genesis Block)。

是的,区块链这样说就和链表很像了


区块链为了放置区块被篡改,引入了一个 Proof of Work(POW)工作量证明机制

区块链还引入了 Peer to Peer(P2P)的网络,形成了分布式存储

一旦有一个区块需要被加入,需要 P2P 网络中所有人达成共识,这个区块才能被加入。



区块链防篡改并不是让数据不能被篡改,而是让做这件事(窜改数据)的成本变的极高。


哈希(散列)函数 Hash Function

F(x) = y (y 为定长)

  • 已知 x,求 y  ==》 容易

  • 已知 y,求 x  ==》 困难

例如:x^18 + x^5 + x^0.5 + x - 5 = y

我们可以尝试猜数字
猜 = 穷举/试值 = WORK
穷举的越快(算力越高),理论上就能越快得到结果的
复制代码


crypto-js

crypto 模块的目的是为了提供通用的加密和哈希算法。用纯 JavaScript 代码实现这些功能不是不可能,但速度会非常慢。Nodejs 用 C/C++实现这些算法后,通过 cypto 这个模块暴露为 JavaScript 接口,这样用起来方便,运行速度也快。

crypto-js 的安装下载和使用





  • 测试哈希值代码: 

const sha256 = require("crypto-js/sha256");
console.log(sha256('hello').toString());console.log(sha256('world').toString());
复制代码


测试结果: 对于不同的输入,哪怕只是一个很微小的改动,输出都是不一样的

得到的结果就是哈希值

对于同一个输入,输出结果是一样的。



  • 例子:我现在需要得到 一个 开头值为 0 的哈希值。请告诉我 X 是多少

function proofOfWork() {    let data = "hello world";    let x = 1;    while (true) {      if(sha256(data + x).toString()[0]!== "0") {        x = x + 1;      } else {        console.log(sha256(data + x).toString());        console.log(x);        break;      }    }  }proofOfWork();
复制代码


结果:




  • 例子:现在需要得到 一个 开头值前 4 位全为 0 的哈希值。请告诉我 X 是多少

function proofOfWork() {    let data = "hello world";    let x = 1;    while (true) {      if (        sha256(data + x).toString()          // 可以通过调整字符串长度来控制难度,自己可以试一下。          // 也可以用自己喜欢的语言,来实现这个函数。          // 这个函数真的不复杂。          .substring(0, 4) !== "0000"      ) {        x = x + 1;      } else {        console.log(sha256(data + x).toString());        console.log(x);        break;      }    }  }  proofOfWork();
复制代码


结果:



创建一个区块的类

 const sha256 = require("crypto-js/sha256");
/**区块 * data * 之前区块的哈希值 * 自己的哈希值——由存储在区块里的信息算出来的(data + 之前区块的哈希值) *///写一个区块的类 class Block{ constructor(data, previousHash) { this.data = data; this.previousHash = previousHash; this.hash = this.computeHash() }
computeHash(){ return sha256(this.data + this.previousHash).toString() } }
const block = new Block("转账10元","KLOP"); console.log(block)
复制代码


运行之后:



编写一个链的类

class Block{  constructor(data, previousHash) {    this.data = data;    this.previousHash = previousHash;    this.hash = this.computeHash()  }
computeHash(){ return sha256(this.data + this.previousHash).toString() } }
// const block = new Block("转账10元","KLOP");// console.log(block)class Chain { constructor(){ this.chain = [this.bigBang()]; }
bigBang(){ //定义一个祖先区块 const genesisBlock = new Block("我是祖先区块",""); return genesisBlock; }}
const chain = new Chain();console.log(chain);
复制代码


输出的一个具有祖先区块的链



添加一个区块到区块链上

class Chain {  constructor(){    this.chain = [this.bigBang()];  }
bigBang(){ //定义一个祖先区块 const genesisBlock = new Block("我是祖先区块",""); return genesisBlock; } //找到最近一个block的hash getLatestBlock(){ return this.chain[this.chain.length - 1]; } //添加区块到区块链上 addBlocktoChain(newBlock){ //找到最近一个block的hash //这个hash就是新区块的previousHash newBlock.previousHash = this.getLatestBlock().hash; newBlock.hash = newBlock.computeHash(); this.chain.push(newBlock); }}
const chain = new Chain();const block1 = new Block("转账10元","");
chain.addBlocktoChain(block1);console.log(chain);
复制代码


效果:



验证区块链中数据是否被篡改

class Chain {  constructor(){    this.chain = [this.bigBang()];  }
bigBang(){ //定义一个祖先区块 const genesisBlock = new Block("我是祖先区块",""); return genesisBlock; } //找到最近一个block的hash getLatestBlock(){ return this.chain[this.chain.length - 1]; } //添加区块到区块链上 addBlocktoChain(newBlock){ //找到最近一个block的hash //这个hash就是新区块的previousHash newBlock.previousHash = this.getLatestBlock().hash; newBlock.hash = newBlock.computeHash(); this.chain.push(newBlock); }
//验证这个当前的区块链是否合法 //当前的数据有没有被篡改 //我们要验证区块的previousHash是否等于previous区块的hash validateChain() { if (this.chain.length === 1) { if (this.chain[0].hash !== this.chain[0].computeHash()) { return false; } return true; } // this.chain[1] 是第二个区块 // 我们从第二个区块开始 验证 // 验证到最后一个区块 this.chain.length -1 for (let i = 1; i <= this.chain.length - 1; i++) { const blockToValidate = this.chain[i]; //当前的数据有没有被篡改 if (blockToValidate.hash !== blockToValidate.computeHash()) { console.log("数据篡改"); return false; } //我们要验证区块的previousHash是否等于previous区块的hash const previousBlock = this.chain[i - 1]; if (blockToValidate.previousHash !== previousBlock.hash) { console.log("前后区块链接断裂"); return false; } } return true; }}
const chain = new Chain();
const block1 = new Block("转账10元","");const block2 = new Block("转账20元","");const block3 = new Block("转账30元","");const block4 = new Block("转账40元","");
chain.addBlocktoChain(block1);chain.addBlocktoChain(block2);chain.addBlocktoChain(block3);chain.addBlocktoChain(block4);
//尝试篡改这个区块链chain.chain[1].data = "转账一百个十元";console.log(chain);console.log(chain.validateChain())
复制代码


效果:


学习来源

https://www.bilibili.com/video/av78391502


发布于: 2021 年 03 月 22 日阅读数: 10
用户头像

空城机

关注

曾经沧海难为水,只是当时已惘然 2021.03.22 加入

业余作者,在线水文

评论

发布
暂无评论
去了解一下区块链