// 导入 SHA256 算法的实现
const SHA256 = require('crypto-js/sha256');
// 区块链类
class BlockChain {
// 构造函数,初始化区块链
constructor() {
// 初始只有一个 Genesis 区块
this.chain = [this.createGenesisBlock()];
this.difficulty = 2;
}
// 创建 Genesis 区块
createGenesisBlock() {
return new Block(0, "03/10/2023", "Genesis block", "0");
}
// 获取最新的区块
getLatestBlock() {
return this.chain[this.chain.length - 1];
}
// 添加新的区块
addBlock(newBlock) {
// 新的区块的前一个哈希是当前链的最后一个区块的哈希值
newBlock.previousHash = this.getLatestBlock().hash;
// 计算新的区块的哈希值
//newBlock.hash = newBlock.calculateHash();
// 将新的区块添加到链中
newBlock.mineBlock(this.difficulty);
this.chain.push(newBlock);
}
// 判断区块链是否有效
isChainValid() {
for (let i = 1; i < this.chain.length; i++) {
const currentBlock = this.chain[i];
const previousBlock = this.chain[i - 1];
// 判断当前区块的哈希值是否合法
if (currentBlock.hash !== currentBlock.calculateHash()) {
return false;
}
// 判断当前区块的前一个哈希是否等于上一个区块的哈希
if (currentBlock.previousHash !== previousBlock.hash) {
return false;
}
}
return true;
}
}
// 区块类
class Block {
// 构造函数,初始化区块
constructor(index, timestamp, data, previousHash = "") {
this.index = index;
this.timestamp = timestamp;
this.data = data;
this.previousHash = previousHash;
// 计算当前区块的哈希值
this.hash = this.calculateHash();
this.nonce = 0;
}
mineBlock(difficulty) {
while (
this.hash.substring(0, difficulty) !== Array(difficulty + 1).join('0')
) {
this.nonce++;
this.hash = this.calculateHash();
}
console.log("BLOCK MINED: " + this.hash);
}
// 计算区块的哈希值
calculateHash() {
return SHA256(this.index + this.previousHash + this.timestamp + JSON.stringify(this.data)+this.nonce).toString();
}
}
// 创建一个新的区块链
let myBlockChain = new BlockChain();
// 添加3个新的区块
myBlockChain.addBlock(new Block(1, "04/10/2023", { amount: 4 }));
myBlockChain.addBlock(new Block(2, "05/10/2023", { amount: 8 }));
myBlockChain.addBlock(new Block(3, "04/10/2023", { amount: 16 }));
//变更第2个块的数据,去掉前面的'//'
//myBlockChain.chain[1].data = { amount: 100 };
// 打印出当前的区块链
console.log(JSON.stringify(myBlockChain, null, 8));
// 判断区块链是否有效,并打印结果
console.log("Is my blockchain valid? " + myBlockChain.isChainValid());