Skip to content

Instantly share code, notes, and snippets.

@mfcodeworks
Last active November 27, 2019 00:10
Show Gist options
  • Save mfcodeworks/8b2a59e16c834aa5d11e8d74bc528571 to your computer and use it in GitHub Desktop.
Save mfcodeworks/8b2a59e16c834aa5d11e8d74bc528571 to your computer and use it in GitHub Desktop.
Web miner using Argon2id hashing from argon2-browser package
export default class Miner {
constructor(difficulty = 1, block = undefined) {
this.difficulty = difficulty;
this.block = block || {
id: 1,
time: new Date().getTime(),
prevHash: 'd5cd02605f5dd530caa73c799ee75d92b8e637986ab4b23875c2fa95da7d5674',
data: {
foo: 42
}
}
this.nonce = 0;
this.hash = '';
this.mined = false;
this.salt = 'nygmacoin';
}
mine() {
if (!this.mined) {
this.nonce++;
console.log('Attempting hash', `${this.block.id}${this.block.time}${this.nonce}`);
return argon2.hash({
pass: `${this.block.id}${this.block.time}${this.nonce}`,
salt: this.salt,
time: 3,
mem: 2048,
hashLen: 64,
parallelism: 1,
type: argon2.ArgonType.Argon2id
})
.then(result => {
console.log(`Hash ${this.nonce}`, result.hashHex);
if (result.hashHex.substr(0, this.difficulty) === '0'.repeat(this.difficulty)) {
this.mined = true;
this.hash = result.hashHex;
return {
block: this.block,
nonce: this.nonce,
hash: this.hash
};
} else {
return this.mine();
}
})
.catch(err => { console.warn('Hash error', err) });
}
}
}
import { Observable } from 'rxjs';
import { share } from 'rxjs/operators';
export default class Miner {
constructor(difficulty = 1, block = undefined) {
this.difficulty = difficulty;
this.block = block || {
id: 1,
time: new Date().getTime(),
prevHash: 'd5cd02605f5dd530caa73c799ee75d92b8e637986ab4b23875c2fa95da7d5674',
data: {
foo: 42
}
}
this.nonce = 0;
this.hash = '';
this.mined = false;
this.salt = 'nygmacoin';
this.observer = null;
}
mine() {
// Return observable for miner process
return Observable.create(observer => {
this.observer = observer;
observer.next(this.hashBlock());
})
.pipe(share());
}
hashBlock() {
// Check if block has been mined
if (!this.mined) {
// Increase nonce and begin hashing
this.nonce++;
argon2.hash({
pass: `${this.block.id}${this.block.time}${this.nonce}`,
salt: this.salt,
time: 3,
mem: 2048,
hashLen: 64,
parallelism: 1,
type: argon2.ArgonType.Argon2id
})
.then(result => {
// Validate result
if (result.hashHex.substr(0, this.difficulty) === '0'.repeat(this.difficulty)) {
// If valid set results
this.mined = true;
this.hash = result.hashHex;
this.block.hash = this.hash;
this.block.nonce = this.nonce;
// Close out miner observer
this.observer.next({
block: this.block,
nonce: this.nonce,
hash: this.hash
});
this.observer.complete();
} else {
// If not vaid send update and continue mining
this.observer.next(`Hash ${this.nonce}: ${result.hashHex}`);
this.hashBlock();
}
})
.catch(this.observer.error);
}
}
}
import Miner from './miner.js';
let mine = new Miner(1, {
id: 1,
time: new Date().getTime(),
prevHash: 'd5cd02605f5dd530caa73c799ee75d92b8e637986ab4b23875c2fa95da7d5674',
data: {
foo: 42
}
});
const start = new Date().getTime();
mine.mine()
.then(mined => {
let elapsed = (new Date().getTime() - start)/1000
console.log('Block mined', mined);
console.log(
`Attempts ${mined.nonce}\ntime ${elapsed}s\nhash rate ${Math.floor(mined.nonce / elapsed)} h/s`
);
});
/* DEBUG: For future implementation
const worker = new Worker('mine.worker.js', { type: "module" });
worker.addEventListener('message', (e) => {
console.log(e);
});
worker.postMessage({
difficulty: 1,
block: {
id: 1,
time: new Date().getTime(),
data: 43
}
});
*/
import './node_modules/argon2-browser/lib/argon2.js';
import Miner from './miner.js';
// DEBUG: Currently module import not supported in browsers
self.addEventListener('message', (e) => {
// init miner and time
let mine = new Miner(e.difficulty, e.block);
let start = new Date().getTime();
// start mining
mine.mine()
.then(mined => {
// calc time and return result
self.postMessage({
mined,
elapsed: (new Date().getTime() - start)/1000
});
self.close();
});
}, false);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment