/ block.js
block.js
 1  const { GENESIS_DATA, MINE_RATE } = require("./config");
 2  const cryptoHash = require("./crypto-hash.js");
 3  const hextToBinary = require("hex-to-binary");
 4  
 5  class Block {
 6    constructor({ timestamp, lastHash, hash, data, nonce, difficulty }) {
 7      this.timestamp = timestamp;
 8      this.lastHash = lastHash;
 9      this.hash = hash;
10      this.data = data;
11      this.nonce = nonce;
12      this.difficulty = difficulty;
13    }
14  
15    static genesis() {
16      return new this(GENESIS_DATA);
17    }
18  
19    static mineBlock({ lastBlock, data }) {
20      const lastHash = lastBlock.hash;
21      let hash, timestamp;
22      let { difficulty } = lastBlock;
23      let nonce = 0;
24  
25      do {
26        nonce++;
27        timestamp = Date.now();
28        difficulty = Block.adjustDifficulty({
29          originalBlock: lastBlock,
30          timestamp,
31        });
32        hash = cryptoHash(timestamp, lastHash, data, nonce, difficulty);
33      } while (hextToBinary(hash).substring(0, difficulty) !== "0".repeat(difficulty));
34  
35      return new this({
36        timestamp,
37        lastHash,
38        data,
39        difficulty,
40        nonce,
41        hash,
42      });
43    }
44  
45    static adjustDifficulty({ originalBlock, timestamp }) {
46      const { difficulty } = originalBlock;
47  
48      if (difficulty < 1) return 1;
49  
50      const difference = timestamp - originalBlock.timestamp;
51  
52      if (difference > MINE_RATE) return difficulty - 1;
53  
54      return difficulty + 1;
55    }
56  }
57  
58  module.exports = Block;