Welche Kriterien muss eine gültige Ethereum-Adresse erfüllen? Ist es nur eine Zufallszahl in Hexadezimal? Oder muss es gemäß einigen kryptografischen Algorithmen auf eine bestimmte Weise abgeleitet werden? Welche Algorithmen und Standards werden verwendet, um das Schlüsselpaar zu generieren?
Kürzlich wurde ich auf diesen Artikel aufmerksam, der viel ausführlicher und technischer ist als meine zugänglichere Version unten. Es führt Sie auch durch die Erstellung eines eigenen. Ich kann es nur empfehlen: https://kobl.one/blog/create-full-ethereum-keypair-and-address/
Erstellen Sie einen zufälligen privaten Schlüssel (64 (Hex) Zeichen / 256 Bits / 32 Bytes)
Leiten Sie den öffentlichen Schlüssel von diesem privaten Schlüssel ab (128 (hex) Zeichen / 512 Bits / 64 Bytes)
Leiten Sie die Adresse von diesem öffentlichen Schlüssel ab. (40 (hex) Zeichen / 160 Bit / 20 Byte)
Auch wenn viele Leute die Adresse den öffentlichen Schlüssel nennen, ist dies bei Ethereum eigentlich nicht der Fall. Es gibt einen separaten öffentlichen Schlüssel, der als Mittelsmann fungiert, den Sie nie sehen werden, es sei denn, Sie stöbern in einer JSON-Datei einer Brieftasche vor dem Verkauf.
Der private Schlüssel besteht aus 64 Hexadezimalzeichen. Jede einzelne Zeichenfolge von 64 Hex ist hypothetisch ein privater Ethereum-Schlüssel (siehe Link oben, warum dies nicht ganz genau ist) , der auf ein Konto zugreift. Wenn Sie vorhaben, ein neues Konto zu erstellen, sollten Sie sicherstellen, dass diese mit einem geeigneten RNG ausgestattet sind. Sobald Sie diese Zeichenfolge haben.
Das ist hart und überfordert mich. Es gibt etwas mit Elliptic Curve Digital Signature Algorithm (ECDSA) und so. Aber am Ende haben Sie einen öffentlichen Schlüssel, der 64 Bytes groß ist.
Beginnen Sie mit dem öffentlichen Schlüssel (128 Zeichen / 64 Bytes)
Nehmen Sie den Keccak-256-Hash des öffentlichen Schlüssels. Sie sollten jetzt eine Zeichenfolge mit 64 Zeichen / 32 Bytes haben. (Hinweis: SHA3-256 wurde schließlich zum Standard, aber Ethereum verwendet Keccak)
Nehmen Sie die letzten 40 Zeichen / 20 Bytes dieses öffentlichen Schlüssels (Keccak-256). Oder anders gesagt, lassen Sie die ersten 24 Zeichen / 12 Bytes weg. Diese 40 Zeichen / 20 Bytes sind die Adresse. Wenn 0x vorangestellt wird, wird es 42 Zeichen lang.
Adresse: Eine Ethereum-Adresse repräsentiert ein Konto. Für EOA wird die Adresse als die letzten 20 Bytes des öffentlichen Schlüssels abgeleitet, der das Konto steuert, z. B. `cd2a3d9f938e13cd947ec05abc7fe734df8dd826. Dies ist ein hexadezimales Format (Basis-16-Notation), das häufig explizit durch das Anhängen von 0x an die Adresse angegeben wird. Web3.js und Konsolenfunktionen akzeptieren Adressen mit oder ohne dieses Präfix, aber aus Gründen der Transparenz empfehlen wir ihre Verwendung. Da jedes Byte der Adresse durch 2 Hexadezimalzeichen dargestellt wird, ist eine vorangestellte Adresse 42 Zeichen lang. Mehrere Apps und APIs sollen auch das neue prüfsummenfähige Adressschema implementieren, das in der Mist Ethereum Wallet ab Version 0.5.0 eingeführt wurde. - Homestead-Dokumente
Privater Schlüssel: Eine zufällig ausgewählte positive Ganzzahl (dargestellt als Byte-Array der Länge 32 in Big-Endian-Form) im Bereich [1, secp256k1n − 1]
. - Gelbes Papier
Privater Schlüsselraum:
Hier sind einige Codebeispiele, basierend auf der von Ethereum verwendeten elliptischen Kurve secp256k1, wie andere angemerkt haben, damit der 256-Bit-Schlüssel gültig ist, muss er kleiner sein als der Parameter der Kurve, n
der auch ein 256-Bit-Wert sein kann im Hexadezimalformat geschrieben werden als:0xfffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141
Fehlerüberprüfung:
Verschiedene Bibliotheken erzeugen Fehler, wenn Sie versuchen, ihnen einen privaten Schlüssel zuzuführen, der größer ist als n
, als Fehlerprüfmechanismus (dh Exception: Invalid privkey
) Weitere Informationen finden Sie in dieser verwandten Antwort mit Beispielen .
Verwandte Kurvenparameter:
Wir können den privaten Schlüssel s
als geheimen Exponenten bezeichnen, da dieser Wert die Kurve mit dem Parameter g
(unter Verwendung der Skalarmultiplikation) umschließt, der einen öffentlichen Generatorpunkt bezeichnet, der wie eine universelle Konstante ist, die jeder kennt und verwendet, um generieren ihren öffentlichen Schlüssel aus s
.
Bleibt also g
öffentlich, s
muss aber geheim gehalten werden, damit die Ethereum-Brieftasche sicher bleibt, nachdem Ihre Ethereum-Adresse von Ihrem öffentlichen Schlüssel abgeleitet wurde.
Der öffentliche Schlüssel kann entweder in einem komprimierten Format mit einer Gesamtlänge von 33 Bytes oder unkomprimiert als 64 Bytes dargestellt werden und wird normalerweise durch ein führendes Präfix 0x02 für komprimierte öffentliche Schlüssel gekennzeichnet, aber die Länge der Zeichenfolge ist ein besserer Indikator als das Präfix je nach Schritt und Implementierung auch nicht sichtbar oder vorhanden.
Kryptografisch sichere Schlüsselableitung:
Auch s
hinsichtlich der kryptografischen Sicherheit spielt die gewählte Art eine große Rolle. Mit anderen Worten, es ist nicht ratsam, diesen geheimen Exponenten selbst zu wählen oder sich irgendeine clevere Methode auszudenken, wie Sie es für ein Passwort (auch bekannt als Brain Wallet) tun könnten, da unzählige solcher Methoden seit Jahrzehnten verwendet werden, um Geheimnisse mit verschiedenen Algorithmen zu knacken und Computersoftware, wie sie zum Knacken von Passwörtern verwendet werden.
Daher sollte der geheime Exponent mit einem kryptografisch sicheren Pseudozufallszahlengenerator (CSPRNG) wie der WorldWideWeb Consortium (W3C) Cryptography API ( Offenlegung: Ich bin einer von 12 Mitwirkenden an dieser Spezifikation auf Github ) generiert werden, damit dort Es ist weit weniger wahrscheinlich, dass ein Angreifer diesen Wert vorhersagen könnte, da die zufälligen Bits, aus denen diese Zahl besteht, von verschiedenen Stellen Ihres lokalen Geräts und von Prozessen stammen, die diese Entropiedaten nicht online übertragen (vorausgesetzt, die Software, die Sie verwenden verwenden, ist zusammen mit einem sicheren CSPRNG sicher).
Beispiel Python-Code:
Bei Verwendung von Python 3 gibt es ein CSPRNG in der Secrets-Bibliothek, das so einfach sein kann wie das Ausführen der folgenden Befehle in der Reihenfolge vom IDLE-Interpreter oder einer .py-Datei nach dem Importieren der Secrets-Bibliothek:
secrets.randbits(256)
Der obige Befehl erzeugt eine 256-Bit-Binärzahl, die als privater Schlüssel verwendet werden kann, wenn sie kleiner als der Wert von n
ist, aber sie muss als Bytes-Objekt im Python-Implementierungsbeispiel unten formatiert werden, indem die eth-keys
Bibliothek aus der verwendet wird Ethereum Foundation Github-Repository (Das folgende Beispiel erfordert möglicherweise die Installation der sha3
Bibliothek ( pip install pysha3 ), die Keccak enthält, falls nicht in der Standardbibliothek vorhanden hashlib
):
import secrets
import sha3
import eth_keys
from eth_keys import keys
private_key = str(hex(secrets.randbits(256))[2:])
private_key_bytes = bytes.fromhex(private_key)
public_key_hex = keys.PrivateKey(private_key_bytes).public_key
public_key_bytes = bytes.fromhex(str(public_key_hex)[2:])
Keccak256_of_public_key_bytes = sha3.keccak_256(public_key_bytes).hexdigest()
public_address = keys.PublicKey(public_key_bytes).to_address()
print('\n Private_key:',private_key,
'\n Private_key_bytes:',private_key_bytes,
'\n Public_key_hex:',public_key_hex,
'\n Public_key_bytes:',public_key_bytes,
'\n Full_Keccak_digest:',Keccak256_of_public_key_bytes,
'\n Ethereum address:',public_address)
Beispielausgabe des obigen Codes (nicht im Hauptnetz zu verwenden, nur zum Beispiel)
Private_key: 7231bfb75a41481965e391fb6d4406b6c356d20194c5a88935151f05136d2f2e
Private_key_bytes: b'r1\xbf\xb7ZAH\x19e\xe3\x91\xfbmD\x06\xb6\xc3V\xd2\x01\x94\xc5\xa8\x895\x15\x1f\x05\x13m/.'
Public_key_hex: 0x013e81c4a44c5303b11452f649be9427b75605339d8eba90f8e99cc401a8bd4f7494e0d0740bcc0282af75f9bd4571ed493a05ed02f1b968a45a46f4d77be149
Public_key_bytes: b"\x01>\x81\xc4\xa4LS\x03\xb1\x14R\xf6I\xbe\x94'\xb7V\x053\x9d\x8e\xba\x90\xf8\xe9\x9c\xc4\x01\xa8\xbdOt\x94\xe0\xd0t\x0b\xcc\x02\x82\xafu\xf9\xbdEq\xedI:\x05\xed\x02\xf1\xb9h\xa4ZF\xf4\xd7{\xe1I"
Full_Keccak_digest: 3f54dd68163875b594cfdc8e8a2250aafb31638b19a83caa49d1ee61089dcb4b
Ethereum address: 0x8a2250aafb31638b19a83caa49d1ee61089dcb4b
Sechs Schritte vom privaten Schlüssel zur Ethereum-Adresse
Wie in der obigen Implementierung, die ich geschrieben habe, zu sehen ist, können die sechs Schritte vom privaten Schlüssel zur Ethereum-Adresse wie folgt zusammengefasst werden:
Alternative Abhängigkeiten:
Zusätzlich zu der Open-SSL-Bibliothek , auf die in dem Artikel verwiesen wird, auf den @tayvano hingewiesen hat, umfassen andere Bibliotheken, die zur Berechnung öffentlicher Adressen von elliptischen Kurven verwendet werden können, die ecdsa-Python-Bibliothek und die in C geschriebene secp256k1-Bibliothek von Bitcoin, obwohl letztere Tools zur Formatierung enthalten wird Bitcoin-Adressen, die sich aufgrund der Formatierungsschritte und unterschiedlichen Hash-Algorithmen und Codierungsmethoden völlig von Ethereum-Adressen unterscheiden, auch wenn der zugrunde liegende private Schlüssel und der öffentliche Schlüssel zum Beispiel gleich sind.
Hinweis: Schließlich ist es wichtig, Tests durchzuführen, um sicherzustellen, dass eine generierte Adresse nicht nur gültig ist, sondern dass der zugrunde liegende private Schlüssel, der im Prozess verwendet wird, zum Signieren von Transaktionen gültig ist (dh wenn ein Benutzer einen Hash-Digest der Byte-Array, das als String statt als Bytes-Objekt behandelt wird, was zu einem falschen Hash-Digest und damit zu einer falschen Adresse für den zugrunde liegenden Schlüssel führt).
Beispiel : Ein solches Tool zur Adressüberprüfung (Prüfsumme) aus der eth-keys-Bibliothek ist der folgende Befehl: keys.PublicKey().to_checksum_address()
der die Bytes des öffentlichen Schlüssels verwendet (dh die Übergabe der Variablen in die erste Klammer würde im obigen Programm sicher public_key_bytes
so aussehen keys.PublicKey(public_key_bytes).to_checksum_address()
berechnete Adresse ist korrekt). Aus diesem Grund kann die Verwendung vorhandener Bibliotheken sicherer sein, als den Code von Grund auf neu zu schreiben.
PS Antworten und Beispiele sollen nicht alle Risiken/Schritte erschöpfend darstellen.
n
finden Sie unter: eips.ethereum.org/EIPS/eip-1271 : „Wenn Ihre Bibliothek formbare Signaturen generiert, wie z. B. s
-Werte im oberen Bereich, berechnen Sie einen neuen S-Wert mit 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1
und wechseln Sie v
von 27
zu 28
oder umgekehrt. Wenn Ihre Bibliothek auch Signaturen mit 0
/ 1
für v
statt 27
/ generiert 28
, fügen Sie 27
zu hinzu v
, um diese formbaren Signaturen ebenfalls zu akzeptieren."Ethereum-Adressen sind Hashes eines öffentlichen Schlüssels. Um einen zu generieren, müssen Sie also zuerst einen privaten Schlüssel generieren (siehe: Was ist der Ansatz, um eine Ethereum-Adresse aus einem 256-Bit-Private-Key zu berechnen? ) Der private Schlüssel ist zufällig, aber der öffentliche Schlüssel und damit sein Hash wird als Adresse verwendet nicht zufällig.
Um eine Adresse zu überprüfen und somit das Format zu kennen, siehe Wie kann ich überprüfen, ob eine Ethereum-Adresse gültig ist?
Falls jemand nach einer JS-Lösung sucht:
const Web3 = require('web3')
const web3 = new Web3()
const elliptic = require('elliptic')
const ec = new elliptic.ec('secp256k1')
function pubKeyToAddress(compressedPubkey) {
let keyPair = ec.keyFromPublic(compressedPubkey, 'hex')
// remove '04' then add prefix '0x'
let pubkey = '0x' + keyPair.getPublic(false, 'hex').substr(2)
let address = trimFirst12Bytes(web3.utils.keccak256(pubkey))
return web3.utils.toChecksumAddress(address)
}
unction trimFirst12Bytes(hexString) {
return '0x'.concat(hexString.substr(hexString.length - 40))
}
Hier ist ein Python-Paket, das in PyPI gehostet wird: eth_address_dump
Eth-Adresse aus privatem Schlüssel ausgeben:
$ echo "0x6ee825aafad19a0d759e1e0ba61d0c523b7b23038998a92d7904458b91667105" | eth_address_dump
private_key = 0x6ee825aafad19a0d759e1e0ba61d0c523b7b23038998a92d7904458b91667105
public_key = 0xaa3e0b3f86053c2aaa08d6f6398e18f76100e0d675680228b000c252e4393e9fe85fc162e43d721533736d79c102139d3035d2d9251ccf809bc5bddb81cc6563
compressed_public_key = 0x03aa3e0b3f86053c2aaa08d6f6398e18f76100e0d675680228b000c252e4393e9f
address = 0xF7dcf60AebA077461862d51b77d6d804C06E0073
Eth-Adresse aus mnemonischen Wörtern ausgeben:
$ echo "olympic wine chicken argue unaware bundle tunnel grid spider slot spell need" | eth_address_dump
mnemonic = olympic wine chicken argue unaware bundle tunnel grid spider slot spell need
private_key = 0x6ee825aafad19a0d759e1e0ba61d0c523b7b23038998a92d7904458b91667105
public_key = 0xaa3e0b3f86053c2aaa08d6f6398e18f76100e0d675680228b000c252e4393e9fe85fc162e43d721533736d79c102139d3035d2d9251ccf809bc5bddb81cc6563
compressed_public_key = 0x03aa3e0b3f86053c2aaa08d6f6398e18f76100e0d675680228b000c252e4393e9f
address = 0xF7dcf60AebA077461862d51b77d6d804C06E0073
Eth-Adresse aus komprimiertem öffentlichen Schlüssel ausgeben:
$ echo "0x03aa3e0b3f86053c2aaa08d6f6398e18f76100e0d675680228b000c252e4393e9f" | eth_address_dump
public_key = 0xaa3e0b3f86053c2aaa08d6f6398e18f76100e0d675680228b000c252e4393e9fe85fc162e43d721533736d79c102139d3035d2d9251ccf809bc5bddb81cc6563
compressed_public_key = 0x03aa3e0b3f86053c2aaa08d6f6398e18f76100e0d675680228b000c252e4393e9f
address = 0xF7dcf60AebA077461862d51b77d6d804C06E0073
Zunächst wird ein zufälliger privater Schlüssel aus 64 (hex) Zeichen (256 Bit / 32 Byte) generiert.
Ein öffentlicher Schlüssel mit 128 (Hex) Zeichen (512 Bit / 64 Byte) wird dann aus dem generierten privaten Schlüssel unter Verwendung des Elliptic Curve Digital Signature Algorithm ( ECDSA ) abgeleitet.
Die Keccak-256- Hash-Funktion wird dann auf den öffentlichen Schlüssel angewendet, um eine Hash-Zeichenkette mit 64 Zeichen (256 Bit / 32 Byte) zu erhalten. Die letzten 40 Zeichen dieser Zeichenfolge mit dem Präfix 0x werden zur endgültigen Ethereum-Adresse. (Hinweis: 0x in der Codierung zeigt an, dass die Zahl/String in Hex geschrieben ist.)
Hinweis: Für eine detailliertere, aber einfache mathematische Erklärung dieser Schritte lesen Sie bitte diesen sehr nützlichen Artikel . Wenn Sie tiefer in das Konzept eintauchen möchten, lesen Sie dieses Buch .
Einfaches Python-Codebeispiel mit dem Modul eth_account
from eth_account import Account
acc = Account.create(password_string)
prv = acc.key
pub = Account._parsePrivateKey(prv).public_key
addr = acc.address
Nicolas Massart
Nicolas Massart
q9f
Paula Livingston