Website-Icon BitcoinBlog.de – das Blog für Bitcoin und andere virtuelle Währungen

Eine Anleitung, wie man mit einem Lightning-Node Geld empfängt

A huge thunderstorm close to Port Hedland (Western Australia) lighting bushfires everywhere. I have waited for this photo since a long time. Bild von Diamond T Design via flickr.com. Lizenz: Public Domain

Als Vorbereitung für den LightningHackday am Samstag habe ich einen Lightning-Node aufgesetzt. Mein Ziel war es, damit nicht nur zu bezahlen, sondern auch so bezahlt zu werden, wie ich es mit Bitcoin werde. Wie es lief und über welche Probleme ich gestolpert bin, erfahrt ihr in diesem Artikel.

1. Greshams Gesetz und Lightning

Es mag ein wenig seltsam sein, aber dieser Lightning-Guide beginnt mit jemandem, der vor knapp 500 Jahren geboren ist: Thomas Gresham (1519-1579), ein Berater der englischen Krone und der Vater des berühmten Gresham’schen Gesetzes. Die Geschichte geht so: Heinrich II. hatte minderwertige Silbermünzen prägen lassen und die Händler per Gesetz gezwungen, diese zu gleichen Sätzen wie die vollwertigen Münzen anzunehmen. Gresham beobachtete, dass die Händler die schlechten Münzen rasch ausgaben, aber die guten horteten. Der Nachfolgerin von Heinrich, Königin Elisabeth, erklärte er die Beobachtung mit dem Satz, dass das schlechte Geld das gute Geld aus dem Umlauf verdränge. Dieser Satz wurde zu Greshams Gesetz.

Auch Bitcoin scheint die Regel zu bestätigen: Die mengenmäßig begrenzte Kryptowährung ist das gute, der dahininflationierende Euro das schlechte Geld. Bei Bitcoin geht es dementsprechend gar nicht so sehr darum, die Münzen auszugeben, sondern darum, sie einzunehmen. Dies trifft meine eigene Erfahrung: Ich benutze Bitcoin zwar auch, um digitale Güter zu bezahlen, aber vor allem, um Geld einzunehmen – als Spenden fürs Blog, für Käufe meines Buches, für Affiliate-Auszahlungen und vieles mehr.

Um Lightning zu testen, hätte sich die Android-Wallet Eclair angeboten. Mit ihr kann man angeblich in wenigen Minuten beginnen, Bitcoins mit Lightning auszugeben. Allerdings kann man mit ihr keine Bitcoins empfangen, weshalb es für mich recht reizlos gewesen wäre. Ich wollte Lightning so benutzen, wie ich Bitcoin benutze; mein Ziel war es, die Spendenadresse, die ich mit Bitcoin seit 2013 habe, mit Lightning zu reproduzieren.

2. Was man braucht, um mit Lightning Geld zu empfangen

Wenn man mit Lightning Geld empfängt, stößt man auf mehrere Probleme: Erstens muss man online sein, damit die Zahlung den Weg zu einem findet. Das ist ein riesiger Unterschied zwischen Bitcoin und Lightning. Zweitens braucht man eingehende Liquidität in den Payment Channels. Das werde ich später noch genauer erklären. Drittens muss man dem Sender irgendwie eine Zahlungsaufforderung zukommen lassen.

Geld mit Lightning zu empfangen, ist also nicht eben trivial. Es mag sein, dass es einfacher geht, aber mein Eindruck ist, dass ich auf jeden Fall einen Node brauche, der rund um die Uhr läuft. Da ich keine Lust habe, bei mir zuhause einen Laptop oder einen Raspberry permanent an zu haben, habe ich beschlossen, einen Node auf einen virtuellen privaten Server zu laden. Um dem Sender eine Zahlungsanweisung zu geben, werde ich meine Webseite benutzen, die irgendwie mit dem Node kommuniziert.

Ob und wie all das funktioniert, werde ich im Folgenden beschreiben.

3. VPS, SSH, SSH, Bitcoin Core

Zunächst einmal brauche ich also einen virtuellen privaten Server, kurz VPS. Da ich darauf einen vollen Bitcoin und Lightning Node aufsetzen werde, muss das VPS mindestens 200 Gigabyte SSD-Festplattenspeicher haben. Ich suche auf hosttest.de nach einem entsprechenden VPS, das ich mit Bitcoin bezahlen kann, und werde fündig.

Danach muss ich mich per SSH einloggen. SSH ist ein verschlüsselter Kanal zur Command Line des Servers. Wenn man es gewohnt ist, mit dem Linux-Terminal zu arbeiten, ist es nicht weiter schwierig. Ich muss nur in meinem Terminal SSH root@185.169.97.66 sowie mein Passwort eingeben. Dann bin ich auf dem Server, und kann mich dort mit üblichen Befehlen wie ls -all oder cp orientieren. Nach einigen Minuten bin ich bereit, den nächsten Schritt zu gehen.

Ich logge mich auf mein VPS ein. Innerhalb von weniger als einem Tag gab es mehr als 27.000 Versuche, den Account zu hacken. Ganz sicher fühle ich mich damit nicht.

Ich lade die neueste Version von Bitcoin Core herunter. Eigentlich sollte man die Signaturen prüfen, aber das spare ich mir der Faulheit wegen. Nach ein wenig Googlen finde ich heraus, dass man mit SCP Dateien auf ein VPS laden kann. Nachdem ich Bitcoin Core in mein Downloadverzeichnis geladen habe, schubse ich es mit dem folgenden Code auf mein VPS: SCP bitcoin-0.16.0-x86_64-linux-gnu.tar.gz root@185.169.97.66:. Dort entpacke ich die Datei und starte Bitcoin Core mit der Anmerkung, dass der Client Transaktionen indizieren soll (was für Lightning nötig ist), und dass ich den Status im Terminal verfolgen möchte: bitcoin-0.16.2/bin/bitcoind --txindex=1 --printtoconsole.

Danach beginnt Bitcoin Core die Blockchain zu synchronisieren. Das dauert ein bis zwei Tage. Nachts fahre ich meinen Computer herunter. Ich nehme an, dass Bitcoin Core auf dem VPS weiterläuft, stelle aber am nächsten Tag fest, dass ich das Programm mit dem Terminal geschlossen habe. Nach ein wenig googlen erfahre ich, dass ich es per screen öffnen muss: Ich gebe einmal screen ein und starte dann Bitcoind. Wenn ich danach mein Terminal schließen möchte, muss ich STRG + a + d drücken. Dann geht der Screen zu, aber Bitcoin läuft weiter.

Ich warte nochmal einen Tag, dann beginne ich, Lightning zu installieren.

4. Den Lightning Node installieren

Es gibt mehrere Versionen von Lightning. Von C-Lightning heißt es, es sei vor allem für Profi-Nutzer gemacht, die volle Version von Eclair braucht Java, was meiner Erfahrung nach bei Linux immer schiefgeht. Also nehme ich LND von Lightning Labs. Das gilt auch als der am weitesten fortgeschrittene und stabilste Client.

Eine Anleitung, wie man LND installiert, gibt es im Github von LND selbst, und im ersten Teil des Lightning-Reviews von Andreas Brekken. Beide Anleitungen sind sehr hilfreich und sollten den User gut durch die Installation führen. Daher werde ich hier nicht so sehr ins Detail gehen.

Zunächst muss man die Programmiersprache Go sowie den Go-Paketmanager Dep installieren. Irgendwie muss man dann auch einen Go-Path bestimmen, wofür man das auch immer braucht. Ich hatte hier das Problem, dass das Ubuntu auf meinem VPS den klassischen Befehl apt-get install nicht kannte. Nach einigem Suchen habe ich aber entdeckt, dass es mit yum geht. Ich bin mir nicht mehr sicher, ob ich auch eine Installationsdatei herunterladen musste, habe aber auf jeden Fall einige Zeit bei diesem Schritt verbracht.

Danach klont man das Lightning-Repository auf dem VPS und installiert es. Ich habe mich dabei an die Codes auf dem LND-Github gehalten, was super geklappt hat.

Anschließend wurde es etwas haarig. Zunächst starte ich den Lightning-Node mit einem relativ ausführlichen Befehl, der dem Node sagt, dass ich das Bitcoin-Mainnet mit Bitcoind benutze. Er sieht etwa so aus: lnd --bitcoin.active --bitcoin.mainnet --debuglevel=debug --bitcoin.node=bitcoind. LND startet und informiert mich darüber, dass ich mit lncli einen neuen Account bilden und diesen entlocken soll.

LND ist nämlich eine Art „Daemon“, also ein Programm, das unterhalb der Nutzeroberfläche läuft. Um es zu bedienen, muss man mit lncli Befehle eingeben. Also probiere ich es mit lncli create, woraufhin ich eine Seed bekomme und ein Passwort wählen kann. Sehr gut. Danach entlocke ich meinen Account mit lncli unlock.

Nun beginnen die Probleme. Denn sobald ich den Account entlocke, fährt LND herunter. Warum, ist für mich schwer nachvollziehbar, und ich hänge etwa ein bis zwei Tage daran. Irgendwie sind die Konfigurationen von Bitcoind und LND nicht kompatibel, weshalb ich es mit den verschiedensten Config-Dateien versuche. Dabei lerne ich, im Terminal Dateien mit vim zu bearbeiten. Irgendwann klappt es.

Die Datei bitcoin.conf, die im Verzeichnis .bitcoin liegt, sieht so aus:
server=1
txindex=1
maxconnections=10
rpcuser=MeinName
rpcpassword=MeinPassWort
zmqpubrawblock=tcp://127.0.0.1:28332
zmqpubrawtx=tcp://127.0.0.1:28333

Ich habe, um ehrlich zu sein, keine Ahnung, wofür die zmq... Zeilen gut sind, aber scheinbar sind sie notwendig. Wenn ich sie weglasse, bringt LND eine Fehlermeldung. Im Verzeichnis .lnd liegt schließlich die Datei lnd.conf. Sie sieht bei mir nun so aus:

[Application Options]
debuglevel=trace
maxpendingchannels=5
alias=MOBY_Blitz
externalip=185.169.97.66:9735
listen=0.0.0.0:9735
[Bitcoin]
bitcoin.active=1
bitcoin.mainnet=1
bitcoin.node=bitcoind
[Bitcoind]
#bitcoind.rpcuser=MeinName
#bitcoind.rpcpass=meinPassWort
#bitcoind.zmqpubrawblock=tcp://127.0.0.1:28332
#bitcoind.zmpubqrawtx=tcp://127.0.0.1:28333
[autopilot]
autopilot.active=1
autopilot.maxchannels=5

Mit Alias kann ich einstellen, wie ich nach außen heiße; mit autopilot weise ich LND an, automatisch mein Guthaben auf einige Payment-Channels zu verteilen.

LND filtert die Blockchain. Es heißt mal wieder „Warten“.

Mit dieser Konfiguration starte ich erneut. Und, voila, es läuft. LND beginnt, die Blockchain zu filtern. Ich vermute, um darin die Channels des Lightning-Netzwerkes zu finden. Das dauert nochmal ein bis zwei Tage. Da ich LND mit screen gestartet habe, kann ich das Terminal schließen und meinen Computer herunterfahren.

5. Lightning benutzen

Nachdem LND synchronisiert hat, kann ich endlich loslegen. Zuerst brauche ich Geld auf meiner Wallet. Also gebe ich mit lncli newaddress p2wkh eine neue Adresse aus, schicke ein wenig Bitcoin darauf und warte auf die Bestätigung.

Danach sollte eigentlich der Autopilot dafür sorgen, dass das Stückchen Bitcoin auf mehrere Channels verteilt wird. Ich warte ein bis zwei Stunden, aber nichts passiert. Mit lncli getinfo erfahre ich, wie die Lage ist. Mein Node hat erst zwei Verbindungen zur Außenwelt und noch nicht mal einen „pending“ Channel. Ich nehme meinen „Identity Pubkey“ und suche bei 1ml.com, ob mein Node schon gesehen wird. Wird er nicht.

Die Webseite 1ml.com ist eine Art Explorer für Lightning. Meinen Node finde ich dort aber nicht.

Ich lasse mich nicht entmutigen und verbinde mich mit mehreren prominenten Lightning-Nodes, etwa von 1ml.com selbst oder von CoinGate. Das klappt. Mit CoinGate baue ich einen Payment-Channel auf, was nach einigen Versuchen ebenfalls klappt, und es gelingt mir auch, eine Zahlung zu tätigen, um einen Artikel bei yall’s freizukaufen. Das Ergebnis ist aber eher enttäuschend und war die Satoshis nicht wert.

Ich verbinde mich mit CoinGate („connect“) und öffnen einen Channel („openchannel“). Nach einigen Versuchen läuft es.

Dennoch bin ich nicht zufrieden. Mein Node ist weiterhin nicht auf 1ml.com sichtbar, keiner baut eine Verbindung zu mir auf, und der Autopilot läuft auch nicht. Ich vermute, dass es daran liegt, dass auf meinem VPS Port 9735 geschlossen ist. Google meint zwar, dass bei den meisten VPS alle Nodes offen sind, doch ein Test auf YouGetSignal zeigt, dass bei mir nur der für SSH zuständige Port 22 offen ist.

Wie kriege ich bei meinem VPS nun den Lightning-Port 9735 auf? Nach einigen verzweifelten Stunden mit Google entdecke ich den Befehl iptables, mit dem es mir irgendwie gelingt, den Port zu öffnen. Danach beginnt der LND-Daemon zu arbeiten, das Display zeigt wirre Logs an, der Autopilot öffnet offenbar Channels mit anderen Nodes. Lightning frisst plötzlich alle Systemressourcen meines VPS.

Mein Port ist offen, der Autopilot arbeitet: Plötzlich ist einiges los bei meinem Lightning-Client.

Aber dafür bin ich auf 1ml.com zu sehen. Ich bin stolz, nun einen vollwertigen Lightning-Node zu haben, klopfe mir auf die Schulter und mache zufrieden Pause.

6. Geld empfangen

Nun aber zu der schwierigen Frage, wie man mit Lightning Geld empfängt. An sich muss man nur eine Invoice bilden mit lncli addinvoice 5000. Die 5000 steht für 5000 Satoshi und kann durch jeden beliebigen Betrag ersetzt werden. Lncli spuckt nun eine Invoice aus, die in meinem Fall so aussieht:
"r_hash": "8b552c600ceeb5c5906cd043667dfc34c4e92afa6f12ec92531bb033f14c2691",
"pay_req": "lnbc50u1pdcv7k6pp53d2jccqva66utyrv6ppkvl0uxnzwj2h6dufweyjnrwcr8u2vy6gsdqqcqzysune4jtuuy8y6u53s4tpe5zsgeuyy8d2vlcwtv92nd3z05veh0z5k83030d49v0lg5r44cy9j6quxkwc55tnln5q83c5vd0fyd7nwusqp0k08r7",
"add_index": 161

Um bezahlt zu werden, muss ich dem Sender einfach nur die pay_req zukommen lassen. Bevor ich mir überlege, wie ich das mache, muss ich mich aber erst um ein anderes Problem kümmern: Wie bekomme ich genügend eingehende Liquidität in meine Channels?

Wenn man selbst einen Lightning-Channel öffnet, steckt man ein wenig Geld hinein, das man ausgeben kann. Ein frischer, von mir gebildeter Channel sieht so aus, dass beispielsweise 0,1 Bitcoin bei mir und 0,0 Bitcoin bei meinem Partner liegen. Ich kann bis zu 0,1 Bitcoin in die andere Richtung schubsen, aber der andere kann derzeit nur 0,0 Bitcoin, also gar nichts, zu mir weiterleiten. Mit einem solchen Channel kann ich kein Geld zu empfangen.

Also warte ich ein wenig, ob jemand einen Channel zu mir eröffnet. Allerdings passiert das nicht. Offenbar ist mein Knoten nicht interessant genug. Ich könnte nun natürlich bei Bitrefill Gutscheinkarten für Amazon oder so kaufen, und den Betrag, den ich ausgegeben habe, wieder einnehmen. Aber das wäre witzlos und skaliert auch nicht wirklich gut. Also frage ich herum, hier auf dem Blog, im Coinforum, und per Twitter. Nach ein bis zwei Stunden habe ich dank der netten Hilfe der Lightning-Community etwa 1000 Euro eingehende Liquidität. Das reicht erstmal.

Wenn ich jetzt mit lncli addinvoice eine neue Zahlungsaufforderung bilde, kann sie auch bedient werden. Aber ich kann kaum jedesmal manuell den Befehl eingeben, wenn mir jemand etwas spenden will. Also muss ich das irgendwie automatisieren. Dafür nehme ich meine Domain Bitcoin-Buch.org und richte eine Lightning-Seite ein. Die Idee ist, dass ich mit PHP irgendwie das VPS ansteuere, um eine Invoice herauszukriegen.

Nach einigem Googeln finde ich heraus, dass man mit der PHP-Erweiterung „phpseclib“ SSH benutzen kann. Es brachte mich fast zur Verzweiflung, dass einem niemand erzählt, wie man die Erweiterung installiert, kam aber am Ende darauf, dass ich sie einfach in mein Verzeichnis hineinkopieren muss. Danach konnte ich mich mit dem folgenden PHP-Code in mein VPS einloggen und eine Zahlungsaufforderung kreieren kann:

// include library
//set_include_path('phpseclib');
//set_include_path('includes/classes/net');
include('Net/SSH2.php');
include('Crypt/RSA.php');
// connection parameters
$config = array(
'host' => '185.169.97.66',
'port' => '22',
'username' => 'MeinUserName',
'password' => 'MeinPassWort',
);
// connect
$ssh = new Net_SSH2($config['host'] . ':' . $config['port']);
if (!$ssh->login($config['username'], $config['password'])) {
echo('Login via ssh at host ' . $config['host'] . ' failed.');
} else {
echo $ssh->exec("lncli addinvoice");
};

Der Code ist natürlich höchst unsicher. Bitte benutzt ihn nicht! Und wenn, dann solltet ihr sicher sein, dass über den GET-Parameter kein Schadcode eingeflöst werden kann. Das hier ist nur zu Test- und Spielzwecken für mich und sollte NIEMALS benutzt werden, wenn echtes Geld im Spiel ist.

Natürlich kann man nun noch relativ einfach eine Variable mit dem Betrag einfügen und so weiter. Ein Problem war nun aber, dass die Zahlungsaufforderung als gesamter String ankommt. Um das Payment-Request, das der Sender braucht, herauszufiltern, muss ich den String in ein JSON umbauen, und in diesem dann das Request finden. Es hat ein wenig gedauert und mich einige Nerven gekostet, aber am Ende funktionierte es mit etwa diesem Code:

$lncli = 'lncli addinvoice ' . $betragKrypto;
$string = $ssh->exec($lncli);
$string = str_replace('\n', '', $string);
$string = rtrim($string, ',');
$string = "[" . trim($string) . "]";
$json = json_decode($string, true);
$paymentrequest = $json[0]["pay_req"];

Vielleicht hilft das ja jemandem, der vor ähnlichen Problemen steht. Indem ich dieses Invoice nun mit einem schnöden HTML-Formular verbinde, kann ich individuelle Spenden für das Blog entgegennehmen. Ihr könnt es auf Bitcoin-Buch.org/Lightning ausprobieren.

Aber zuvor möchte ich noch ein letztes Detail vorstellen: Wie man erfährt, ob man bezahlt wurde.

7. Eine Zahlung mit Lightning erkennen

Mittlerweile mag ich LND. Der Daemon läuft stabil und verbraucht relativ wenig Systemressourcen, und der Client, lncli, hat recht intuitive Befehle. Man findet sich rasch darin zurecht.

Die Befehle von lncli: Schön intuitiv und übersichtlich.

Dennoch ist es für mich recht unübersichtlich, ob ich nun Geld erhalten habe, und wenn ja, wie viel und woher. Man kann bei lncli mit zwei Befehlen Guthaben prüfen: lncli walletbalance schaut nach dem Guthaben onchain. Es ist möglich, dass dieses vom tatsächlichen Guthaben erheblich abweicht.

Der andere Befehl ist lncli channelbalance. Er zeigt an, wie das Guthaben in den Channels ist. Auch das finde ich recht verwirrend, da ich nicht weiß, ob es zu- oder abgenommen hat. Einmal schaue ich und stelle fest, dass es im Vergleich zu vor fünf Minuten weniger geworden ist, obwohl ich keine Zahlung abgesendet habe. Damit ist meine Verwirrung komplett.

Am übersichtlichsten scheint noch die Einsicht in die Invoices sein. Mit lncli listinvoices kann ich mir die Invoices anzeigen lassen. Das werden nach einigen Tests schon ziemlich viele, und offenbar gibt es noch keine Funktion, Invoices löschen zu lassen. Die Datensätze für die Invoices haben eine Variable „settled“, die entweder „true“ oder „false“ ist. Ich nehme an, mit ihr kann man herausfinden, ob eine Zahlungsaufforderung erfüllt wurde.

Wer nicht alle invoices manuell durchsuchen möchte, muss recht umständlich über mehrere Schritte die Invoice dekodieren.

Vermutlich könnte man sich ein recht komplexes System bauen, das Walletbalance, Channelbalance, die einzelnen Channels und die Invoices fortlaufend in eine Datenbank einträgt und auch Buch über jede Veränderung führt. Das ist mir aber derzeit noch zuviel. Ich entscheide mich zunächst dafür, einfach per PHP bzw. SSH zu fragen, ob eine Invoice erfüllt wurde, und das Ergebnis auf meiner Spendenseite mitzuteilen.

Getestet habe ich es noch nicht, da ich mir mit Lightning nicht selbst etwas schicken kann (zumindest weiß ich nicht, ob es geht). Wenn jemand von euch eine Lightning-Wallet parat hat, würde ich mich freuen, wenn ihr auf Bitcoin-Buch.org/lightning ein paar Satoshis an mich spendet und testet, ob meine Webseite es erkennt, wenn eine Invoice bezahlt wurde. Es wäre ziemlich grandios, wenn es funktioniert.

Ich habe den Verdacht, dass es ein paar Sekunden bis Minuten dauert, bis die Zahlung bei mir als „settled“ angezeigt wird. Falls es jemand versucht, wäre es interessant zu erfahren, was nach ein paar Minuten passiert.

Update: Ich habe das Verfahren mittlerweile geändert, indem ich die Balance der Channels abfrage. Mal sehen, ob das besser klappt.

Daher schon mal vielen Dank dafür. Morgen oder übermorgen werde ich hier ein erstes Resümée aus meiner Beschäftigung mit Lightning veröffentlichen.

Die mobile Version verlassen