diff --git a/.gitignore b/.gitignore index 646ac51..fa7139b 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ .DS_Store node_modules/ +*.txt \ No newline at end of file diff --git a/README.md b/README.md index c9df372..ba7c77a 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,13 @@ +# Origin source +* [https://github.com/professorhantzen/ripple-vanity](https://github.com/professorhantzen/ripple-vanity) + +# Update from origin +* Add cluster for multi core CPU usage +* Export result to file +* Support regex vanity string +* Default max attemps = Math.round(Number.MAX_VALUE/2); +* Some minor cleanup + # ripple-vanity Simple node.js script to create Ripple "vanity" wallets. These are secp256k1 public/private key pairs, where the public key encodes to a base58 address containing a search string. @@ -19,3 +29,4 @@ String format: `123456789 ABCDEFGH JKLMN PQRSTUVWXYZabcdefghijk mnopqrstuvwxyz` (Note: `0`, `I`, `O` and `l` are excluded, as per [base58](https://en.wikipedia.org/wiki/Base58) convention.) + diff --git a/package.json b/package.json new file mode 100644 index 0000000..4672d64 --- /dev/null +++ b/package.json @@ -0,0 +1,13 @@ +{ + "name": "ripple-vanity", + "version": "1.1.0", + "private": true, + "dependencies": { + "ripple-keypairs": "^0.8.0" + }, + "engines": { + "node": "6.*", + "npm": "3.*" + }, + "main": "ripple-vanity.js" +} diff --git a/ripple-vanity.js b/ripple-vanity.js index 1e5106c..4c61ed0 100644 --- a/ripple-vanity.js +++ b/ripple-vanity.js @@ -1,50 +1,63 @@ -// ripple vanity address finder -// -const l = console.log; -const s = process.stdout; +const log = console.log; +const stdout = process.stdout; const cr = '\r\x1b[K'; -const vanity_string = process.argv[2]; -const attempts = process.argv[3]; +const vanitystr = process.argv[2]; +const attempts = process.argv[3] || Math.round(Number.MAX_VALUE / 2); +const cluster = require('cluster'); +const numCPUs = process.argv[4] || Math.max(1, require('os').cpus().length - 1); +const xrpKeygen = require('ripple-keypairs'); +const fs = require('fs'); -var kp = require('ripple-keypairs'); +var filename = 'VanityXRP_'+Math.round(new Date().getTime() / 1e3)+'.txt'; var start_time = Date.now(); var end_time = null; -var valid = false; -var found = 0; -var usage = 'Ripple Vanity Address Finder v1.0\n\n'+ - 'usage: node ripple-vanity.js \n'+ - 'example: node ripple-vanity.js xrp 100000\n\n'+ - ' may be comprised of any of these characters:\n'+ - '123456789 ABCDEFGH JKLMN PQRSTUVWXYZabcdefghijk mnopqrstuvwxyz\n'+ - '(Note: \'0\', \'I\', \'O\' and \'l\' are excluded.)'; +var valid = vanitystr && !~vanitystr.search('(0|O|I|l)'); +var regex = new RegExp(vanitystr, 'i'); +var found = 0; +var usage = 'Ripple Vanity Address Finder v1.1\n\n'+ + 'usage: node ripple-vanity.js \n'+ + 'example: node ripple-vanity.js "mj(i|1)" 1000000 4\n\n'+ + ' may be regex of comprised of any of these characters:\n'+ + '123456789 ABCDEFGH JKLMN PQRSTUVWXYZabcdefghijk mnopqrstuvwxyz\n'+ + '(Note: \'0\', \'I\', \'O\' and \'l\' are excluded.)\n---\n'; -if(vanity_string && - vanity_string.split('0').length === 1 && - vanity_string.split('I').length === 1 && - vanity_string.split('O').length === 1 && - vanity_string.split('l').length === 1 ) valid = true; +if (cluster.isMaster || !valid || !attempts) { + log(usage); + log('Vanity is valid:', valid); + log('Searching', attempts, 'addresses for', regex, 'with', numCPUs, "CPUs\n"); + stdout.write(cr + '0%'); -if(attempts > 0 && valid) { - l('Searching', attempts, 'addresses for ' + '\"' + vanity_string +'\"...'); - s.write(cr + '0%'); + for (var i = numCPUs - 1; i >= 0; i--) { + cluster.fork(); + } + + // cluster.on('exit', function (deadWorker, code, signal) { + // for (var id in cluster.workers) cluster.workers[id].process.kill(); + // return process.exit(); + // }); +} else { var temp_wallet = null; var prog = (attempts/100).toFixed(0) * 1; // for speed not accuracy var step = prog; var perc = 0; - for(var i = 0; i-1) { - l(cr + i +', ' + temp_wallet.accountID + ', ' + temp_wallet.seed); - found++; + temp_wallet = xrpKeygen.generateWallet(); + + if (temp_wallet.accountID.search(regex) == 1) { + log('Found:', cr + i +', ' + temp_wallet.accountID + ', ' + temp_wallet.seed); + fs.appendFileSync(filename, temp_wallet.accountID+', '+temp_wallet.seed+'\n'); + found++; } } + end_time = Date.now(); - var pl = ''; if(found>1 || found === 0) pl = 'es' ; - l(cr + found + ' address'+pl+' found. Took ' + ((end_time-start_time)/60000).toFixed(1) + ' minutes.'); -} else { - l(usage); + var pl = (found>1 || found === 0) ? 'es' : ''; + log('Cluster', cluster.worker.id, ':', cr, found, 'address', pl, 'found. Took', ((end_time-start_time)/60e3).toFixed(1), 'minutes.'); + + return process.exit(); }