forked from MyEtherWallet/VanityEth
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
6 changed files
with
617 additions
and
622 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -35,3 +35,4 @@ jspm_packages | |
|
||
# Optional REPL history | ||
.node_repl_history | ||
VanityEth-log* |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,4 @@ | ||
FROM node:8.9-alpine | ||
FROM node:14.18-alpine | ||
|
||
RUN mkdir -p /usr/src/app | ||
WORKDIR /usr/src/app | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,99 +1,126 @@ | ||
#! /usr/bin/env node | ||
|
||
var VanityEth = require('./libs/VanityEth'); | ||
const ora = require('ora'); | ||
var cluster = require('cluster') | ||
var TimeFormat = require('hh-mm-ss') | ||
var numCPUs = require('os').cpus().length | ||
var argv = require('yargs') | ||
.usage('Usage: $0 <command> [options]') | ||
.example('$0 -checksum -i B00B5', 'get a wallet where address matches B00B5 in checksum format') | ||
.example('$0 --contract -i ABC', 'get a wallet where 0 nonce contract address matches the vanity') | ||
.example('$0 -n 25 -i ABC', 'get 25 vanity wallets') | ||
.example('$0 -n 1000', 'get 1000 random wallets') | ||
.alias('i', 'input') | ||
.string('i') | ||
.describe('i', 'input hex string') | ||
.alias('c', 'checksum') | ||
.boolean('c') | ||
.describe('c', 'check against the checksum address') | ||
.alias('n', 'count') | ||
.number('n') | ||
.describe('n', 'number of wallets') | ||
.boolean('contract') | ||
.describe('contract', 'contract address for contract deployment') | ||
.alias('l', 'log') | ||
.boolean('l') | ||
.describe('l', 'log output to file') | ||
.help('h') | ||
.alias('h', 'help') | ||
.epilog('copyright 2018') | ||
.argv; | ||
import VanityEth from "./libs/VanityEth.js"; | ||
import ora from "ora"; | ||
import cluster from "cluster"; | ||
import TimeFormat from "hh-mm-ss"; | ||
import { cpus } from "os"; | ||
import Yargs from "yargs"; | ||
import process from "process"; | ||
import fs from "fs"; | ||
|
||
const numCPUs = cpus().length; | ||
const argv = Yargs(process.argv.slice(2)) | ||
.usage("Usage: $0 <command> [options]") | ||
.example( | ||
"$0 -checksum -i B00B5", | ||
"get a wallet where address matches B00B5 in checksum format" | ||
) | ||
.example( | ||
"$0 --contract -i ABC", | ||
"get a wallet where 0 nonce contract address matches the vanity" | ||
) | ||
.example("$0 -n 25 -i ABC", "get 25 vanity wallets") | ||
.example("$0 -n 1000", "get 1000 random wallets") | ||
.alias("i", "input") | ||
.string("i") | ||
.describe("i", "input hex string") | ||
.alias("c", "checksum") | ||
.boolean("c") | ||
.describe("c", "check against the checksum address") | ||
.alias("n", "count") | ||
.number("n") | ||
.describe("n", "number of wallets") | ||
.boolean("contract") | ||
.describe("contract", "contract address for contract deployment") | ||
.alias("l", "log") | ||
.boolean("l") | ||
.describe("l", "log output to file") | ||
.help("h") | ||
.alias("h", "help") | ||
.epilog("copyright 2021").argv; | ||
|
||
if (cluster.isMaster) { | ||
const args = { | ||
input: argv.input ? argv.input : '', | ||
isChecksum: argv.checksum ? true : false, | ||
numWallets: argv.count ? argv.count : 1, | ||
isContract: argv.contract ? true : false, | ||
log: argv.log ? true : false, | ||
logFname: argv.log ? 'VanityEth-log-' + Date.now() + '.txt' : '' | ||
} | ||
if (!VanityEth.isValidHex(args.input)) { | ||
console.error(args.input + ' is not valid hexadecimal'); | ||
process.exit(1); | ||
} | ||
if (args.log) { | ||
var fs = require('fs'); | ||
console.log('logging into ' + args.logFname); | ||
var logStream = fs.createWriteStream(args.logFname, { 'flags': 'a' }); | ||
} | ||
var walletsFound = 0; | ||
const spinner = ora('generating vanity address 1/' + args.numWallets).start(); | ||
let addps = 0; | ||
setInterval(function(){ | ||
spinner.text ='Approximate ETA for an account ' + TimeFormat.fromS((Math.pow(16,20)/Math.pow(16,20-args.input.length))/addps, 'hh:mm:ss'); | ||
addps = 0; | ||
},1000) | ||
for (var i = 0; i < numCPUs; i++) { | ||
const worker_env = { | ||
input: args.input, | ||
isChecksum: args.isChecksum, | ||
isContract: args.isContract | ||
const args = { | ||
input: argv.input ? argv.input : "", | ||
isChecksum: argv.checksum ? true : false, | ||
numWallets: argv.count ? argv.count : 1, | ||
isContract: argv.contract ? true : false, | ||
log: argv.log ? true : false, | ||
logFname: argv.log ? "VanityEth-log-" + Date.now() + ".txt" : "", | ||
}; | ||
if (!VanityEth.isValidHex(args.input)) { | ||
console.error(args.input + " is not valid hexadecimal"); | ||
process.exit(1); | ||
} | ||
let logStream; | ||
if (args.log) { | ||
console.log("logging into " + args.logFname); | ||
logStream = fs.createWriteStream(args.logFname, { flags: "a" }); | ||
} | ||
let walletsFound = 0; | ||
const spinner = ora("generating vanity address 1/" + args.numWallets).start(); | ||
let addps = 0; | ||
setInterval(function () { | ||
spinner.text = | ||
"Approximate ETA for an account " + | ||
TimeFormat.fromS( | ||
Math.pow(16, 20) / Math.pow(16, 20 - args.input.length) / addps, | ||
"hh:mm:ss" | ||
); | ||
addps = 0; | ||
}, 1000); | ||
for (let i = 0; i < numCPUs; i++) { | ||
const worker_env = { | ||
input: args.input, | ||
isChecksum: args.isChecksum, | ||
isContract: args.isContract, | ||
}; | ||
const proc = cluster.fork(worker_env); | ||
proc.on("message", function (message) { | ||
if (message.account) { | ||
spinner.succeed(JSON.stringify(message)); | ||
if (args.log) logStream.write(JSON.stringify(message) + "\n"); | ||
walletsFound++; | ||
if (walletsFound >= args.numWallets) { | ||
cleanup(); | ||
} | ||
proc = cluster.fork(worker_env); | ||
proc.on('message', function(message) { | ||
if(message.account){ | ||
spinner.succeed(JSON.stringify(message)); | ||
if (args.log) logStream.write(JSON.stringify(message) + "\n"); | ||
walletsFound++; | ||
if (walletsFound >= args.numWallets) { | ||
cleanup(); | ||
} | ||
spinner.text ='generating vanity address ' + (walletsFound + 1) +'/' + args.numWallets; | ||
spinner.start(); | ||
} else if(message.counter){ | ||
addps++ | ||
} | ||
}); | ||
} | ||
|
||
spinner.text = | ||
"generating vanity address " + | ||
(walletsFound + 1) + | ||
"/" + | ||
args.numWallets; | ||
spinner.start(); | ||
} else if (message.counter) { | ||
addps++; | ||
} | ||
}); | ||
} | ||
} else { | ||
const worker_env = process.env; | ||
while (true) { | ||
process.send({ | ||
account: VanityEth.getVanityWallet(worker_env.input, worker_env.isChecksum == 'true', worker_env.isContract == 'true', function (){ | ||
const worker_env = process.env; | ||
while (true) { | ||
if (process.send) { | ||
process.send({ | ||
account: VanityEth.getVanityWallet( | ||
worker_env.input, | ||
worker_env.isChecksum == "true", | ||
worker_env.isContract == "true", | ||
function () { | ||
process.send({ | ||
counter: true | ||
}) | ||
})}) | ||
counter: true, | ||
}); | ||
} | ||
), | ||
}); | ||
} | ||
} | ||
} | ||
process.stdin.resume(); | ||
var cleanup = function(options, err) { | ||
if (err) console.log(err.stack); | ||
for (var id in cluster.workers) cluster.workers[id].process.kill(); | ||
process.exit(); | ||
} | ||
process.on('exit', cleanup.bind(null, {})); | ||
process.on('SIGINT', cleanup.bind(null, {})); | ||
process.on('uncaughtException', cleanup.bind(null, {})); | ||
const cleanup = function (options, err) { | ||
if (err) console.log(err.stack); | ||
for (const id in cluster.workers) cluster.workers[id].process.kill(); | ||
process.exit(); | ||
}; | ||
process.on("exit", cleanup.bind(null, {})); | ||
process.on("SIGINT", cleanup.bind(null, {})); | ||
process.on("uncaughtException", cleanup.bind(null, {})); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,46 +1,55 @@ | ||
const crypto = require('crypto'); | ||
var ethUtils = require('ethereumjs-util'); | ||
import crypto from "crypto"; | ||
import ethUtils from "ethereumjs-util"; | ||
var ERRORS = { | ||
invalidHex: "Invalid hex input" | ||
} | ||
var getRandomWallet = function() { | ||
var randbytes = crypto.randomBytes(32); | ||
var address = '0x' + ethUtils.privateToAddress(randbytes).toString('hex'); | ||
return { address: address, privKey: randbytes.toString('hex') } | ||
} | ||
var isValidHex = function(hex) { | ||
if (!hex.length) return true; | ||
hex = hex.toUpperCase(); | ||
var re = /^[0-9A-F]+$/g; | ||
return re.test(hex); | ||
} | ||
var isValidVanityWallet = function(wallet, input, isChecksum, isContract) { | ||
var _add = wallet.address; | ||
if (isContract) { | ||
var _contractAdd = getDeterministicContractAddress(_add); | ||
_contractAdd = isChecksum ? ethUtils.toChecksumAddress(_contractAdd) : _contractAdd; | ||
wallet.contract = _contractAdd; | ||
return _contractAdd.substr(2, input.length) == input | ||
} | ||
_add = isChecksum ? ethUtils.toChecksumAddress(_add) : _add; | ||
return _add.substr(2, input.length) == input; | ||
} | ||
var getVanityWallet = function(input = '', isChecksum = false, isContract = false, counter = function(){}) { | ||
if (!isValidHex(input)) throw new Error(ERRORS.invalidHex); | ||
input = isChecksum ? input : input.toLowerCase(); | ||
var _wallet = getRandomWallet(); | ||
while (!isValidVanityWallet(_wallet, input, isChecksum, isContract)) { | ||
counter() | ||
_wallet = getRandomWallet(isChecksum); | ||
} | ||
if (isChecksum) _wallet.address = ethUtils.toChecksumAddress(_wallet.address); | ||
return _wallet; | ||
} | ||
var getDeterministicContractAddress = function(address) { | ||
return '0x' + ethUtils.sha3(ethUtils.rlp.encode([address, 0])).slice(12).toString('hex'); | ||
} | ||
module.exports = { | ||
getVanityWallet: getVanityWallet, | ||
isValidHex: isValidHex, | ||
ERRORS: ERRORS | ||
} | ||
invalidHex: "Invalid hex input", | ||
}; | ||
var getRandomWallet = function () { | ||
var randbytes = crypto.randomBytes(32); | ||
var address = "0x" + ethUtils.privateToAddress(randbytes).toString("hex"); | ||
return { address: address, privKey: randbytes.toString("hex") }; | ||
}; | ||
var isValidHex = function (hex) { | ||
if (!hex.length) return true; | ||
hex = hex.toUpperCase(); | ||
var re = /^[0-9A-F]+$/g; | ||
return re.test(hex); | ||
}; | ||
var isValidVanityWallet = function (wallet, input, isChecksum, isContract) { | ||
var _add = wallet.address; | ||
if (isContract) { | ||
var _contractAdd = getDeterministicContractAddress(_add); | ||
_contractAdd = isChecksum | ||
? ethUtils.toChecksumAddress(_contractAdd) | ||
: _contractAdd; | ||
wallet.contract = _contractAdd; | ||
return _contractAdd.substr(2, input.length) == input; | ||
} | ||
_add = isChecksum ? ethUtils.toChecksumAddress(_add) : _add; | ||
return _add.substr(2, input.length) == input; | ||
}; | ||
var getVanityWallet = function ( | ||
input = "", | ||
isChecksum = false, | ||
isContract = false, | ||
counter = function () {} | ||
) { | ||
if (!isValidHex(input)) throw new Error(ERRORS.invalidHex); | ||
input = isChecksum ? input : input.toLowerCase(); | ||
var _wallet = getRandomWallet(); | ||
while (!isValidVanityWallet(_wallet, input, isChecksum, isContract)) { | ||
counter(); | ||
_wallet = getRandomWallet(isChecksum); | ||
} | ||
if (isChecksum) _wallet.address = ethUtils.toChecksumAddress(_wallet.address); | ||
return _wallet; | ||
}; | ||
var getDeterministicContractAddress = function (address) { | ||
return ( | ||
"0x" + | ||
ethUtils | ||
.keccak256(ethUtils.rlp.encode([address, 0])) | ||
.slice(12) | ||
.toString("hex") | ||
); | ||
}; | ||
export default { getVanityWallet, isValidHex, ERRORS }; |
Oops, something went wrong.