1
0
mirror of https://github.com/bitcoinbook/bitcoinbook synced 2024-12-30 18:30:56 +00:00
bitcoinbook/code/vanity-miner.cpp
Arthur O'Dwyer 9504d804e0 Stop using numeric_limits for the constant "255", and fix a bug.
The bug is that `x % 255` is not quite the same thing as `x % 256`;
but `x & 255` is.

The stylistic issue is that `numeric_limits<uint8_t>::max()` is a
very verbose way of spelling `255`.
2018-03-25 20:17:35 -07:00

74 lines
2.2 KiB
C++

#include <random>
#include <bitcoin/bitcoin.hpp>
// The string we are searching for
const std::string search = "1kid";
// Generate a random secret key. A random 32 bytes.
bc::ec_secret random_secret(std::default_random_engine& engine);
// Extract the Bitcoin address from an EC secret.
std::string bitcoin_address(const bc::ec_secret& secret);
// Case insensitive comparison with the search string.
bool match_found(const std::string& address);
int main()
{
// random_device on Linux uses "/dev/urandom"
// CAUTION: Depending on implementation this RNG may not be secure enough!
// Do not use vanity keys generated by this example in production
std::random_device random;
std::default_random_engine engine(random());
// Loop continuously...
while (true)
{
// Generate a random secret.
bc::ec_secret secret = random_secret(engine);
// Get the address.
std::string address = bitcoin_address(secret);
// Does it match our search string? (1kid)
if (match_found(address))
{
// Success!
std::cout << "Found vanity address! " << address << std::endl;
std::cout << "Secret: " << bc::encode_base16(secret) << std::endl;
return 0;
}
}
// Should never reach here!
return 0;
}
bc::ec_secret random_secret(std::default_random_engine& engine)
{
// Create new secret...
bc::ec_secret secret;
// Iterate through every byte setting a random value...
for (uint8_t& byte: secret)
byte = engine() & 255;
// Return result.
return secret;
}
std::string bitcoin_address(const bc::ec_secret& secret)
{
// Convert secret to payment address
bc::wallet::ec_private private_key(secret);
bc::wallet::payment_address payaddr(private_key);
// Return encoded form.
return payaddr.encoded();
}
bool match_found(const std::string& address)
{
auto addr_it = address.begin();
// Loop through the search string comparing it to the lower case
// character of the supplied address.
for (auto it = search.begin(); it != search.end(); ++it, ++addr_it)
if (*it != std::tolower(*addr_it))
return false;
// Reached end of search string, so address matches.
return true;
}