Skip to content

Instantly share code, notes, and snippets.

@elleyeayeme
Created May 30, 2018 19:07
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save elleyeayeme/7d29997b518dd891cae066f275a006bf to your computer and use it in GitHub Desktop.
Save elleyeayeme/7d29997b518dd891cae066f275a006bf to your computer and use it in GitHub Desktop.
const { sha256 } = require('js-sha256').sha256;
class Miner {
constructor(fnHash, difficulty = 1, maxAttempts = 1000, verbose = true) {
if (difficulty <= 0 || difficulty > 5) {
throw new Error('Invalid difficulty provided');
}
this.fnHash = fnHash;
this.maxAttempts = maxAttempts;
this.verbose = verbose;
this.difficulty = difficulty;
this.nonce = 0;
}
getPrefix() {
return '0'.repeat(this.difficulty);
}
mine(merkleRoot) {
console.log(`Attempting to mine block with Merkle root ${merkleRoot}.`);
console.log(`Difficulty level: ${this.difficulty}`);
const startTime = new Date().valueOf();
const prefix = this.getPrefix();
for (this.nonce = 0; this.nonce < this.maxAttempts; this.nonce += 1) {
const hash = this.fnHash(`${merkleRoot}${this.nonce}`);
this.logAttempt(hash);
if (String(hash).slice(0, this.difficulty) === prefix) {
return this.logResult(true, startTime, new Date().valueOf());
}
}
return this.logResult(false, startTime, new Date().valueOf());
}
logAttempt(hash) {
if (this.verbose === true) {
console.log(`Attempting with nonce ${this.nonce}: ${hash}`);
}
}
logResult(succeeded, startTimeMs, endTimeMs) {
const elapsed = (endTimeMs - startTimeMs) / 1000;
if (succeeded) {
return console.log(`\n*** Block mined after ${this.nonce + 1} attempts in ${elapsed} seconds ***`);
}
return console.log(`\n*** Unable to mine block after ${this.nonce} attempts in ${elapsed} seconds ***`);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment