Comment créer une adresse de portefeuille Ethereum à partir d'une clé privée

Dans le premier article de cette série, nous avons généré une clé privée bitcoin: 60cf347dbc59d31c1358c8e5cf5e45b822ab85b79cb32a9f3d98184779a9efc2.

Ici, nous allons utiliser cette clé pour obtenir l’adresse publique, puis l’adresse de portefeuille Ethereum de cette clé privée.

Créer l'adresse du portefeuille Bitcoin à partir de la clé privée est un peu compliqué. Ici, le processus sera beaucoup plus simple. Nous devons appliquer une fonction de hachage pour obtenir la clé publique et une autre pour obtenir l'adresse.

Alors, commençons.

Clé publique

Cette partie est presque identique à celle décrite dans l'article Bitcoin. Si vous la lisez, vous pouvez la sauter (sauf si vous avez besoin d'un rappel).

La première chose à faire est d’appliquer l’ECDSA, ou l’algorithme de signature numérique à courbe elliptique, à notre clé privée. Une courbe elliptique est une courbe définie par l'équation y² = x³ + ax + b avec a et b choisis. Il existe toute une famille de courbes de ce type largement connues et utilisées. Bitcoin utilise la courbe secp256k1. Si vous souhaitez en savoir plus sur la cryptographie à courbe elliptique, je vous renvoie à cet article.

Ethereum utilise la même courbe elliptique, secp256k1, de sorte que le processus d'obtention de la clé publique est identique dans les deux monnaies cryptées.

En appliquant l'ECDSA à la clé privée, nous obtenons un entier de 64 octets, soit deux entiers de 32 octets qui représentent X et Y du point de la courbe elliptique, concaténés ensemble.

Pour notre exemple, nous avons: 1e7bcc70c72770dbb72fea022e8a6d07f814d2ebe4de9ae3f7af75bf706902a7b73ff919898c836396a6b0c96812c3213b9937bd9978857db78787d

En Python, cela ressemblerait à ceci:

private_key_bytes = codecs.decode (clé privée, "hex")
# Obtenir la clé publique ECDSA
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')

Remarque: comme vous pouvez le voir dans le code ci-dessus, j'ai utilisé une méthode du module ecdsa et j'ai décodé la clé privée à l'aide de codecs. Ceci est plus pertinent pour le Python et moins pour l'algorithme lui-même, mais je vais expliquer ce que nous faisons ici pour éliminer toute confusion possible.

En Python, au moins deux classes peuvent conserver les clés privée et publique: «str» et «octets». Le premier est une chaîne et le second est un tableau d'octets. Les méthodes cryptographiques en Python fonctionnent avec une classe «octets», la prenant comme entrée et la retournant comme résultat.

Maintenant, il ya un petit problème: une chaîne, disons, 4f3c ne correspond pas au tableau d’octets 4f3c. Au contraire, il est égal au tableau d'octets avec deux éléments, O <. Et c’est ce que fait la méthode codecs.decode: elle convertit une chaîne en tableau d’octets. Ce sera la même chose pour toutes les manipulations cryptographiques que nous allons faire dans cet article.

Adresse du portefeuille

Une fois la clé publique obtenue, nous pouvons calculer l’adresse. Aujourd'hui, contrairement à Bitcoin, Ethereum possède les mêmes adresses sur le réseau principal et sur tous les réseaux de test. Les utilisateurs spécifient le réseau qu'ils souhaitent utiliser plus tard dans le processus lorsqu'ils effectuent et signent une transaction.

Pour créer une adresse à partir de la clé publique, il suffit d’appliquer Keccak-256 à la clé, puis de prendre les 20 derniers octets du résultat. Et c'est tout. Aucune autre fonction de hachage, pas de base58 ni aucune autre conversion. La seule chose dont vous avez besoin est d’ajouter ‘0x’ au début de l’adresse.

Voici le code 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 ()
# Prendre les 20 derniers octets
wallet_len = 40
wallet = '0x' + keccak_digest [-wallet_len:]

Somme de contrôle

Comme vous vous en souvenez peut-être, Bitcoin crée la somme de contrôle en hachant la clé publique et en prenant les 4 premiers octets du résultat. Ceci est vrai pour toutes les adresses Bitcoin, vous ne pouvez donc pas obtenir l’adresse valide sans ajouter les octets de somme de contrôle.

Dans Ethereum, ce n’est pas comme ça que ça marche. Initialement, aucun mécanisme de somme de contrôle ne permettait de valider l'intégrité de la clé. Cependant, en 2016, Vitalik Buterin a mis en place un mécanisme de somme de contrôle, qui a depuis été adopté par les portefeuilles et les échanges.

L'ajout d'une somme de contrôle à l'adresse du portefeuille Ethereum le rend sensible à la casse.

Tout d’abord, vous devez obtenir le hachage Keccak-256 de l’adresse. Notez que cette adresse doit être transmise à la fonction de hachage sans la partie 0x.

Deuxièmement, vous parcourez les caractères de l'adresse initiale. Si le octet du hachage est supérieur ou égal à 8, vous convertissez le caractère de cette adresse en majuscule, sinon vous le laissez en minuscule.

Enfin, vous rajoutez 0x au début de la chaîne résultante. L’adresse de la somme de contrôle est la même que la première si vous ignorez la casse. Mais les lettres majuscules permettent à quiconque de vérifier que l'adresse est bien valide. Vous pouvez trouver l'algorithme de validation de la somme de contrôle sur la page liée ici.

Comme vous le lirez dans la proposition, pour ce schéma de contrôle,

«En moyenne, il y aura 15 bits de contrôle par adresse, et la probabilité nette qu'une adresse générée aléatoirement, en cas d'erreur de frappe, réussisse accidentellement un contrôle est de 0,0247%.»

Et voici le code pour ajouter une somme de contrôle à l’adresse Ethereum:

somme de contrôle = '0x'
# Supprimer ‘0x’ de l’adresse
adresse = adresse [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 ()
pour i dans la plage (len (adresse)):
    address_char = adresse [i]
    keccak_char = keccak_digest [i]
    si int (keccak_char, 16)> = 8:
        somme de contrôle + = address_char.upper ()
    autre:
        somme de contrôle + = str (address_char)

Conclusion

Comme vous pouvez le constater, la création d’une adresse pour Ethereum est beaucoup plus simple que pour Bitcoin. Il suffit d’appliquer l’ECDSA à une clé publique, puis d’appliquer Keccak-256 et de prendre enfin les 20 derniers octets de ce hachage.

Si vous voulez jouer avec le code, je l'ai publié dans le référentiel GitHub.

Je fais un cours sur les crypto-monnaies ici sur Medium. La première partie est une description détaillée de la blockchain.

Je publie également des pensées aléatoires à propos de crypto sur Twitter, alors vous voudrez peut-être y jeter un coup d'œil.