const ChainUtil = require('../chain-util'); const { DIFFICULTY, MINE_RATE } = require('../config'); class Block { constructor(timestamp, lastHash, hash, data, nonce, difficulty) { this.timestamp = timestamp; this.lastHash = lastHash; this.hash = hash; this.data = data; this.nonce = nonce; this.difficulty = difficulty || DIFFICULTY; } toString() { return `Block - Timestamp : ${this.timestamp} Last Hash : ${this.lastHash.substring(0, 10)} Hash : ${this.hash.substring(0, 10)} Nonce : ${this.nonce} Difficulty: ${this.difficulty} Data : ${this.data}`; } static genesis() { return new this('Genesis time', '-----', 'f1r57-h45h', [], 0, DIFFICULTY); } //we want this to eventually be continously running where there are things in the pool, //however as node is single threaded, this almost has to be a fiber, and yield after every //other iteration to allow for meaningful forward progress //we can either add all new transactions into the block as we see them, or stay with the starting list, idk which //to be done later static mineBlock(lastBlock, data) { let hash, timestamp; const lastHash = lastBlock.hash; let { difficulty } = lastBlock; let nonce = 0; do { nonce++; timestamp = Date.now(); difficulty = Block.adjustDifficulty(lastBlock, timestamp); hash = Block.hash(timestamp, lastHash, data, nonce, difficulty); } while (hash.substring(0, difficulty) !== '0'.repeat(difficulty)); return new this(timestamp, lastHash, hash, data, nonce, difficulty); } static hash(timestamp, lastHash, data, nonce, difficulty) { return ChainUtil.hash(`${timestamp}${lastHash}${data}${nonce}${difficulty}`).toString(); } static blockHash(block) { const { timestamp, lastHash, data, nonce, difficulty } = block; return Block.hash(timestamp, lastHash, data, nonce, difficulty); } static adjustDifficulty(lastBlock, currentTime) { let { difficulty } = lastBlock; difficulty = lastBlock.timestamp + MINE_RATE > currentTime ? difficulty + 1 : difficulty - 1; return difficulty; } } module.exports = Block;