最简区块链Demo | 基于NodeJS实现移动端区块链公有链

[复制链接]
查看402 | 回复1 | 2022-6-25 03:09:36 | 显示全部楼层 |阅读模式
配景


对于年夜 多半 开发者,区块链行业不容易在第一时间形成初步的思维印象。本文旨在在最短时间内,授与 刚入门的开发者一个最简的区块链Demo。
最终效果


最终效果:每隔1s模拟一个区块的产生  


正文

    结构 一个模拟 区块 的类

1. 每个区块拥有区块头和区块体两部分  ;

2. 区块头有如下几个症结 字段:height - 高度,previousHash - 上一个区块的哈希值,timestamp - 当前时间戳, Nonce - 一个随机数,MerkelRoot - 梅克尔树根的哈希值,hash - 当前区块的哈希;

3. 区块体data中包含 了:在当前这一段时间内产生 的,并且  被加入到该区块的交易;
class Block {  /**   * 结构 函数   * @param {Number} height    * @param {String} previousHash    * @param {Number} timestamp    * @param {*} data    * @param {String} hash    */  constructor(height, previousHash, timestamp, data, hash) {    this.height = height    this.previousHash = previousHash + ''    this.timestamp = timestamp    this.data = data    this.hash = hash + ''  }  static generateBlock(blockData, previousBlock) {    const nextHeight = previousBlock.height + 1;    const nextTimeStamp = new Date().getTime();    //暂时忽略MerkelRoot和Nonce    const nextHash = CryptoJS.SHA256(nextHeight + previousBlock.hash + nextTimeStamp + blockData) + '';     return new Block(nextHeight, previousBlock.hash, nextTimeStamp, blockData, nextHash);      }}
    结构 一个模拟 区块链 的类

区块链类拥有的功能  :

1. 创建   “创世区块”;

2. 依据 当前区块的各个字段和区块体的交易数据,计算对应的哈希值;

3. 获得 区块链中最后一个块节点;

4. 计算当前链表的下一个区块;

5. 判断新加入的块是否正当 ;

6. 判断height是否连续且自增;

7. 判断前后区块的哈希是否相连;

8. 向区块链新增节点;

9. 插入新的短链表时判断是否正当 ,如何插入;

10. 附加功能  :保存  /展示区块链的数据;
class BlockChain {  /**   * 如果指定在历史BlockChain上继续增加区块,则从本地  存储中取出;不然 默认创建  新的区块链   * @param { string } historyChain   */  constructor(historyChain) {    this.blocks = [this.getGenesisBlock()]  }  // constructor(historyChain) {  //   if( historyChain) {  //     let blocks = this.getHistoryChain(historyChain);  //     this.blocks = blocks ? [blocks] : [this.getGenesisBlock()];  //   } else {  //     this.blocks = [this.getGenesisBlock()]  //   }  // }  /**   * 将区块链异步保存  到文件中   */  async saveHistoryChain(file, block) {    await fs.appendFile(file, JSON.stringify(block), err => {      if (err) throw err;      console.log(`Height: ${block.height} is saved.`);    });      }  /**   * 从文件中同步读出历史区块数据   */  // getHistoryChain() {  //   return fs.readFileSync('historyChain.txt', 'utf-8');  // }    /**   * 创建  区块链起源块, 此块是硬编码(取比特币高度:642022, 对应的时间是2020-08-03 17:00)   */  getGenesisBlock() {    return new Block(0, '0', 1595490064640, 'GenesisBlock', '0000000000000000000d87bedef9550a014af9a3af74b791d84d049cc3ca85f4')  }  /**   * 依据 信息计算hash值   */  calcuteHash(height, previousHash, timestamp, data) {    return CryptoJS.SHA256(height + previousHash + timestamp + data) + ''  }  /**   * 获得 区块链中最后一个块节点   */  getLatestBlock() {    return this.blocks[this.blocks.length - 1]  }  /**   * 计算当前链表的下一个区块   * @param {*} blockData    */  generateNextBlock(blockData) {    const previousBlock = this.getLatestBlock()    const nextIndex = previousBlock.height + 1    const nextTimeStamp = new Date().getTime()    const nextHash = this.calcuteHash(nextIndex, previousBlock.hash, nextTimeStamp, blockData)    return new Block(nextIndex, previousBlock.hash, nextTimeStamp, blockData, nextHash)  }  /**   * 判断新加入的块是否正当    * @param {Block} newBlock    * @param {Block} previousBlock    */  isValidNewBlock(newBlock, previousBlock) {    if(      !(newBlock instanceof Block) ||      !(previousBlock instanceof Block)    ) {      return false    }    // 判断height    if(newBlock.height !== previousBlock.height + 1) {       return false    }    // 判断hash值    if(newBlock.previousHash !== previousBlock.hash) {       return false    }    // 计算新块的hash值是否相符 规矩     if(this.calcuteHash(newBlock.height, newBlock.previousHash, newBlock.timestamp, newBlock.data) !== newBlock.hash) {       return false    }    return true  }    /**   * 向区块链添加新节点   * @param {Block} newBlock    */  addBlock(newBlock) {    if(this.isValidNewBlock(newBlock, this.getLatestBlock())) {      this.blocks.push(newBlock)      return true      }    return false  }  /**   * 判断新插入的区块链是否正当 并且 可以笼罩 原来的节点   * @param {Array} newChain    */  isValidNewChain(newChain) {    if(Array.isArray(newChain) === false || newChain.length === 0) {      return false    }    let newChainLength = newChain.length,      firstBlock = newChain[0]    // 硬编码的起源块不克不及 转变     if(firstBlock.height === 0) {      return false    }    // 移植新的链的长度 <= 现有链的长度    // 新的链弗成 信    if(newChainLength + firstBlock.height <= this.blocks.length) {      return false    }    // 下面检查新的链能否移植    // 以及新的链的每个节点是否相符 规矩     if(!this.isValidNewBlock(firstBlock, this.blocks[firstBlock.height - 1])) {      return false    }    for(let i = 1; i < newChainLength; ++i) {      if(!this.isValidNewBlock(newChain, newChain[i - 1])) {        return false      }    }    return true  }  /**   * 插入新链表   * @param {Array} newChain    */  addChain(newChain) {    if(this.isValidNewChain(newChain)) {      const height = newChain[0].height      this.blocks.splice(height)      this.blocks = this.blocks.concat(newChain)      return true    }    return false  }  //打印该区块链的所有区块  printBlockChain() {    console.table(this.blocks);  }  //打印该区块链的最新区块  printLastBlock() {    console.table(this.blocks[this.blocks.length - 1]);  }  }
    测试上述代码

代码功能  有:

1. 模拟生成区块体中的交易数据;

2. 新建一个区块链条;

3. 准时 (每隔2秒)模拟生成一个区块,并添加到区块链中;

4. 同时打印该区块链
//生成模拟的区块体交易数据function generateBlockData() {  const dataList = ['Zhangjie is cool', 'Pengxiaohua is cool', 'ChenZiqiang is cool', 'Fangguojun is cool', 'Lulina is beautiful', 'Maqicheng is cool', 'Wangchuanshuo is cool', 'Linshaoyuan is beautiful', 'Lulina is beautiful'];  return dataList[Math.random() * dataList.length >> 0];}function mockBlocks() {  //实例化一个区块链  const blockChain = new BlockChain('testNet');  blockChain.printLastBlock();  let newBlock;  setInterval(() => {    newBlock = Block.generateBlock(generateBlockData(), blockChain.getLatestBlock());    blockChain.addBlock(newBlock);    blockChain.printBlockChain();  }, 2000);}//开启模拟区块mockBlocks();完整源码


基于NodeJS的完整可运行的最简区块链Demo

运行方法

    下载源码:
git clone https://github.com/stevekeol/YunDang-Chain
    切换至对应目录,并安装依赖项
cd yundang-chain/demo && npm install
    运行
npm start作者简介

【stevekeol】卒业 于三墩职业技术学院的一名loser。求索于区块链行业四五载,拥有近乎信仰级其余 热爱。近期已提上日程的计划是打造一款 基于NodeJS的移动端全节点公有链: YunDang-Chain。如需交流,参考 https://github.com/stevekeol/YunDang-Chain

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

CK3VK_Gom | 2022-6-25 03:10:32 | 显示全部楼层
怎么玩
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

15

主题

45

回帖

145

积分

注册会员

Rank: 2

积分
145