Lightning Deep Dive: Invoices, LNURL, Bolt12 & Lightning Address

Lightning-Transaktion: Ja gerne, aber wie eigentlich? Unser Lightning-Entwickler, Johannes Zweng, geht in diesem Beitrag den verschiedenen Lightning-Adressformaten auf die Spur, erklärt deren Unterschiede und gibt Einblick darüber, wie eine Transaktion über das Lightning-Netzwerk überhaupt funktioniert.

Anders als das Bezahlen On-Chain, also das Senden von Bitcoin an eine Bitcoin-Adresse, ist ein Bezahlvorgang über das Lightning-Netzwerk immer ein interaktiver Vorgang. Die beiden LN Nodes (Zahlungsempfänger und Sender) müssen vor Beginn und während der eigentlichen Zahlung interaktiv Informationen austauschen. Doch warum ist das eigentlich so?

On-Chain

Für eine klassische Bitcoin Zahlung an eine BTC Adresse benötigt der Sender nichts anderes als die Adresse (was nichts anderes ist als die gehashte Darstellung eines öffentlichen Schlüssels). Die Wallet des Senders kann dann einfach einen neuen Transaction Output erstellen, in welchem sie als Bedingung (unlock condition) formuliert, dass dieser Output (diese “coin”) nur mit einer passenden Signatur zu diesem öffentlichen Schlüssel bewegt werden darf. Dazu muss der Empfänger während der Transaktion nicht online sein, der Sender benötigt nur die Adresse des Empfängers.

Lightning

Bei Lightning funktioniert das anders. Um das zu verstehen, wollen wir kurz auf den Ablauf einer Lightning Zahlung eingehen: Eine Lightning Zahlung wird über mehrere Routing Nodes und deren Payment Channels weitergeleitet. Vereinfacht gesprochen gibt der Absender seine Satoshis an eine Routing Node 1 weiter, mit der Bitte, dass diese sie an Routing Node 2 weitergibt, usw. bis die letzte Node die Sats an den Empfänger weitergibt. 

Dabei gibt jede Node ein bisschen weniger weiter als sie erhält, und diese Differenz sind die Gebühren, welche die Routing Nodes für ihren Dienst behalten dürfen. Um zu gewährleisten, dass alle Nodes entlang der Route auch nach den Regeln spielen, und niemand auf dem Weg einfach das Geld komplett behält, ohne es weiterzuleiten, werden die Satoshis vom ursprünglichen Absender mit einem Secret “gelockt”, also an eine Bedingung geknüpft.

Diese Bedingung ist so gewählt, dass die Nodes am Weg erst dann ihre Satoshis empfangen können, wenn das Geld den eigentlichen Empfänger erreicht hat. 

Hashfunktion by Johnny

Wie geht das? 

Dazu denkt sich die Empfänger-Wallet ein zufälliges und einmaliges Geheimnis aus, hashed dieses (siehe Infografik “Hashfunktion”) und übergibt diesen Hash direkt (also außerhalb des Lightning-Netzwerks) dem Sender. Die Absender-Wallet gestaltet nun ihre Transaktion derart, dass nur derjenige, der das Geheimnis hinter diesem Hash kennt, die Coins nehmen kann, und schickt diese auf den Weg durch das Lightning-Netzwerk.

Somit ist gewährleistet, dass alle Nodes entlang der Route die Coins nur dann bewegen können, wenn die Zahlung beim Empfänger ankommt, denn wenn der Empfänger die sats nehmen will, muss er dazu das Geheimnis hinter dem Hash preisgeben und nur dadurch wird das Geheimnis auch für die anderen Nodes am Weg sichtbar und somit können alle am Weg die Coins erst dann final  bewegen, wenn der Empfänger die Coins erhalten hat.

Also zusammengefasst: entweder bewegen sich die Coins in allen Channels auf dem Weg weiter, oder es bewegen sich nirgends Coins, dazwischen gibt es nichts. Der ganze Vorgang ist atomar (alles oder nichts).


Um mehr über das Lightning-Netzwerk zu erfahren, sieh dir diesen Blogbeitrag an.

LN Invoice

Wir wissen nun, dass wir diesen Hash (dieses verdeckte Geheimnis) vor der eigentlichen Transaktion an den Absender übergeben müssen. Genau das (das Übergeben dieses gehashten Geheimnisses) ist die Hauptfunktion der Lightning Invoice. (Es stehen zwar auch noch zusätzliche Infos in der Invoice, wie zum Beispiel. Betrag, Empfänger-Node-ID, optionale Routing-Infos, Ablaufdatum, sowie eine Unterschrift der Empfänger-Node, aber der Hash ist das Wesentliche. (Falls Du mehr dazu https://www.bolt11.org/ um dir die Inhalte einer Invoice anzusehen.)

Für die Sicherheit der Zahlung auf dem Weg (also dass keine der Nodes entlang der Route die Coins einfach nehmen kann, ohne sie weiterzuleiten) ist es wesentlich, dass niemand das verdeckte Geheimnis kennt, bevor die Zahlung den Empfänger erreicht hat. Aus diesem Grund kann eine Lightning Invoice immer nur einmalig verwendet werden (weil danach das Secret bekannt ist). Das bedeutet, für jede neue Lightning-Zahlung muss man den Empfänger erneut um eine neue Invoice bitten.

LNURL

Um den Empfänger nun nicht jedes Mal manuell nach einer neuen Invoice fragen zu müssen, haben Entwickler ein auf HTTP aufbauendes Protokoll entwickelt (also außerhalb des eigentlichen Lightning-Netzwerkes), das diesen Austausch von Lightning Invoices automatisiert. Dies ist das LNURL Protokoll

Im Wesentlichen ist LNURL ein Webprotokoll, also einfach ein Webserver (eine URL), dem man eine Anfrage dieser Art senden kann: “Bitte gib mir eine neue, unbenutzte Lightning Invoice, denn ich möchte Dir Geld senden”. 

Somit ist LNURL nicht Teil des eigentlichen Lightning Kernprotokolls, sondern ein Standard, auf den sich Lightning Wallet-Entwickler geeinigt haben, um die Usability von Lightning zu verbessern. LNURLs werden ebenfalls meist als QR Codes dargestellt. Wenn man sich den Text in so einem QR Code ansieht, so beginnt dieser immer mit “lnurl” und nicht mit “https”. Dies liegt daran, dass die Webadresse noch zusätzlich mit einem fehlertoleranten Kodierungsverfahren (mit Prüfsumme) kodiert wird, nämlich “bech32” (welches auch für Segwit Bitcoin Adressen verwendet wird). 

Mit solchen LNURL QR Codes ist es nun möglich, statische, wiederverwendbare QR Codes zu erstellen, die man für mehrere Zahlungen verwenden kann. Also in diesem QR Code steckt nun keine Bitcoin Adresse oder Lightning Invoice, sondern einfach eine “https://” Web-Adresse, an die sich eine Wallet wenden kann, wenn sie eine neue frische LN Invoice erhalten möchte.

Der Vollständigkeit halber sei noch angemerkt, dass dies nur eine Teilanwendung des LNURL Protokolls ist, nämlich LNURL-pay, es gibt noch einige andere Subprotokolle, die ebenfalls LNURL verwenden, wie zb. LNURL-auth für Login, oder LNURL-withdraw, wenn man Empfangen statt Senden möchte.

Lightning Address

LNURLs sind in der Regel lange und nicht intuitiv menschenlesbar. Sinnvollerweise verwendet man sie daher meist nur als QR Codes. Zum manuellen Eintippen sind diese nicht gedacht. Um aber trotzdem, ähnlich wie bei E-Mail Adressen, das manuelle Merken oder Eintippen von Adressen einfacher zu ermöglichen, wurde aufbauend auf LNURL eine vereinfachte Darstellung von LNURLs entwickelt, die tatsächlich genauso wie E-Mail Adressen aussehen.

Im Hintergrund steckt aber dennoch nach wie vor einfach eine “https” Web-Adresse, nur wird einfach per Konvention festgelegt, wie diese URL aufgebaut ist.

Also am Beispiel der Lightning Adresse: username@domain.com 

Quelle: github.com/andrerfneves/lightning-address

Eine Lightning Adresse sieht also aus wie eine E-Mail-Adresse, ist aber nur eine verkürzte Darstellung für LNURL-pay Webadresse. Alles andere funktioniert dann wie bei LNURL-pay.

Kritik

In einer LNURL steht eine Webseiten-URL. Das Protokoll arbeitet über HTTP und erfordert, dass man einen Domainnamen besitzt (oder ein Tor Hidden Service bereitstellt)  und einen Webserver betreibt. Dies ist für Custodial Wallets oder große Serviceanbieter keine Einschränkung (denn die haben in der Regel bereits eine Webseite), aber im privaten Umfeld kann dies eine Hürde darstellen (nicht jeder kleine private Nutzer betreibt eine Webseite). Zudem gibt man als Benutzer (Absender) von LNURL jedes Mal seine IP-Adresse an den Webserver bekannt (wenn es nicht gerade über Tor läuft). Der Empfänger erfährt also in der Regel wo im Internet der Absender sitzt.

All dies ist im Lightning Protokoll nicht der Fall. Dort wurde viel Arbeit in privacy-schonende Technologien gesteckt. Lightning verwendet eine Technik namens “onion routing”, die ähnlich wie bei Tor eine Nachricht in mehrere verschlüsselte Schichten einpackt, ähnlich wie ein Brief, den man in einen Brief steckt, den man in einen Brief steckt, den man in einen Brief steckt. Jede Station auf dem Weg dieses Briefes öffnet ihr Kuvert und findet darin nur einen weiteren adressierten Brief, dessen Inhalt sie nicht kennt und sendet diesen weiter. Somit kennt niemand auf dem Transaktionsweg den Inhalt oder den Empfänger der Nachricht.

BOLT12

BOLTs (kurz für “Basis of Lightning Technology”) nennt man die Lightning Spezifikationsdokumente (ähnlich wie BIPs bei Bitcoin) und diese können hier auf Github eingesehen werden. Bisher gibt es 11 Bolts. Bolt 11 beschreibt das Format der Lightning Invoice. Bolt 12 wäre das nächste Dokument und ist derzeit noch ein Entwurf. Bolt 12 beschreibt eine Erweiterung namens “Lightning Offers”, die eine ähnliche Funktion bieten soll wie derzeit LNURL-pay.

Ein Offer ist ebenso wie eine LNURL wiederverwendbar und statisch (ein QR Code kann für viele Zahlungen verwendet werden). Ein Offer beinhaltet ähnlich wie eine LNURL die Information, wohin sich eine Wallet wenden soll, um eine neue frische Invoice zu erhalten. Allerdings erfolgt die Kommunikation hierbei nicht via HTTP, sondern wie auch Lightning Zahlungen selbst, via Onion-Routing. Man benötigt dafür keinen Domainnamen, keinen Webserver, und muss seine IP Adresse nicht preisgeben. Es läuft alles über die Lightning Node und alles über das Lightning-Netzwerk.

Zusätzlich wird es noch weitere Features ermöglichen, wie regelmäßig wiederkehrende Zahlungen (Daueraufträge), optionale payer proofs (optionaler Nachweis wer bezahlt hat, wenn gewünscht), und andere Features, die der weiteren Verbreitung von LN zugutekommen dürften.

Fazit

Die LNURL Protokollfamilie hat den großen Vorteil, dass sie sehr flexibel in der Entwicklung ist, da es sich um Protokolle außerhalb der Lightning Kern-Spezifikation handelt. Dadurch war es in der Vergangenheit möglich sehr schnell sehr nützliche Features zu entwickeln, die für die Usability und Verwendbarkeit von Lightning sehr wesentlich waren. Ohne LNURL gäbe es sehr viele der heutigen Lightning Projekte und Services nicht (oder noch nicht). Zudem sind die Einschränkungen von LNURL in vielen Anwendungsfällen auch völlig ok. Wenn ein Kunde bereits per HTTP mit einem Onlineshop kommuniziert, verliert er nichts, wenn er auch LNURL über HTTP nutzt.

Gleichzeitig ist es aber wichtig, all diese Funktionen auch für self-hosted Wallets ohne Serviceprovider und ohne Webserver bereitstellen zu können. Es wird daher vermutlich auch in Zukunft nicht ein Entweder und ein Oder sein, sondern vermutlich werden auch künftig beide Protokolle koexistieren. 

Mit LNURL können neue Features schneller realisiert werden und Dinge, die für das Kernprotokoll nützlich und sinnvoll sind, werden (zwar langsamer, aber früher oder später auch) ohnehin ins Lightning Protokoll einfließen. Also solange Bolt 12 noch ein Entwurf und noch nicht umgesetzt ist, ist es besser, wir benutzen LNURL, als Lightning gar nicht zu nutzen.

Vielen Dank für's Lesen meines Beitrags zu diesem Thema und bis zum nächsten mal - euer Johnny.