Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow both prefix & suffix #57

Merged
merged 1 commit into from
Jun 26, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 9 additions & 8 deletions src/App.vue
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,8 @@
<!--Statistics-->
<div class="col-md-6">
<statistics
:hex="input.hex"
:prefix="input.prefix"
:suffix="input.suffix"
:checksum="input.checksum"
:status="status"
:first-tick="firstTick"
Expand Down Expand Up @@ -83,7 +84,7 @@
threads: 4,
cores: 0,
result: { address: '', privateKey: '' },
input: { hex: '', checksum: true, suffix: false },
input: { prefix: '', suffix: '', checksum: true },
firstTick: null,
error: null,
};
Expand All @@ -99,15 +100,15 @@
setInput: function (inputType, value) {
// eslint-disable-next-line default-case
switch (inputType) {
case 'hex':
this.input.hex = value;
break;
case 'checksum':
this.input.checksum = value;
case 'prefix':
this.input.prefix = value;
break;
case 'suffix':
this.input.suffix = value;
break;
case 'checksum':
this.input.checksum = value;
break;
case 'threads':
this.threads = value;
}
Expand Down Expand Up @@ -256,7 +257,7 @@
worker.terminate();
}
};
const input = { checksum: true, hex: 'f'.repeat(5), suffix: false };
const input = { checksum: true, prefix: 'f'.repeat(5), suffix: '' };
console.info('Starting benchmark with 1 core...');
worker.postMessage(input);
},
Expand Down
49 changes: 29 additions & 20 deletions src/js/vanity.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,35 +27,42 @@ const getRandomWallet = () => {

/**
* Check if a wallet respects the input constraints
* @param address
* @param input
* @param isChecksum
* @param isSuffix
* @param address - Wallet address
* @param prefix - Prefix chosen by the user
* @param suffix - Suffix chosen by the user
* @param isChecksum - Is the input case-sensitive
* @returns {boolean}
*/
const isValidVanityAddress = (address, input, isChecksum, isSuffix) => {
const subStr = isSuffix ? address.substr(40 - input.length) : address.substr(0, input.length);
const isValidVanityAddress = (address, prefix, suffix, isChecksum) => {
const addressPrefix = address.substring(0, prefix.length);
const addressSuffix = address.substring(40 - suffix.length);

if (!isChecksum) {
return input === subStr;
return prefix === addressPrefix && suffix === addressSuffix;
}
if (input.toLowerCase() !== subStr) {
if (prefix.toLowerCase() !== addressPrefix || suffix.toLowerCase() !== addressSuffix) {
return false;
}

return isValidChecksum(address, input, isSuffix);
return isValidChecksum(address, prefix, suffix);
};

const isValidChecksum = (address, input, isSuffix) => {
const isValidChecksum = (address, prefix, suffix) => {
const hash = keccak('keccak256').update(address).digest().toString('hex');
const shift = isSuffix ? 40 - input.length : 0;

for (let i = 0; i < input.length; i++) {
const j = i + shift;
if (input[i] !== (parseInt(hash[j], 16) >= 8 ? address[j].toUpperCase() : address[j])) {
for (let i = 0; i < prefix.length; i++) {
if (prefix[i] !== (parseInt(hash[i], 16) >= 8 ? address[i].toUpperCase() : address[i])) {
return false;
}
}

for (let i = 0; i < suffix.length; i++) {
const j = i + 40 - suffix.length;
if (suffix[i] !== (parseInt(hash[j], 16) >= 8 ? address[j].toUpperCase() : address[j])) {
return false;
}
}

return true;
};

Expand All @@ -70,18 +77,20 @@ const toChecksumAddress = (address) => {

/**
* Generate a lot of wallets until one satisfies the input constraints
* @param input - String chosen by the user
* @param prefix - Prefix chosen by the user
* @param suffix - Suffix chosen by the user
* @param isChecksum - Is the input case-sensitive
* @param isSuffix - Is it a suffix, or a prefix
* @param cb - Callback called after x attempts, or when an address if found
* @returns
*/
const getVanityWallet = (input, isChecksum, isSuffix, cb) => {
input = isChecksum ? input : input.toLowerCase();
const getVanityWallet = (prefix, suffix, isChecksum, cb) => {
let wallet = getRandomWallet();
let attempts = 1;

while (!isValidVanityAddress(wallet.address, input, isChecksum, isSuffix)) {
const pre = isChecksum ? prefix : prefix.toLowerCase();
const suf = isChecksum ? suffix : suffix.toLowerCase();

while (!isValidVanityAddress(wallet.address, pre, suf, isChecksum)) {
if (attempts >= step) {
cb({ attempts });
attempts = 0;
Expand All @@ -95,7 +104,7 @@ const getVanityWallet = (input, isChecksum, isSuffix, cb) => {
onmessage = function (event) {
const input = event.data;
try {
getVanityWallet(input.hex, input.checksum, input.suffix, (message) => postMessage(message));
getVanityWallet(input.prefix, input.suffix, input.checksum, (message) => postMessage(message));
} catch (err) {
self.postMessage({ error: err.toString() });
}
Expand Down
105 changes: 58 additions & 47 deletions src/vue/Input.vue
Original file line number Diff line number Diff line change
@@ -1,15 +1,32 @@
<template>
<div class="panel" id="input-panel">
<form :class="{ error: inputError }" @submit.prevent="startGen">
<div class="error-text">Numbers and letters from A to F only</div>
<input
type="text"
class="text-input-large"
id="input"
:placeholder="suffix ? 'Suffix' : 'Prefix'"
v-model="hex"
:disabled="running"
/>
<form @submit.prevent="startGen">
<div class="error-text" v-if="inputError">Numbers and letters from A to F only</div>

<div class="row">
<div class="col-12 col-sm-6 col-md-12 col-lg-6">
<input
:class="{ error: prefixError }"
type="text"
class="text-input-large"
id="input"
placeholder="Prefix"
v-model="prefix"
:disabled="running"
/>
</div>
<div class="col-12 col-sm-6 col-md-12 col-lg-6">
<input
:class="{ error: suffixError }"
type="text"
class="text-input-large"
id="input"
placeholder="Suffix"
v-model="suffix"
:disabled="running"
/>
</div>
</div>
<div class="row justify-content-center hide-render">
<div class="spinner">
<div></div>
Expand All @@ -20,31 +37,22 @@
</div>
<div class="example hide-prerender">
E.g.&nbsp;
<span class="monospace">
<span v-if="inputError" class="monospace">N/A</span>
<span v-else class="monospace">
0x<!--
--><b v-if="!suffix" v-text="example.chosen"></b
--><b v-if="example.prefix" v-text="example.prefix"></b
><!--
--><span v-text="example.random"></span
><!--
--><b v-if="suffix" v-text="example.chosen"></b>
--><b v-if="example.suffix" v-text="example.suffix"></b>
</span>
</div>
<div class="row controls hide-prerender">
<div class="col-12 col-sm-6 col-md-12 col-lg-6">
<label class="checkbox">
<input type="checkbox" name="checkbox" checked="" v-model="checksum" :disabled="running" />
<i class="left"> </i>
Case-sensitive
</label>
</div>
<div class="col-12 col-sm-6 col-md-12 col-lg-6">
<span>Prefix</span>
<label class="switch">
<input type="checkbox" v-model="suffix" :disabled="running" />
<span class="slider"></span>
</label>
<span>Suffix</span>
</div>
<div class="controls hide-prerender">
<label class="checkbox">
<input type="checkbox" name="checkbox" checked="" v-model="checksum" :disabled="running" />
<i class="left"> </i>
Case-sensitive
</label>
</div>
<div class="threads hide-prerender">
<input
Expand Down Expand Up @@ -105,26 +113,33 @@
data: function () {
return {
threads: this.$props.cores || 4,
hex: '',
prefix: '',
suffix: '',
checksum: true,
suffix: false,
error: false,
};
},
computed: {
prefixError: function () {
return !isValidHex(this.prefix);
},
suffixError: function () {
return !isValidHex(this.suffix);
},
inputError: function () {
return !isValidHex(this.hex);
return this.prefixError || this.suffixError;
},
example: function () {
if (this.inputError) {
return 'N/A';
return null;
}
const chosen = this.checksum ? this.hex : mixCase(this.hex);
const prefix = this.checksum ? this.prefix : mixCase(this.prefix);
const suffix = this.checksum ? this.suffix : mixCase(this.suffix);
let random = '';
for (let i = 0; i < 40 - this.hex.length; i++) {
for (let i = 0; i < 40 - this.prefix.length - this.suffix.length; i++) {
random += mixCase(Math.floor(Math.random() * 16).toString(16));
}
return { random, chosen };
return { random, prefix, suffix };
},
},
methods: {
Expand All @@ -138,15 +153,15 @@
},
},
watch: {
hex: function () {
this.$emit('input-change', 'hex', this.hex);
},
checksum: function () {
this.$emit('input-change', 'checksum', this.checksum);
prefix: function () {
this.$emit('input-change', 'prefix', this.prefix);
},
suffix: function () {
this.$emit('input-change', 'suffix', this.suffix);
},
checksum: function () {
this.$emit('input-change', 'checksum', this.checksum);
},
threads: function () {
this.$emit('input-change', 'threads', this.threads);
},
Expand All @@ -160,15 +175,11 @@
min-height: 280px

.error-text
display: none
font-size: 14px
color: $error

.error
input[type="text"]
border: 1px solid $error
.error-text
display: block
input.error
border: 1px solid $error

.example
font-size: 14px
Expand Down
6 changes: 5 additions & 1 deletion src/vue/Result.vue
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
</div>
<div class="col-lg-2 col-12">
<button data-remodal-target="modal" class="save button-large" :disabled="!privateKey">
<i class="icon-lock"></i>&nbsp;&nbsp;&nbsp;Save
<i class="icon-lock"></i>Save
</button>
</div>
</div>
Expand Down Expand Up @@ -74,6 +74,10 @@

.save
margin-top: 30px
i
margin-right: 8px
top: 2px
position: relative

@media screen and (min-width: 992px)
.save
Expand Down
1 change: 1 addition & 0 deletions src/vue/Save.vue
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,7 @@
margin-bottom: 45px
.remodal-close
outline: none
margin: 8px
&:before
font-size: 2em
&:hover
Expand Down
15 changes: 10 additions & 5 deletions src/vue/Statistics.vue
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,8 @@
<script>
import humanizeDuration from 'humanize-duration';

const computeDifficulty = function (pattern, isChecksum) {
const computeDifficulty = function (prefix, suffix, isChecksum) {
const pattern = prefix + suffix;
const ret = Math.pow(16, pattern.length);
return isChecksum ? ret * Math.pow(2, pattern.replace(/[^a-f]/gi, '').length) : ret;
};
Expand All @@ -46,13 +47,17 @@
};
},
props: {
hex: String,
prefix: String,
suffix: String,
checksum: Boolean,
status: String,
firstTick: {},
},
watch: {
hex() {
prefix() {
this.count = 0;
},
suffix() {
this.count = 0;
},
checksum() {
Expand All @@ -61,10 +66,10 @@
},
computed: {
inputError: function () {
return !isValidHex(this.hex);
return !isValidHex(this.prefix) || !isValidHex(this.suffix);
},
difficulty: function () {
return this.inputError ? 'N/A' : computeDifficulty(this.hex, this.checksum);
return this.inputError ? 'N/A' : computeDifficulty(this.prefix, this.suffix, this.checksum);
},
probability50() {
return this.inputError ? 0 : Math.floor(Math.log(0.5) / Math.log(1 - 1 / this.difficulty));
Expand Down