Blockchain Slip No 10 solution

const crypto = require('crypto');

class Transaction

{

  constructor(fromAddress, toAddress, amount)

{

    this.fromAddress = fromAddress;

    this.toAddress = toAddress;

    this.amount = amount;

    this.timestamp = Date.now();

  }

        calculateHash()

{

                return crypto .createHash('sha256').update(

                this.fromAddress +

                this.toAddress +

        this.amount +

        this.timestamp

      ).digest('hex');

}

}

 

class Block

{

  constructor(timestamp, transactions, previousHash = '') 

{

                this.timestamp = timestamp;

 this.transactions = transactions;

 this.previousHash = previousHash;

 this.hash = this.calculateHash();

 this.nonce = 0;

}

        calculateHash()

{

    return crypto.createHash('sha256').update(

        this.previousHash +

        this.timestamp +

        JSON.stringify(this.transactions) +

         this.nonce).digest('hex');

}

 

  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);

  }

}

 class Blockchain

{

  constructor()

{

    this.chain = [this.createGenesisBlock()];

    this.difficulty = 2;

    this.pendingTransactions = [];

    this.miningReward = 100;

}

        createGenesisBlock()

 {

    return new Block('01/01/2023', 'Genesis Block', '0');

        }

 

  getLatestBlock()

{

    return this.chain[this.chain.length - 1];

}

 createTransaction(transaction)

{

    this.pendingTransactions.push(transaction);

}

 

  minePendingTransactions(miningRewardAddress) {

    const rewardTransaction = new Transaction('Blockchain',miningRewardAddress,this.miningReward);

    this.pendingTransactions.push(rewardTransaction);

 

    const newBlock = new Block(

      Date.now(),

      this.pendingTransactions,

      this.getLatestBlock().hash

    );

    newBlock.mineBlock(this.difficulty);

 

    console.log('Block successfully mined!');

    this.chain.push(newBlock);

    this.pendingTransactions = [];

  }

 

  getBalanceOfAddress(address) {

    let balance = 0;

    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;

  }

 

  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;

  }

}

 

// Usage example:

const myBlockchain = new Blockchain();

 

myBlockchain.createTransaction(new Transaction('ABC', 'MNO', 50));

myBlockchain.createTransaction(new Transaction('MNO', 'XYZ', 30));

 

console.log('\nMining...');

myBlockchain.minePendingTransactions('Miner-Address');

 

console.log('\nBalance of ABC:', myBlockchain.getBalanceOfAddress('ABC'));

console.log('Balance of MNO:', myBlockchain.getBalanceOfAddress('MNO'));

console.log('Balance of Miner:', myBlockchain.getBalanceOfAddress('Miner-Address'));

 console.log('\nIs blockchain valid?', myBlockchain.isChainValid());

 

 Output:

Mining...

Block mined: 00e5b94ae9453ecacee44c14d3b986ff0b8c9ce039c81b5fedfbacb46c6de41b

Block successfully mined!


Balance of ABC: -50

Balance of MNO: 20

Balance of Miner: 100


Is blockchain valid? true


No comments:

Post a Comment