去了解一下区块链

171 阅读4分钟

区块链由一个一个区块组成,通过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())

 

学习来源

www.bilibili.com/video/av783…

 

 

 

 

 

一起学习,一起进步 -.- ,如有错误,可以发评论