From 5836433c927f0ea23e4ffd6c8137279407419c78 Mon Sep 17 00:00:00 2001 From: Boris Kubiak Date: Thu, 8 Mar 2018 08:46:06 +0100 Subject: [PATCH] Improve perfs, get rid of ethereumjs-util --- package-lock.json | 88 ++--------------------------------------------- package.json | 3 +- src/js/vanity.js | 38 ++++++++++++++------ 3 files changed, 32 insertions(+), 97 deletions(-) diff --git a/package-lock.json b/package-lock.json index 793040f..decd7de 100644 --- a/package-lock.json +++ b/package-lock.json @@ -978,37 +978,6 @@ } } }, - "babel-preset-es2015": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-preset-es2015/-/babel-preset-es2015-6.24.1.tgz", - "integrity": "sha1-1EBQ1rwsn+6nAqrzjXJ6AhBTiTk=", - "requires": { - "babel-plugin-check-es2015-constants": "6.22.0", - "babel-plugin-transform-es2015-arrow-functions": "6.22.0", - "babel-plugin-transform-es2015-block-scoped-functions": "6.22.0", - "babel-plugin-transform-es2015-block-scoping": "6.26.0", - "babel-plugin-transform-es2015-classes": "6.24.1", - "babel-plugin-transform-es2015-computed-properties": "6.24.1", - "babel-plugin-transform-es2015-destructuring": "6.23.0", - "babel-plugin-transform-es2015-duplicate-keys": "6.24.1", - "babel-plugin-transform-es2015-for-of": "6.23.0", - "babel-plugin-transform-es2015-function-name": "6.24.1", - "babel-plugin-transform-es2015-literals": "6.22.0", - "babel-plugin-transform-es2015-modules-amd": "6.24.1", - "babel-plugin-transform-es2015-modules-commonjs": "6.26.0", - "babel-plugin-transform-es2015-modules-systemjs": "6.24.1", - "babel-plugin-transform-es2015-modules-umd": "6.24.1", - "babel-plugin-transform-es2015-object-super": "6.24.1", - "babel-plugin-transform-es2015-parameters": "6.24.1", - "babel-plugin-transform-es2015-shorthand-properties": "6.24.1", - "babel-plugin-transform-es2015-spread": "6.22.0", - "babel-plugin-transform-es2015-sticky-regex": "6.24.1", - "babel-plugin-transform-es2015-template-literals": "6.22.0", - "babel-plugin-transform-es2015-typeof-symbol": "6.23.0", - "babel-plugin-transform-es2015-unicode-regex": "6.24.1", - "babel-plugin-transform-regenerator": "6.26.0" - } - }, "babel-preset-stage-3": { "version": "6.24.1", "resolved": "https://registry.npmjs.org/babel-preset-stage-3/-/babel-preset-stage-3-6.24.1.tgz", @@ -1083,15 +1052,6 @@ "to-fast-properties": "1.0.3" } }, - "babelify": { - "version": "7.3.0", - "resolved": "https://registry.npmjs.org/babelify/-/babelify-7.3.0.tgz", - "integrity": "sha1-qlau3nBn/XvVSWZu4W3ChQh+iOU=", - "requires": { - "babel-core": "6.26.0", - "object-assign": "4.1.1" - } - }, "babylon": { "version": "6.18.0", "resolved": "https://registry.npmjs.org/babylon/-/babylon-6.18.0.tgz", @@ -3037,30 +2997,6 @@ "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=" }, - "ethereumjs-util": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-5.1.2.tgz", - "integrity": "sha1-JboCFcu0wvCxCKb5avKi5i5Fkh8=", - "requires": { - "babel-preset-es2015": "6.24.1", - "babelify": "7.3.0", - "bn.js": "4.11.8", - "create-hash": "1.1.3", - "ethjs-util": "0.1.4", - "keccak": "1.4.0", - "rlp": "2.0.0", - "secp256k1": "3.4.0" - } - }, - "ethjs-util": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/ethjs-util/-/ethjs-util-0.1.4.tgz", - "integrity": "sha1-HItoeSV0RO9NPz+7rC3tEs2ZfZM=", - "requires": { - "is-hex-prefixed": "1.0.0", - "strip-hex-prefix": "1.0.0" - } - }, "event-emitter": { "version": "0.3.5", "resolved": "https://registry.npmjs.org/event-emitter/-/event-emitter-0.3.5.tgz", @@ -5143,11 +5079,6 @@ "is-extglob": "2.1.1" } }, - "is-hex-prefixed": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-hex-prefixed/-/is-hex-prefixed-1.0.0.tgz", - "integrity": "sha1-fY035q135dEnFIkTxXPggtd39VQ=" - }, "is-installed-globally": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/is-installed-globally/-/is-installed-globally-0.1.0.tgz", @@ -8427,11 +8358,6 @@ "inherits": "2.0.3" } }, - "rlp": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/rlp/-/rlp-2.0.0.tgz", - "integrity": "sha1-nbOE/0uJqPYVY9kjldhiWxjzr7A=" - }, "run-async": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/run-async/-/run-async-0.1.0.tgz", @@ -8541,9 +8467,9 @@ } }, "secp256k1": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/secp256k1/-/secp256k1-3.4.0.tgz", - "integrity": "sha512-eC120ESQ6MB3gMkxj0PVcSjv/9VtSUmm9uPGNc58yTs93iMCUQZ1xeGPidQMY1z1O4psbCtOxRu3vNqpbuck6Q==", + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/secp256k1/-/secp256k1-3.5.0.tgz", + "integrity": "sha512-e5QIJl8W7Y4tT6LHffVcZAxJjvpgE5Owawv6/XCYPQljE9aP2NFFddQ8OYMKhdLshNu88FfL3qCN3/xYkXGRsA==", "requires": { "bindings": "1.3.0", "bip66": "1.1.5", @@ -9232,14 +9158,6 @@ "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=" }, - "strip-hex-prefix": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/strip-hex-prefix/-/strip-hex-prefix-1.0.0.tgz", - "integrity": "sha1-DF8VX+8RUTczd96du1iNoFUA428=", - "requires": { - "is-hex-prefixed": "1.0.0" - } - }, "strip-json-comments": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", diff --git a/package.json b/package.json index a20419d..7108bf1 100644 --- a/package.json +++ b/package.json @@ -12,12 +12,13 @@ "cross-env": "^5.0.5", "css-loader": "^0.28.7", "downloadjs": "^1.4.7", - "ethereumjs-util": "^5.1.2", "file-loader": "^1.1.6", + "keccak": "^1.4.0", "node-sass": "^4.5.3", "randombytes": "^2.0.6", "remodal": "^1.1.1", "sass-loader": "^6.0.6", + "secp256k1": "^3.5.0", "url-loader": "^0.6.2", "uuid": "^3.2.1", "vue": "^2.5.11", diff --git a/src/js/vanity.js b/src/js/vanity.js index 935215f..47a2519 100644 --- a/src/js/vanity.js +++ b/src/js/vanity.js @@ -1,10 +1,18 @@ /* eslint-env worker */ - -const ethUtils = require('ethereumjs-util'); +const secp256k1 = require('secp256k1'); +const keccak = require('keccak'); const randomBytes = require('randombytes'); const step = 500; +/** + * Transform a private key into an address + */ +const privateToAddress = privateKey => { + const pub = secp256k1.publicKeyCreate(privateKey, false).slice(1); + return keccak('keccak256').update(pub).digest().slice(-20).toString('hex'); +}; + /** * Create a wallet from a random private key * @returns {{address: string, privKey: string}} @@ -12,28 +20,27 @@ const step = 500; const getRandomWallet = () => { const randbytes = randomBytes(32); return { - address: '0x' + ethUtils.privateToAddress(randbytes).toString('hex'), + address: privateToAddress(randbytes).toString('hex'), privKey: randbytes.toString('hex') }; }; /** * Check if a wallet respects the input constraints - * @param wallet + * @param address * @param input * @param isChecksum * @returns {boolean} */ -const isValidVanityWallet = (wallet, input, isChecksum) => { +const isValidVanityAddress = (address, input, isChecksum) => { if (!isChecksum) { - return input === wallet.address.substr(2, input.length); + return input === address.substr(0, input.length); } - if (input.toLowerCase() !== wallet.address.substr(2, input.length)) { + if (input.toLowerCase() !== address.substr(0, input.length)) { return false; } - const address = wallet.address.substr(2); - const hash = ethUtils.sha3(address).toString('hex'); + const hash = keccak('keccak256').update(address).digest().toString('hex'); for (let i = 0; i < input.length; i++) { if (input[i] !== (parseInt(hash[i], 16) >= 8 ? address[i].toUpperCase() : address[i])) { @@ -43,6 +50,15 @@ const isValidVanityWallet = (wallet, input, isChecksum) => { return true; }; +const toChecksumAddress = address => { + const hash = keccak('keccak256').update(address).digest().toString('hex'); + let ret = ''; + for (let i = 0; i < address.length; i++) { + ret += parseInt(hash[i], 16) >= 8 ? address[i].toUpperCase() : address[i]; + } + return ret; +}; + /** * Generate a lot of wallets until one satisfies the input constraints * @param input @@ -55,7 +71,7 @@ const getVanityWallet = (input, isChecksum, cb) => { let wallet = getRandomWallet(); let attempts = 1; - while (!isValidVanityWallet(wallet, input, isChecksum)) { + while (!isValidVanityAddress(wallet.address, input, isChecksum)) { if (attempts >= step) { cb({attempts}); attempts = 0; @@ -63,7 +79,7 @@ const getVanityWallet = (input, isChecksum, cb) => { wallet = getRandomWallet(); attempts++; } - cb({address: ethUtils.toChecksumAddress(wallet.address), privKey: wallet.privKey, attempts}); + cb({address: '0x' + toChecksumAddress(wallet.address), privKey: wallet.privKey, attempts}); }; onmessage = function (event) {