Cómo crear una dirección de billetera Ethereum a partir de una clave privada

En el primer artículo de esta serie, hemos generado una clave privada Bitcoin: 60cf347dbc59d31c1358c8e5cf5e45b822ab85b79cb32a9f3d98184779a9efc2.

Aquí, usaremos esa clave para obtener la dirección pública y luego la dirección de la billetera Ethereum de esa clave privada.

Crear la dirección de la billetera de Bitcoin a partir de la clave privada es un poco complicado. Aquí, el proceso será mucho más sencillo. Necesitamos aplicar una función hash para obtener la clave pública y otra para obtener la dirección.

Entonces empecemos.

Llave pública

Esta parte es casi idéntica a lo que discutimos en el artículo de Bitcoin, por lo que si la lee, puede omitirla (a menos que necesite un repaso).

Lo primero que debemos hacer es aplicar el ECDSA, o el algoritmo de firma digital de curva elíptica, a nuestra clave privada. Una curva elíptica es una curva definida por la ecuación y² = x³ + ax + bcon ay elegido b. Existe toda una familia de tales curvas que son ampliamente conocidas y utilizadas. Bitcoin usa la curva secp256k1 . Si desea obtener más información sobre la criptografía de curva elíptica, lo referiré a este artículo.

Ethereum usa la misma curva elíptica, secp256k1 , por lo que el proceso para obtener la clave pública es idéntico en ambas criptomonedas.

Al aplicar ECDSA a la clave privada, obtenemos un entero de 64 bytes, que son dos enteros de 32 bytes que representan X e Y del punto en la curva elíptica, concatenados juntos.

Para nuestro ejemplo, tenemos 1e7bcc70c72770dbb72fea022e8a6d07f814d2ebe4de9ae3f7af75bf706902a7b73ff919898c836396a6b0c96812c3213b99372050853bd1678da0ead14487d7.

En Python, se vería así:

private_key_bytes = codecs.decode(private_key, ‘hex’) # Get ECDSA public key key = ecdsa.SigningKey.from_string(private_key_bytes, curve=ecdsa.SECP256k1).verifying_key key_bytes = key.to_string() key_hex = codecs.encode(key_bytes, ‘hex’)

Nota: como puede ver en el código anterior, utilicé un método del ecdsamódulo y decodifiqué la clave privada usando codecs. Esto es más relevante para Python y menos para el algoritmo en sí, pero explicaré qué estamos haciendo aquí para eliminar posibles confusiones.

En Python, hay al menos dos clases que pueden mantener las claves públicas y privadas: "str" ​​y "bytes". El primero es una cadena y el segundo es una matriz de bytes. Los métodos criptográficos en Python funcionan con una clase de "bytes", tomándola como entrada y devolviéndola como resultado.

Ahora, hay una pequeña trampa: una cadena, digamos, 4f3cno es igual a la matriz de bytes 4f3c. Más bien, es igual a la matriz de bytes con dos elementos, O&lt ;. Y eso es lo he codecs.decque hace el método t ode: convierte una cadena en una matriz de bytes. Esto será igual para todas las manipulaciones criptográficas que haremos en este artículo.

Dirección de billetera

Una vez que obtengamos la clave pública, podemos calcular la dirección. Ahora, a diferencia de Bitcoin, Ethereum tiene las mismas direcciones tanto en la red principal como en todas las redes de prueba. Los usuarios especifican la red que desean utilizar más adelante en el proceso cuando realizan y firman una transacción.

Para hacer una dirección a partir de la clave pública, todo lo que tenemos que hacer es aplicar Keccak-256 a la clave y luego tomar los últimos 20 bytes del resultado. Y eso es. Sin otras funciones hash, sin Base58 o cualquier otra conversión. Lo único que necesita es agregar '0x' al comienzo de la dirección.

Aquí está el código de Python:

public_key_bytes = codecs.decode(public_key, ‘hex’) keccak_hash = keccak.new(digest_bits=256) keccak_hash.update(public_key_bytes) keccak_digest = keccak_hash.hexdigest() # Take the last 20 bytes wallet_len = 40 wallet = ‘0x’ + keccak_digest[-wallet_len:]

Suma de comprobación

Ahora, como recordará, Bitcoin crea la suma de comprobación aplicando un hash a la clave pública y tomando los primeros 4 bytes del resultado. Esto es cierto para todas las direcciones de Bitcoin, por lo que no puede obtener la dirección válida sin agregar los bytes de suma de comprobación.

En Ethereum, no es así como funcionan las cosas. Inicialmente, no existían mecanismos de suma de verificación para validar la integridad de la clave. Sin embargo, en 2016, Vitalik Buterin introdujo un mecanismo de suma de comprobación, que desde entonces ha sido adoptado por carteras y bolsas de valores.

Agregar una suma de verificación a la dirección de la billetera Ethereum hace que se distinga entre mayúsculas y minúsculas.

Primero, necesita obtener el hash Keccak-256 de la dirección. Tenga en cuenta que esta dirección debe pasarse a la función hash sin la 0xparte.

En segundo lugar, itera sobre los caracteres de la dirección inicial. Si el i- ésimo byte del hash es mayor o igual a 8, convierte el carácter de la i- ésima dirección a mayúsculas, de lo contrario lo deja en minúsculas.

Finalmente, 0xvuelve a agregar al comienzo de la cadena resultante. La dirección de la suma de comprobación es la misma que la inicial si ignora el caso. Pero las letras mayúsculas permiten que cualquiera verifique que la dirección sea válida. Puede encontrar el algoritmo de validación de la suma de comprobación en la página vinculada aquí.

Como leerá en la propuesta, para este esquema de suma de comprobación,

"En promedio, habrá 15 bits de verificación por dirección, y la probabilidad neta de que una dirección generada al azar, si se escribe incorrectamente, pase accidentalmente una verificación es del 0.0247%".

Y aquí está el código para agregar la suma de comprobación a la dirección de Ethereum:

checksum = ‘0x’ # Remove ‘0x’ from the address address = address[2:] address_byte_array = address.encode(‘utf-8’) keccak_hash = keccak.new(digest_bits=256) keccak_hash.update(address_byte_array) keccak_digest = keccak_hash.hexdigest() for i in range(len(address)): address_char = address[i] keccak_char = keccak_digest[i] if int(keccak_char, 16) >= 8: checksum += address_char.upper() else: checksum += str(address_char)

Conclusión

Como puede ver, crear una dirección para Ethereum es mucho más simple que para Bitcoin. Todo lo que tenemos que hacer es aplicar ECDSA a la clave pública, luego aplicar Keccak-256 y finalmente tomar los últimos 20 bytes de ese hash.

Si quieres jugar con el código, lo publiqué en el repositorio de GitHub.

Estoy haciendo un curso sobre criptomonedas aquí en freeCodeCamp News. La primera parte es una descripción detallada de la cadena de bloques.

También publico pensamientos aleatorios sobre criptografía en Twitter, por lo que es posible que desee comprobarlo.