//区块链 block chain //data 之前区块的哈希值 当前区块的哈希值:是由存储在区块里的信息算出来的(data + 之前区块的哈希值) const sha256 = require('./crypto-js/sha256') //区块 class Block{ constructor(data){ this.data = data this.previousHash = '' this.nonce = 1 this.hash = this.computeHash() } computeHash(){ return sha256(this.data + this.previousHash + this.nonce).toString() } // 计算符合区块链难度的hash值 mine(difficulty){ while(true){ this.hash = this.computeHash() if(this.hash.substring(0, difficulty) !== this.getAnswer(difficulty)){ this.nonce++ }else{ break } } } getAnswer(difficulty){ // 开头前n位为0的hash let answer = '' while(difficulty-- !== 0){ answer += '0' } return answer } } //区块 的 链 //生成祖先区块 class Chain{ constructor(){ this.chain = [this.bigBang()] this.difficulty = 4 } bigBang(){ const genesisBlock = new Block('祖先区块') return genesisBlock } //获取最新一个区块 getLatestBlock(){ return this.chain[this.chain.length-1] } //添加新区块 addBlockToChain(newBlock){ // 1、data 2、previousHash newBlock.previousHash = this.getLatestBlock().hash newBlock.hash = newBlock.computeHash() // 进行挖矿 newBlock.mine(this.difficulty) 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 } // 验证其他区块 for(let i = 1, len = this.chain.length-1; i <= len; i++){ const blockToValidate = this.chain[i] // 验证数据是否被篡改 if(blockToValidate.hash !== blockToValidate.computeHash()){ console.log("数据被篡改!") return false } // 验证hash值 if(blockToValidate.previousHash !== this.chain[i-1].hash){ console.log("前后区块断裂!") return false } } return true } } const zzBlock = new Block('转账1000') const zzBlock2 = new Block('转账3210') const zzBlock3 = new Block('转账210') const blockChain = new Chain() blockChain.addBlockToChain(zzBlock) blockChain.addBlockToChain(zzBlock2) blockChain.addBlockToChain(zzBlock3) console.log(blockChain.chain.length) //尝试篡改数据 blockChain.chain[1].data = '转账10W' blockChain.chain[1].mine(4) console.log(blockChain) console.log(blockChain.validateChain())