3.2.JS手写一个迷你区块链实战(2)

197 阅读2分钟

挖矿原理实现

这个小节我们要来实现挖矿功能,先整理需求,分析思路

1.我们使用工作量证明这种共识机制,那就需要不断的算题

2.算题就是生成哈希值后,拿这个哈希去验证是否合法

3.合法的标准,我们这里这样规定: 如果你算出来的哈希值,前面有n个"0"就符合标准,这里具体n是多
少,由难度值决定,举个例子:难度值为4,那么意味着算出来的哈希值前面需要有4"0"才符合标准

基于上面的分析,编写代码

index.js 文件里面的代码

const crypto = require('crypto')

class BlockChain {
  constructor() {
    // 定义一个创世区块,即第一个区块的数据结构
    this.firstBlock = {
      index: 0,
      data: 'hello world',
      prevHash: '0',
      timestamp: 1679234322447,
      hash: 'f0c40a6c9ea4b9ae794c89744b45a2aa10af6d6d561046d039db981f94a5073b'
    }
    // 区块链数组
    this.blockchain = [this.firstBlock]
    // 难度值
    this.difficulty = 4
  }
  // 生成区块的hash值
  createHash({ index, prevHash, timestamp, data, nonce }) {
    return crypto
      .createHash('sha256')
      .update(index + prevHash + timestap + data + nonce)
      .digest('hex')
  }
  // 挖矿
  mine() {
    // 记录挖矿次数
    let nonce = 0
    // 记录当前是第几个区块
    let index = this.blockchain.length
    // 交易数据
    let data = 'A -> B: 100'
    // 最后一个区块的hash就是新区块的上一个hash
    let prevHash = this.blockchain[this.blockchain.length - 1].hash
    let timestamp = new Date().getTime()
    let hash = this.createHash({ index, prevHash, timestamp, data, nonce })
    while (hash.slice(0, this.difficulty) !== '0'.repeat(this.difficulty)) {
      nonce++
      hash = this.createHash({ index, prevHash, timestamp, data, nonce })
    }
    console.log('Nonce: ' + nonce, 'Hash: ' + hash)
  }
  // 获取到最后一个区块
  getLastBlock() {
    return this.blockchain[this.blockchain.length - 1]
  }
}

测试一下效果

let b = new BlockChain()
b.mine()

输出结果

Nonce: 45697 Hash: 000024e29bcdb21e417102385720a05f1372ae0c06e28458e9d2ff3adfd8a3b7

上面结果表示挖矿计算了 45697 次挖矿成功