js 实现简单区块链

js 实现简单区块链,第1张

一步步解决问题,简单写个链,
const SHA256 = require("crypto-js/sha256");

class Block {
  constructor(index, transactions, timestamp, previousHash) {
    this.index = index;
    this.transactions = transactions;
    this.timestamp = timestamp;
    this.previousHash = previousHash;
    this.hash = this.calculateHash();
    this.nonce = 0; //工作量证明
  }
  calculateHash() {
    return SHA256(
      this.index +
        this.previousHash +
        this.timestamp +
        JSON.stringify(this.transactions) +
        this.nonce
    ).toString();
  }
  mineBlock(difficulty) {
    while (
      this.hash.substring(0, difficulty) !== Array(difficulty + 1).join("0")
    ) {
      this.nonce++;
      this.hash = this.calculateHash();
    }
  }
}

class Blockchain {
  constructor() {
    this.index = 0;
    this.difficulty = 2;
    this.pendingTransactions = [];
    this.miningReward = 200;
    this.chain = [this.createGenesisBlock()];
  }
  createGenesisBlock() {
    let firstBlock = new Block(this.index++, "创世love", new Date(), "我爱你");
    firstBlock.mineBlock(this.difficulty);
    return firstBlock;
  }
  getLatestBlock() {
    return this.chain[this.chain.length - 1];
  }
  createTransaction(transactions) {
    // 这里应该有一些校验!
    // 推入待处理交易数组
    this.pendingTransactions.push(transactions);
  }
  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;
  }
  minePendingTransactions(miningRewardAddress) {
    // 用所有待交易来创建新的区块并且开挖..
    let block = new Block(
      this.index++,
      this.pendingTransactions,
      new Date(),
      this.getLatestBlock().hash
    );
    block.mineBlock(this.difficulty);
    // 将新挖的看矿加入到链上
    this.chain.push(block);
    // 重置待处理交易列表并且发送奖励
    this.pendingTransactions = [
      new Transaction(null, miningRewardAddress, this.miningReward),
    ];
  }

  getBalanceOfAddress(address) {
    let balance = 0; // you start at zero!
    // 遍历每个区块以及每个区块内的交易
    for (const block of this.chain) {
      for (const trans of block.transactions) {
        // 如果地址是发起方 -> 减少余额
        if (trans.fromAddress === address) {
          balance -= trans.amount;
        }
        // 如果地址是接收方 -> 增加余额
        if (trans.toAddress === address) {
          balance += trans.amount;
        }
      }
    }
    return balance;
  }
}

// 交易信息
class Transaction {
  constructor(fromAddress, toAddress, amount) {
    this.fromAddress = fromAddress;
    this.toAddress = toAddress;
    this.amount = amount;
  }
}

let chain1 = new Blockchain();

chain1.createTransaction(new Transaction("anni", "zhanguo", 50));
chain1.createTransaction(new Transaction("anni", "zhanguo", 60));
chain1.createTransaction(new Transaction("anni", "zhanguo", 100));

chain1.minePendingTransactions("anni");

chain1.createTransaction(new Transaction("anni", "zhanguo", 50));
chain1.createTransaction(new Transaction("anni", "zhanguo", 60));
chain1.createTransaction(new Transaction("anni", "zhanguo", 100));

chain1.minePendingTransactions("anni");

chain1.minePendingTransactions("anni");

console.log(
  chain1.chain,
  chain1.getBalanceOfAddress("anni"),
  chain1.getBalanceOfAddress("zhanguo")
);

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/1498490.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-25
下一篇 2022-06-25

发表评论

登录后才能评论

评论列表(0条)

保存