From 94c40441afaa44429f5e72db9ad1f1b091db01cd Mon Sep 17 00:00:00 2001 From: Luke Childs <lukechilds123@gmail.com> Date: Thu, 9 May 2019 07:15:31 +0700 Subject: [PATCH] Add p2wpkh-p2sh address format --- bench/index.js | 40 +++++++++++++++-------------- src/index.js | 59 ++++++++++++++++++++++++++++++++++++------ src/p2pkh.js | 64 +++++++++++----------------------------------- src/p2wpkh-p2sh.js | 24 +++++++++++++++++ 4 files changed, 111 insertions(+), 76 deletions(-) create mode 100644 src/p2wpkh-p2sh.js diff --git a/bench/index.js b/bench/index.js index a0999d3..4323b9f 100644 --- a/bench/index.js +++ b/bench/index.js @@ -1,26 +1,28 @@ const Vain = require('..'); const prettyMs = require('pretty-ms'); -const prefix = 'BTC'; -console.log(); -console.log(`Searching for the prefix "${prefix}"...`); +['p2pkh', 'p2wpkh-p2sh'].forEach(addressFormat => { + const prefix = 'BTC'; + console.log(); + console.log(`Searching for the prefix "${prefix}" for addres format "${addressFormat}"...`); -const vain = new Vain({prefix}); + const vain = new Vain({prefix, addressFormat}); -vain.on('update', data => { - const duration = prettyMs(data.duration); - const {attempts} = data; - const speed = `${data.addressesPerSecond} addr/s`; - console.log(`Duration: ${duration} | Attempts: ${attempts} | Speed: ${speed}`); -}); + vain.on('update', data => { + const duration = prettyMs(data.duration); + const {attempts} = data; + const speed = `${data.addressesPerSecond} addr/s`; + console.log(`Duration: ${duration} | Attempts: ${attempts} | Speed: ${speed}`); + }); -vain.on('found', data => { - console.log(); - console.log(`Address: ${data.address}`); - console.log(`WIF: ${data.wif}`); - console.log(); - console.log(`Found in ${prettyMs(data.duration)}`); - console.log(`Speed: ${data.addressesPerSecond} addr/s`); -}); + vain.on('found', data => { + console.log(); + console.log(`Address: ${data.address}`); + console.log(`WIF: ${data.wif}`); + console.log(); + console.log(`Found in ${prettyMs(data.duration)}`); + console.log(`Speed: ${data.addressesPerSecond} addr/s`); + }); -vain.start(); + vain.start(); +}); diff --git a/src/index.js b/src/index.js index 47692ef..2fcb7f7 100644 --- a/src/index.js +++ b/src/index.js @@ -1,21 +1,64 @@ const Emitter = require('tiny-emitter'); const p2pkh = require('./p2pkh'); +const p2wpkhp2sh = require('./p2wpkh-p2sh'); + +const addressFormats = new Map(Object.entries({ + p2pkh, + 'p2wpkh-p2sh': p2wpkhp2sh +})); + +const ONE_SECOND = 1000; class Vain extends Emitter { - constructor({prefix}) { + constructor({prefix, addressFormat = 'p2pkh'}) { super(); - this.prefix = `1${prefix}`; + this.addressFormat = addressFormats.get(addressFormat); + this.prefix = `${this.addressFormat.prefix}${prefix}`; } start() { return new Promise(resolve => { - const miner = p2pkh(this.prefix); - miner.on('update', data => this.emit('update', data)); - miner.on('found', data => { - this.emit('found', data); - resolve(data); - }); + const startTime = Date.now(); + + let found; + let attempts = 0; + let data; + let lastUpdate = Date.now(); + + while (!found) { + attempts++; + + data = this.addressFormat.derive(); + + if (data.address.startsWith(this.prefix)) { + found = true; + } + + const now = Date.now(); + if ((now - lastUpdate) > ONE_SECOND) { + const duration = now - startTime; + const addressesPerSecond = Math.floor(attempts / (duration / ONE_SECOND)); + this.emit('update', { + duration, + attempts, + addressesPerSecond + }); + lastUpdate = now; + } + } + + const endTime = Date.now(); + const duration = endTime - startTime; + const addressesPerSecond = Math.floor(attempts / (duration / ONE_SECOND)); + + const result = { + duration, + addressesPerSecond, + ...this.addressFormat.format(data) + }; + this.emit('found', result); + resolve(result); }); } } diff --git a/src/p2pkh.js b/src/p2pkh.js index 809e67b..52c88d8 100644 --- a/src/p2pkh.js +++ b/src/p2pkh.js @@ -1,56 +1,22 @@ -const Emitter = require('tiny-emitter'); const bitcoin = require('bitcoinjs-lib'); -const ONE_SECOND = 1000; - -const p2pkh = prefix => { - const emitter = new Emitter(); - - process.nextTick(() => { - const startTime = Date.now(); - - let found; - let attempts = 0; - let keyPair; - let address; - let lastUpdate = Date.now(); - - while (!found) { - attempts++; - keyPair = bitcoin.ECPair.makeRandom(); - ({address} = bitcoin.payments.p2pkh({pubkey: keyPair.publicKey})); - - if (address.startsWith(prefix)) { - found = true; - } - - const now = Date.now(); - if ((now - lastUpdate) > ONE_SECOND) { - const duration = now - startTime; - const addressesPerSecond = Math.floor(attempts / (duration / ONE_SECOND)); - emitter.emit('update', { - duration, - attempts, - addressesPerSecond - }); - lastUpdate = now; - } - } - - const endTime = Date.now(); - const duration = endTime - startTime; - const addressesPerSecond = Math.floor(attempts / (duration / ONE_SECOND)); +const p2pkh = { + prefix: '1' +}; - emitter.emit('found', { - duration, - attempts, - addressesPerSecond, - address, - wif: keyPair.toWIF() - }); - }); +p2pkh.derive = () => { + const keyPair = bitcoin.ECPair.makeRandom(); + const {address} = bitcoin.payments.p2pkh({pubkey: keyPair.publicKey}); - return emitter; + return { + address, + keyPair + }; }; +p2pkh.format = ({address, keyPair}) => ({ + address, + wif: keyPair.toWIF() +}); + module.exports = p2pkh; diff --git a/src/p2wpkh-p2sh.js b/src/p2wpkh-p2sh.js new file mode 100644 index 0000000..12658ef --- /dev/null +++ b/src/p2wpkh-p2sh.js @@ -0,0 +1,24 @@ +const bitcoin = require('bitcoinjs-lib'); + +const p2wpkhp2sh = { + prefix: '3' +}; + +p2wpkhp2sh.derive = () => { + const keyPair = bitcoin.ECPair.makeRandom(); + const {address} = bitcoin.payments.p2sh({ + redeem: bitcoin.payments.p2wpkh({pubkey: keyPair.publicKey}) + }); + + return { + address, + keyPair + }; +}; + +p2wpkhp2sh.format = ({address, keyPair}) => ({ + address, + wif: keyPair.toWIF() +}); + +module.exports = p2wpkhp2sh;