Mastering Bitcoin

Mastering Bitcoin


6. Claves, Direcciones, Carteras » Claves y Direcciones Avanzadas » Direcciones de Vanidad » Generando direcciones de vanidad

Página 40 de 98

Generando direcciones de vanidad

Es importante tener en cuenta que una dirección bitcoin es simplemente un número representado por símbolos en el alfabeto Base58. La búsqueda de un patrón como «1Kids» puede entenderse como la búsqueda de una dirección en el rango de 1Kids11111111111111111111111111111 a 1Kidszzzzzzzzzzzzzzzzzzzzzzzzzzzzz. Hay aproximadamente 5829 (aproximadamente 1,4 * 1051) direcciones en ese rango, todas ellas comenzando por «1Kids». El rango de direcciones de vanidad comenzando con «1Kids» muestra el rango de direcciones que tienen el prefijo 1Kids.

Tabla 11. El rango de direcciones de vanidad comenzando con «1Kids»

Desde

1Kids11111111111111111111111111111

1Kids11111111111111111111111111112

1Kids11111111111111111111111111113

Hasta

1Kidszzzzzzzzzzzzzzzzzzzzzzzzzzzzz

Veamos el patrón «1Kids» como un número y la frecuencia con la que podríamos encontrar este patrón en una dirección bitcoin (ver La frecuencia del patrón de vanidad (1KidsCharity) y el tiempo de búsqueda promedio en una PC de escritorio). De promedio, un ordenador de sobremesa sin ningún hardware especializado puede buscar aproximadamente 100.000 claves por segundo.

Tabla 12. La frecuencia del patrón de vanidad (1KidsCharity) y el tiempo de búsqueda promedio en una PC de escritorio

Como se puede ver, Eugenia no podrá crear la dirección de vanidad «1KidsCharity» en el corto plazo, incluso si ella tuviese acceso a varios miles de ordenadores. Cada carácter adicional aumenta la dificultad en un factor de 58. Los patrones con más de siete caracteres se encuentran generalmente con hardware especializado, tales como escritorios hechos a medida con múltiples unidades de procesamiento de gráficos (GPU). Estos son a menudo reutilizados por «plataformas» mineras de bitcoin que ya no son rentables para la minería bitcoin, pero que se pueden utilizar para encontrar direcciones de vanidad. Las búsquedas de vanidad sobre sistemas de GPU son varios órdenes de magnitud más rápidas que las de una CPU de propósito general.

Otra manera de encontrar una dirección de vanidad es la de subcontratar el trabajo a un grupo de mineros de vanidad, como en el pool Vanity pool. Un pool es un servicio que permite ganar bitcoin a las personas con hardware de GPU buscando direcciones de vanidad para los demás. Por un pequeño pago (0,01 bitcoin o aproximadamente $5 en el momento de escribir esto), Eugenia puede externalizar la búsqueda de una dirección con un patrón de vanidad de siete caracteres y obtener resultados en un par de horas en lugar de tener que realizar una búsqueda de CPU durante meses.

Generar una dirección de vanidad es un ejercicio de fuerza bruta: probar una clave aleatoria, comprobar la dirección resultante para ver si coincide con el patrón deseado, repetir hasta que tenga éxito. Minero de direcciones de vanidad muestra un ejemplo de un «minero de vanidad», un programa diseñado para encontrar direcciones de vanidad, escrito en C++. El ejemplo utiliza la biblioteca libbitcoin, que ya se presentó en el capítulo sobre monedas alternativas.

Ejemplo 8. Minero de direcciones de vanidad

#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_hex(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() % std::numeric_limits<uint8_t>::max();

// Return result.

return secret;

}

std::string bitcoin_address(const bc::ec_secret& secret)

{

// Convert secret to pubkey…

bc::ec_point pubkey = bc::secret_to_public_key(secret);

// Finally create address.

bc::payment_address payaddr;

bc::set_public_key(payaddr, pubkey);

// 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;

}

El ejemplo anterior usa std::random_device. Dependiendo de la implementación puede reflejar un generador de números aleatorios criptográficamente seguro (CSRNG) proporcionado por el sistema operativo subyacente. En el caso de los sistemas operativos basados en UNIX, como Linux, se nutre de /dev/urandom. El generador de números aleatorios utilizado aquí es para fines de demostración y no es apropiado para generar claves Bitcoin de calidad de producción, ya que no está implementado con la suficiente seguridad.

El código de ejemplo debe ser compilado usando un compilador de C y enlazado con la biblioteca libbitcoin (que debe ser instalado por primera vez en ese sistema). Para ejecutar el ejemplo, lance el ejecutable de vanity-miner sin parámetros (ver Compilando y ejecutando el ejemplo de vanity-miner) e intentará encontrar una dirección de vanidad que empiece por «1kid».

Ejemplo 9. Compilando y ejecutando el ejemplo de vanity-miner

$ # Compilar el código con g++

$ g++ -o vanity-miner vanity-miner.cpp $(pkg-config --cflags --libs libbitcoin) $ # Ejecutar el ejemplo

$ ./vanity-miner

Found vanity address! 1KiDzkG4MxmovZryZRj8tK81oQRhbZ46YT

Secret: 57cc268a05f83a23ac9d930bc8565bac4e277055f4794cbd1a39e5e71c038f3f $ # Ejecutarlo otra vez para obtener un resultado distinto

$ ./vanity-miner

Found vanity address! 1Kidxr3wsmMzzouwXibKfwTYs5Pau8TUFn

Secret: 7f65bbbbe6d8caae74a0c6a0d2d7b5c6663d71b60337299a1a2cf34c04b2a623

# Usar "time" para ver cuánto tarda en encontrar un resultado $ time ./vanity-miner

Found vanity address! 1KidPWhKgGRQWD5PP5TAnGfDyfWp5yceXM

Secret: 2a802e7a53d8aa237cd059377b616d2bfcfa4b0140bc85fa008f2d3d4b225349

real 0m8.868s

user 0m8.828s

sys 0m0.035s

El código de ejemplo tardará unos segundos en encontrar una coincidencia para el patrón de tres caracteres «kid», como podemos ver cuando usamos el comando time de Unix para medir el tiempo de ejecución. Cambie el patrón de búsqueda en el apartado search del código fuente y ¡vea cuánto tiempo más se tarda entre un patrón de cuatro caracteres y otro de cinco!

Ir a la siguiente página

Report Page