Ich raube mir die Haare und versuche, ein paar Konzepte zu verstehen. Ich möchte eine Segwit-Wallet in meinem Ledger Nano S verwenden, um ungehärtete (?) untergeordnete öffentliche Schlüssel (und damit Segwit-Adressen) abzuleiten, die mit denen übereinstimmen, die mein Nano produziert. Ich möchte dies mit Python 3 tun. Ich glaube, das Erstellen einer solchen Adresse wird als "Watch Wallet" bezeichnet oder wird zumindest in den Bip32-Dokumenten wie folgt beschrieben:
Dies ermöglicht beispielsweise einem Webshop-Unternehmen, seinen Webserver für jede Bestellung oder für jeden Kunden neue Adressen (Public Key Hashes) generieren zu lassen, ohne dem Webserver Zugriff auf die entsprechenden privaten Schlüssel (die für die Ausgabe der erhaltenen Gelder erforderlich sind) zu geben. https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki#Motivation
Genau das versuche ich mit Python für meine Django-Anwendung zu tun. Ich möchte keinen Drittanbieterdienst verwenden, da mir gesagt wird, dass ich der Weitergabe meines erweiterten öffentlichen Schlüssels (xPub) nicht vertrauen soll. Ich möchte den xPub von meinem Ledger Nano S verwenden. Eigentlich bin ich mir nicht ganz sicher, ob mein Nano S einen xpub oder einen zpub verwendet, aber ich habe dies in einer separaten Frage gestellt.
Hat Ledger Nano S ein xPub oder ein zPub für Bitcoin-Geldbörsen?
Unabhängig davon habe ich den "xpub"-Schlüssel in einen "zpub"-Schlüssel umgewandelt und versucht, neue Schlüssel abzuleiten, indem ich VIELE verschiedene Python-Module verwendet habe und ohne Erfolg eine Adresse erstellt habe, die mit der übereinstimmt, die mein Nano produziert, oder sogar ähnlich aussieht.
Um Antworten zu eliminieren, die Methoden vorschlagen, die ich bereits ausprobiert habe, finden Sie hier eine vollständige und erschöpfende Liste aller Methoden, die ich ausprobiert habe, mit Links zu allen ähnlichen Fragen auf Stack Exchange.
Zuerst habe ich btclib zusammen mit Pycoin ausprobiert .
Hinweis: In allen Beispielen versuche ich, das Bitcoin Testnet zu verwenden
from btclib import bip32
from pycoin.networks.registry import network_for_netcode
network = network_for_netcode("XTN") # XTN for the Testnet, BTC for the Mainnet
xpub = "x(z/t)pub-big-long-key-that-starts-with-tpub-zpub-xpub"
child_xpub_key = bip32.derive(xpub, "84'/1'/0'/0/0")
key = network.parse.bip32(child_xpub_key)
print(str("Key: {}").format(child_xpub_key))
print(str("Address: {}").format(key.address()))
Ähnlich wie bei dieser Frage: Öffentlichen Schlüssel von xpub ableiten? Ich erhalte einen Fehler bei Verwendung des "gehärteten" Ableitungspfads, und damit der Fehler behoben wird, kann ich nur den Pfad 84/1/0/0/0 verwenden. Ich habe sogar Pfad 0 und 0/0 ausprobiert. Natürlich enthält der Pfad, den mein Nano mir gibt, das ('). Nach meinem Verständnis ist dieser Ableitungspfad für zpub-Schlüssel, aber selbst wenn ich in zpub konvertiere, gibt es mir keine Adresse, die zu meinem Nano passt. Ich nehme an, das liegt daran, dass ich Bip44 oder Bip84 verwenden sollte, um Adressen abzuleiten? Richtig?
Das nächste, was ich zu verwenden versuchte, war bip_utils
from bip_utils import Bip44, Bip44Coins
key_str = "x(z/t)pub-big-long-key-that-starts-with-tpub-zpub-xpub"
bip44_ctx = Bip44.FromExtendedKey(key_str, Bip44Coins.BITCOIN_TESTNET)
Dieser Code funktioniert, der Beispielcode auf der Github-Seite bip_utils legt jedoch nahe, dass die nächste Codezeile wie folgt aussehen sollte:
# Derive account 0 for Bitcoin: m/44'/0'/0'
bip44_acc = bip44_ctx.Purpose().Coin().Account(0)
Was mir den Fehler gibt
Bip44DepthError: Current depth (3) is not suitable for deriving purpose
Ich weiß bereits, dass ich m/44'/0'/0' nicht will, aber die Dokumentation gibt keinen Hinweis darauf, wie man den Pfad ändert, und ein Blick auf den Quellcode hat mir auch nicht geholfen.
Dann habe ich versucht, pybitcointools des berühmten Vitalik Buterin zu verwenden. Er hat sogar einen Teil in den Dokumenten über "Wallets beobachten":
Aus Sicherheitsgründen sollten Seed und xprv idealerweise nur im Kühlhaus aufbewahrt werden. Wenn eine Webanwendung in der Lage sein muss, Adressen auf Abruf bereitzustellen, besteht die Lösung darin, eine Watch-Wallet zu verwenden, die aus dem xpub generiert wird. Nehmen wir zum Beispiel das Dash xpub aus einem vorherigen Beispiel:
from cryptos import *
coin = Dash()
xpub = 'xpub-some-xpub-key'
wallet = coin.watch_wallet(xpub)
wallet.is_watching_only
wallet.new_receiving_address()
wallet.new_change_address()
Ich denke: "Das ist es, Vitalik ist mein Held! Er weiß, wonach ich suche!" Aber NEIN, dieser Beispielcode funktioniert anscheinend nur für Dash. Wenn ich die Klasse auf Bitcoin() ändere, funktioniert keine der in der Dokumentation beschriebenen „watch_wallet“-Methoden, oder sie existieren nicht. Nirgendwo ist ein Beispiel dafür, wie man das mit Bitcoin zum Laufen bringt.
Von allen Methoden, die ich ausprobiert habe, hat mir zumindest btclib keine Fehler gegeben. Ich könnte diese Python-Module falsch verwenden oder vielleicht gibt es ein besseres Python-Modul / eine bessere Klasse, die ich verwenden sollte. Jede Richtung wäre hilfreich. Vielen Dank im Voraus.
Da Sie mit xPubs keine gehärteten Pfade durchlaufen können, zeigt das Hauptbuch nicht den Master-XPUB an, sondern den XPUB an der Ableitungsadresse 84/0'/0'
oder was auch immer Ihre Kontonummer ist. Von dort benötigen Sie zwei zusätzliche Ableitungen von 0/0, um den endgültigen 84/0'/0'/0/0
öffentlichen Schlüssel zu erhalten.
Der resultierende öffentliche Schlüssel kann verwendet werden, um entweder eine P2PKH-Adresse (Nicht-Segwit) oder eine P2WPKH-Adresse (Segwit) abzuleiten. Xpub und Zpub sind beide Codierungen desselben Schlüssels, aber Zpub weist die Brieftasche zusätzlich an, eine P2WPKH-Adresse daraus abzuleiten. Ledger verwendet diesen Standard nicht und kodiert ihn lieber mit der allgemeineren Xpub-Kodierung (die keine Anweisungen enthält).
Mit meiner Spielzeug-Python-Bibliothek können Sie das folgende Skript verwenden, um Ihre Adressen abzuleiten:
from cryptotools import Xpub
MY_XPUB = 'xpub-as-shown-in-ledger'
key = Xpub.decode(MY_XPUB)
pubkey0 = key/0/0
print(pubkey0.address('P2WPKH')) # Tell the wallet that you want a P2WPKH address
Wenn Sie Testnet-Adressen wünschen, setzen Sie die envvar CRYPTOTOOLS_NETWOK = 'test'
Pycoin unterstützt jetzt nach diesem Commit segwit xpub . Es kann xpub/ypub/zpub parsen und Adressen ableiten. Ledger verwendet immer noch ein falsches Präfix für segwit xpub und Sie müssen möglicherweise das xpub entsprechend in ypub/zpub umwandeln
Antoine Pointot