Im November 2020 veröffentlichte Andreas Antonopoulos ein Video über die winzig kleine Wahrscheinlichkeit, dass jemand zufällig den gleichen Private Key errechnet und damit Zugriff auf meine Bitcoin erlangt. Er führte dafür astronomische Maßstäbe ein und begnügte sich nicht mit der Nadel im Heuhaufen. Es lief auf das Beispiel hinaus, ein bestimmtes Siliziumatoms im bekannten Universum zu finden.

Damit sollte klar sein, dass die Wahrscheinlichkeit, dass ich zufällig ein Wallet erzeuge, das bereits Coins auf seinen Adressen hat, deutlich geringer ist, als die, dass der Haustürschlüssel der Wohnung eines Einbrechers auch meine Tür aufsperrt. Allerdings, das war alles woran ich denken konnte:

Lottospielen – aber noch dümmer

Da ich sowieso einen VServer angemietet habe um meine Bitcoin-Fullnode zu betreiben und sich dessen CPU-Cores die meiste Zeit langweilen, dachte ich mir:

Warum nicht das Unmögliche versuchen? Kostet das gleiche.

Gesagt getan. Mein erster Prototyp nahm einfach Electrum her und erzeugte mittels Kommandozeilenparameter einen neuen Seed inkl. Kontostandcheck. Das bedeutet, dass hier innerhalb von ca. 10sec ein HD-Wallet erzeugt wird, inkl. 20 Adressen die auf etwaige Sats geprüft werden. Das ist sehr langsam. Allerdings habe ich so auch über 60.000 Wallets geprüft.

Auf Dauer ist das aber nicht nur unwitzig sondern auch abhängig vom Electrum-Netzwerk.

Technische Umsetzung mit Open Source

Die Open-Source-Welt ist groß, vielseitig und voller Überraschungen. In meinem Fall habe ich mir dann aber fast alles selbst gestrickt was die (sinnlose) Wallet-Generierung betrifft. Die Idee ist folgende:

  • Jeden Tag die Bitcoin-UTXOs durchforsten und alle Adressen die seit 2016 nicht mehr angerührt werden und min. einen Bitcoin darauf haben herausfischen. (UTXO-Erklärung hier: QTUM – Ein Quantensprung) Ich nenne das die Liste der abgestandenen Adressen bzw. stale addresses.
  • Das Programm erzeugt BIP39 Seed Phrasen und leitet daraus pro Wallet 1.000 Adressen ab. Diese werden dann in der Liste der abgestandenen Adressen gesucht.
  • Wenn eine Adresse gefunden werden sollte, wird die Adresse in ein File geschrieben.

Neben einem Linux-Server und ein bisschen Bash-Skripting habe ich dafür folgende Programme verwendet bzw. geschrieben:

  • Bitcoin Core – meine Full-Node synchronisiert sich mit dem Main-Net und enthält die UTXO-Daten
  • bitcoin-utxo-dump ist dazu in der Lage die Daten aus der lokalen Bitcoin-Core Datenbank zu extrahieren.
  • Da das UTXO-Extraktionsprogramm keine Filterparameter anbietet, habe ich mir dafür ein kleines Hilfsprogramm geschrieben: utxofilter
  • Ein (leider noch buggy) Programm um deutlich schneller Wallets und dazugehörige Adressen zu generieren und zu überprüfen: cryptosnatch

Das Programm ist noch buggy bzw. hat es ein Memory-Leak. Der RAM-Verbrauch wächst unaufhörlich und eskaliert nach ein paar Stunden. Auf meinem Server lasse ich es daher abstürzen sobald es die Maximalgrenze für den RAM-Verbrauch erreicht und starte es neu. (funktioniert mittels Systemd)

Lokal komme ich so auf ca. 10 Wallets pro Sekunde bzw. 10.000 Adress-Checks pro Sekunde. Auf meinem Server – der deutlich schwächer ist, da er ein günstiger VServer ist – auf ein bisschen mehr als 2 Wallets pro Sekunde bzw. 2.000 Adress-Checks pro Sekunde.

Äh – bist du doof?

Die Frage liegt nahe – allerdings sah ich das als Gelegenheit um mir genauer anzusehen wie man Adressen und Wallets generiert (meine eigene Implementierung habe ich allerdings schlussendlich mit bitcoinj ausgetauscht) und anhand eines sinnlosen Spaßprojekts ein bisschen mit Bitcoin herum experimentiert.

Was das zeigt, ist nur, dass solche Beispiele wie die von Antonopoulos nicht nur so dahin gesagt sind. Mein Programm läuft noch nicht lange, aber ein paar Milliarden Adressen habe ich schon erfolglos geprüft.

Mit jeder Million Adressen die erfolglos überprüft wird, bestätigt sich die praktische Unmöglichkeit ein winziges Stückchen mehr.

Schreiben Sie einen Kommentar

Ihre E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.

*

code