Wie kann man Gelder aus einem gewaltsam geschlossenen Lnd-Blitzkanal zurückerhalten?

Ich habe mein Lnd-Kanal-Backup bei einem Bootsunfall verloren, aber ich habe immer noch die Mnemonik. Ich hatte einen frisch geöffneten Kanal zu meinem eigenen C-Lightning-Knoten, der nie benutzt wurde. Ich habe den Kanal von der C-Lightning-Seite zwangsweise geschlossen.

Die Gelder befinden sich jetzt in einer P2WPKH-Adresse, die ich in Bitcoin Core importiert habe. Jetzt muss ich den privaten Schlüssel herausfinden, um ihn zu fegen. Dazu muss man wissen, wie man es ableitet und dann, wie man es ausgibt.

Es gibt eine Pull-Anforderung für das Brieftaschen-Dienstprogramm , die ich optimieren könnte, um den Schlüssel auszugeben, den ich brauche, sobald ich weiß, wie ich ihn ableiten kann.

Ich kenne auch die Finanzierungstransaktions-ID, die Kanal-ID und alle anderen Kanaldetails, die c-lightning mit ausspuckt listfunds.

Die Schlüsselableitung wird in derivation.go erklärt :

m/1017'/coinType'/keyFamily'/0/index

Der CoinType für Bitcoin ist 0, und ich glaube, die Schlüsselfamilie ist 3: „Wird in Skripten verwendet, die ohne Verzögerung direkt an uns zahlen.“

Meine Vermutung ist, dass der Index 0 ist, da es der erste Kanal war.

BOLT 3 erklärt dann, wie man diesen Schlüssel für eine Commitment-Transaktion optimiert. Da die andere Seite diesen Kanal geschlossen hat, brauche ich die to_remoteAusgabe, die die remotepubkey.

pubkey = basepoint + SHA256(per_commitment_point || basepoint) * G 
privkey = basepoint_secret + SHA256(per_commitment_point || basepoint)

Die Spezifikation besagt, dass "der Remotepubkey den Payment_Basepoint des Remote-Knotens verwendet". Ist das der Schlüssel, den wir gerade hergeleitet haben?

Damit bleibt noch per_commitment_pointherauszufinden, abgeleitet von per_commitment_secret. Ich bin verwirrt, woher das kommt.

Welche Go-Beschwörung sollte ich verwenden, um den gesuchten privaten Schlüssel auszugeben?

Ich kann Ihnen die Antwort nicht aus der Schublade geben, aber ich wollte dieser Logik schon lange nachjagen. Wenn niemand die Antwort findet, würde ich freiwillig einen Hangout (oder welchen Dienst Sie auch immer bevorzugen) veranstalten, um die Ableitung der per_commit-Sekrete aus dem mnemonischen Samen zu verfolgen

Antworten (2)

In c-lightning wird der Punkt pro Zusage aus der hsm_secretVerwendung von per_commit_point abgeleitet von:

  1. Die Knoten-ID / der öffentliche Schlüssel (kann mit gefunden werden listfunds, bis der Kanal einige Zeit nach dem Schließen gelöscht wird)
  2. Die Kanaldatenbank-ID (zu finden mit cat ~/.lightning/debug.log | grep $node_id), angezeigt alschan #$node_id
  3. Die Verpflichtungsnummer (0 beim Öffnen des Kanals, erhöht sich während Gebührenverhandlungen und anderen Kanalaktualisierungen, | grep commit)

Wir kümmern uns um den Verpflichtungspunkt, nicht um das Geheimnis, denn der von uns benötigte private Schlüssel wird wie folgt abgeleitet:

privkey = basepoint_secret + SHA256(per_commitment_point || basepoint)

Ich habe ein Tool für c-lightning erstellt, um diesen Punkt zu löschen (mit Hilfe von @cdecker): https://github.com/ElementsProject/lightning/pull/3115

Zurück zu Lnd ... Ein einfacher Ort, um einen privaten Schlüssel abzulegen, ist der lnwallet walletinfoBefehl. Fügen Sie so etwas hinzu commands.go:

basePointSecret, err := keyRing.DerivePrivKey(keychain.KeyDescriptor{
  KeyLocator: keychain.KeyLocator{
    Family: keychain.KeyFamilyPaymentBase,
    Index:  0, // Same commitment index as used in c-lightning 
  },
})

// Parse per_commitment_point dumped by c-lightning:
bytes, err := hex.DecodeString(".........")
commitPoint, err := btcec.ParsePubKey(bytes, btcec.S256())

// Obtain SHA256(per_commitment_point || basepoint)
h := sha256.New()
h.Write(commitPoint.SerializeCompressed())
h.Write(basePointSecret.PubKey().SerializeCompressed())
commitTweak := h.Sum(nil)

// Obtain and dump private key
tweakedPrivkey := TweakPrivKey(basePointSecret, commitTweak)
commitmentWif, err := btcutil.NewWIF(tweakedPrivkey, &chaincfg.MainNetParams, true)

fmt.Printf("Dump commitment priv key: %s\n", commitmentWif)

Wobei TweakPrivKey() von script_utils gehoben wird .

Importieren Sie den resultierenden privaten Schlüssel in Bitcoin Core et voila!

Damit bleibt der per_commitment_point zu ermitteln, abgeleitet von per_commitment_secret. Ich bin verwirrt, woher das kommt.

Dies kommt von den open_channel/accept_channelNachrichten in BOLT2. Es heißt first_per_commitment_point.

Leider kann ich in der lnd-Dokumentation nicht finden, wo Sie darauf zugreifen können.

Eine Idee: Sehen Sie sich die lnd-Backup-Dokumentation an und versuchen Sie herauszufinden, wie das funktioniert. per_commitment_secretmüssen gesichert werden, um Gelder vertrauenswürdig einzulösen. Da es so aussieht, als ob sie keinen einfachen Zugriff darauf bieten, können Sie es möglicherweise in den Sicherungsinformationen finden.