The Lightning Network: How to install and (hopefully) make money

Ronald Mannak
Jul 18, 2018 · 14 min read

Note: This document was written in July 2018. Lightning is new and improving fast. If you find any out-of-date information or omissions, please leave a comment.

Image for post
Image for post

Lightning is an intriguing new technology that promises (lightning) fast transactions at a scale that is unheard of for Bitcoin. And now that Lightning is live on the Bitcoin mainnet, it is also a potential money maker.

Unfortunately, I’ve also found that Lightning is extremely hard to install, and I’ve wasted many hours setting up a node. I’m sharing my experiences so others will hopefully have a smoother experience.

This blogpost only describes the installation process, and assumes the reader is proficient in setting up a server. To learn more about Lightning itself, check the excellent white paper. To learn more about the economics behind Lightning, see The Economics of Lightning Network Fees. LnRoute lists many helpful resources.

Warning: Lightning is not for the faint of heart. There are known and unknown issues. The wallet’s private key will be stored on the Lightning node, and the node will have to be online 24/7 to route transactions. As always with crypto, do not experiment with more btc than you’re prepared to lose. (Or experiment on Testnet. But where’s the fun in that?).

Prerequisites

This tutorial assumes you’re using a Mac to connect to the VPS. Using Linux or Windows shouldn’t be too different though.

Your Lightning node has to be always online to forward payments.

If you want to run a Lightning Network Node hassle-free, check these Lightning network and Bitcoin node providers.

Setup Digital Ocean

  1. Create an account
  2. Create a new droplet
  3. Create SSH key pair
  4. Log in

Use the following referral link to create an account on Digital Ocean and receive $10 (I will receive $25).

Create a new droplet

Image for post
Image for post

On the Create Droplet page, select the One-click apps tab and the Docker option, and select the 320GB option on the same page.

Image for post
Image for post
Image for post
Image for post

Next, we’re going to create a new SSH key pair by entering the following command in the Terminal:

# 1. Create SSH key pair. "lightning" will be the filename
# Enter a passphrase to secure the file
$ ssh-keygen -f ~/.ssh/lightning -t rsa -b 4096
# 2. Backup lightning and lightning.pub files
$ cd ~/.ssh
$ (Make a safe backup)
# 3. Copy the public key to the clipboard
$ pbcopy < ~/.ssh/lightning.pub

Back in the browser, click on the New SSH Key button and paste the public key (copied to the clipboard in step 3 above) into the text box, and click the Create button to create the droplet.

Image for post
Image for post

Once the droplet is created, copy the ip-address of the droplet.

# Log in.
$ ssh root@<droplet's ip-address> -i ~/.ssh/lightning

Install bitcoind

I followed the steps in Doug von Kohorn’s Lightning post.

  1. Make sure to be logged in on your server.
  2. Install Bitcoind Docker image.
  3. Download the Bitcoin blockchain.
  4. Create a convenience script for easy access to the bitcoind container
  5. Wait while the blockchain is downloading.

Log in if you’re not logged in already.

# Log in.
$ ssh root@<droplet's ip-address> -i ~/.ssh/lightning

Create a bitcoind Docker container using the dockerfile which is (confusingly) located in a repo called lightning-node.

Bitcoind will save the blockchain and all settings on the disk, not in the container itself. This way, all data will persist, even if we replace the bitcoind container with an updated version.

# 1. Clone the bitcoind repo. (don't let the lightning 
# node project name fool you, this will install bitcoind)
$ git clone https://github.com/dougvk/lightning-node.git
# 2. Build the bitcoind Docker container.
$ cd lightning-node
$ docker build . -t dougvk/bitcoind
# 3. Create a working directory outside of the Docker image,
# so the working directory won't be overwritten when you
# update the Docker image with a new bitcoind version.
$ mkdir -p /scratch/bitcoin/mainnet/bitcoind
# 4. Run bitcoind and start downloading the blockchain.
$ docker run --name bitcoind -d -v /scratch/bitcoin/mainnet/bitcoind:/data -p 8333:8333 -p 9735:9735 dougvk/bitcoind:latest

Add a convenience script to access the bitcoind container:

# 1. Create script.
$ touch /bin/bitcoin-cli
# 2. Make script executable.
$ chmod +x /bin/bitcoin-cli
# 3. Edit script (See below).
$ nano /bin/bitcoin-cli
# 4. Confirm script is working. This command shows the wallet info.
$ bitcoin-cli getwalletinfo

In Nano (step 3 above), edit the bitcoin-cli script as follows:

#!/usr/bin/env bash
docker run --rm --network container:bitcoind -v /scratch/bitcoin/mainnet/bitcoind:/data dougvk/bitcoind:latest bitcoin-cli "$@"

At the time of writing, the Bitcoin blockchain is 175GB in size. The blockchain download should already be in progress and will take up to 24 hours to complete. Take a break, a nap or a short vacation while the blockchain is downloading.

Check the status of the download by entering the following command. When the download is complete, the latest downloaded block should have today’s date.

# Check the blockchain download progress.
$ docker logs bitcoind --tail "10"

Install C-Lightning

I found this step more complicated than I expected and wasted time trying to use the lnd implementation. In the end I gave up on lnd and switched to C-Lightning. (Since the software and documentation is updated on an almost daily basis, it is entirely possible that lnd will be easier to install by the time you read this.) Installing C-Lightning should take about 30 minutes.

  1. Make sure to be logged in on your server.
  2. Create a C-Lightning docker image and sync the Lightning network.
  3. Create a convenience script for easy access to the bitcoind container.
  4. Set name and other options

Log in if you’re not logged in already.

# Log in.
$ ssh root@<droplet's ip-address> -i ~/.ssh/lightning

Create the C-Lighting docker image and a scratch directory on disk so the data will persist even if we replace the lightning docker container.

# 1. Create a working directory outside of the Docker image,
# so the working directory won't be overwritten when you
# update the Docker image with a newer C Lightning version.
$ mkdir -p /scratch/bitcoin/mainnet/clightning
# 2. Create the Lighting docker image.
$ docker run --rm --name lightning --network container:bitcoind -v /scratch/bitcoin/mainnet/bitcoind:/root/.bitcoin -v /scratch/bitcoin/mainnet/clightning:/root/.lightning --entrypoint /usr/bin/lightningd elementsproject/lightningd --network=bitcoin --log-level=debug

The Lightining node should now be downloading the Lightning network, which should take about 10 minutes.

Since the last command doesn’t return to the command prompt, open a new Terminal window or tab and log in again.

# Log in.
$ ssh root@<droplet's ip-address> -i ~/.ssh/<filename>

Next, we’ll create a convenience script to access the Lightning client.

# 1. Create script.
$ touch /bin/lightning-cli
# 2. Make script executable.
$ chmod +x /bin/lightning-cli
# 3. Edit script (See below).
$ nano /bin/lightning-cli
# 4. Confirm script is working.
$ lightning-cli getinfo

In Nano (step 3 above), edit the lightning-cli script as follows:

#!/usr/bin/env bash
docker run --rm -v /scratch/bitcoin/mainnet/clightning:/root/.lightning --entrypoint /usr/bin/lightning-cli
elementsproject/lightningd "$@"

I haven’t found the complete documentation of all config file options. If you’ve found one, please leave a comment. A basic config file sets the name of the Lightning node and the color the name appears in Lightning explorers, such as Recksplorer.

# 1. Create config file
$ touch /scratch/bitcoin/mainnet/clightning/config
# 2. Edit and save config file (see below)
$ nano /scratch/bitcoin/mainnet/clightning/config

My config file is as follows. I’ve named my node Punchbeef✅ (yes, a Mystery Science Theater 3000 reference) and set its color to orange. The color is used various Lightning explorers and provides an way to stand out.You obviously want to change the alias and the color (unless you like orange). To ensure more stable channels, Chang Li of FirstBlock suggested to add bind-addr and announce-addr to the config file. However, bind-addr didn’t seem to work as expected.

alias=Punchbeef✅           # Change the alias, obviously
rgb=FF4500
#bind-addr=0.0.0.0:9735 This doesn't seem to work yet
announce-addr=<droplet's ip-address>:9735

Restart the Lightning node to the update the changes.

# 1. Stop the Lightning node
$ lightning-cli stop
# 2. Start the Lightning node
# Note: this creates a new container. How do we restart
# the existing one? Any Docker experts here?
$ docker run --rm --name lightning --network container:bitcoind_mainnet -v /scratch/bitcoin/mainnet/bitcoind:/root/.bitcoin -v /scratch/bitcoin/mainnet/clightning:/root/.lightning --entrypoint /usr/bin/lightningd elementsproject/lightningd --network=bitcoin --log-level=debug

We now have a fully functional Lightning node running on mainnet.

Note: If you prefer to use lnd over C-Lightning, the undocumented command to install lnd on mainnet is as follows. For support, check their active Slack.

# Don't use unless you want to install LND, instead of C-Lightning!$ docker create --name=lnd lightninglabs/lnd --bitcoin.active --bitcoin.mainnet

Setting fees

I was expecting to be able to set fees to optimize for more traffic. Unfortunately, I haven’t found a way to do that yet and am currently using the default settings. If anyone knows the solution or has suggestions, please leave a comment.

Connecting to nodes and creating Channels

Funding channels is a two step process: you first send btc from your current wallet to the node’s wallet, and then you fund the channel with btc from the node’s wallet. Creating and funding channels will take about two hours and will involve the following steps:

  1. Create a Bitcoin address for the node’s wallet.
  2. Send btc to the address created in step 1 and wait for six confirmations.
  3. Connect to any Lightning node of your choosing to create a channel.
  4. Fund the channel with btc from step 2 and wait for six confirmations.

As with any other Bitcoin wallet, you can create multiple addresses for a single wallet. Send a small amount of btc to the Lightning wallet, like so:

# 1. Create new address. 
$ lightning-cli newaddr
# 2. Send btc to the address generated above and wait for six
# confirmations. Check status at:
# https://www.blockchain.com/btc/tx/
# 3. Confirm the funds have been received.
$ lightning-cli listfunds

When needed, use the dev-listaddrs command to list all addresses of your Lightning wallet:

# List all addresses of your Lightning wallet.
$ lightning-cli dev-listaddrs

Next, connect to one or more other Lightning nodes.

# 1. Connect to another Lightning node. The parameters are 
# the Lightning id, and optional ip-address and port.
# The command below connects to the author's Punchbeef✅ node.
$ lightning-cli connect 02060d0c8577cfc2a1962220a1cde4f623ca55ef80bd25e4be5a8b15fed78b11a3@178.62.237.239
# 2. Confirm your node is connected to the node in step 4, and
# the state is "GOSSIPING".
$ lightning-cli listpeers

Looking for nodes to connect to? Recksplorer is a live Lightning network map that can be used to find other nodes you might want to connect to. Other great resources are the Lightning Network Stores list, and the Y’alls list. 1ml maintains a list of the largest nodes in terms of btc and nodes with most channels.

I funded most channels with 318 kSatoshi (approx. 20 USD). Some hosts required a higher minimum, to which I conformed. I also checked the prices of the goods the merchants sold and made sure the channel had enough satoshi for a purchase of at least the cheaper items in the store.

Funding a channel is a channel is an on-chain event and needs to be confirmed.

# 1. If needed, list connections. Unfunded channels will have 
# state set to 'GOSSIPING'
$ lightning-cli listpeers
# 2. Fund the channel to peer ID 02060... belonging to Punchbeef✅
# with 400 kSat.
$ lightning-cli fundchannel 02060d0c8577cfc2a1962220a1cde4f623ca55ef80bd25e4be5a8b15fed78b11a3 400000

And boom. We’re live.

Payments

Image for post
Image for post
# 1. Connect to the Y'alls node
$ lightning-cli connect 03e50492eab4107a773141bb419e107bda3de3d55652e6e1a41225f06a0bbf2d56@mainnet-lnd.yalls.org
# 2. Fund outbound channel with 1 mSat and wait for confirmation
$ lightning-cli fundchannel 03e50492eab4107a773141bb419e107bda3de3d55652e6e1a41225f06a0bbf2d56 1000000
# 3. Confirm the channel state is CHANNELD_NORMAL
$ lightning-cli listpeers 03e50492eab4107a773141bb419e107bda3de3d55652e6e1a41225f06a0bbf2d56
# 4. Browse to https://mainnet.yalls.org/about/, locate the 'Join
# the Y'alls Community' box and select your node from the
# dropdown list and click 'Attempt Channel Open'.
# 5. Copy the invoice starting with "lnbc" from the bottom box# 6. Pay Y'alls node to create inbound channel using the invoice
# copied in step 5.
$ lightning-cli pay <lnbc...>

Closing channels and withdraw funds

  1. Find the id of the channel you want to close
  2. Close channel
  3. Profit!

Just like funding a channel, closing one is also an on-chain event and needs to be confirmed.

# 1. Show funded channels to look up channel id.
$ lightning-cli listfunds
# 2. Close channel. Command should return a txid, which is
# verifiable on https://www.blockchain.com/btc/tx/
$ lightning-cli close xxxxx:xxx:x
# 3. After about one hour, the channel should be removed
# from the list, and a utxo should be added to the utxo list.
# You may need to rescan the outputs to see the latest updates.
$ lightning-cli dev-rescan-outputs
$ lightning-cli listfunds

Backups

My first instinct was to back up the state of the channels themselves. But that turned out to be a bad idea, according to this Github issue, which is probably the best resource on Lightning backups.

To understand why you should never back up channel states, you have to understand how the Lightning protocol punishes dishonest nodes. One attack vector is to propagate an old state of a channel, which is exactly what could happen if you back up channel states. The punishment for propagating an old state is confiscation of all funds in a channel by the peer. In other words: you risk losing all your funds in the channels if you try to backup and restore an a channel state.

The channel states are saved in the lightning.sqlite3 file in the /scratch/bitcoin/mainnet/clightning/ directory. Never back up the lightning.sqlite3 file.

Instead, backup the hsm_secret file in the /scratch/bitcoin/mainnet/clightning/ directory. The following command copies the hsm_secret file to your local home directory.

# Run from your local computer. <filename> is the ssh file on 
# your local drive, <ip-address> is your lightning
# server's IP address.
$ scp -i <filename> root@<droplet's ip-address>:/scratch/bitcoin/mainnet/clightning/hsm_secret ~

The steps to recover the funds are copied from the GitHub issue metioned above: Copy hsm_secret on a clean install and start lightningd with the--port=0 option. Do not connect or fund any channel. Run lightning-cli newaddr a few times, then shut down lightning with lightningd stop. Run sqlite3 /scratch/bitcoin/mainnet/clightning/lightningd.sqlite3 "UPDATE vars SET val= 500000 WHERE name='last_processed_block';" Run lightningd again with the --port=0 option. Recover on-chain funds to your personal wallet by running lightning-cli withdraw all. Then wait up to a few months for the peers to close your old channels. Once all channels are closed, recover your funds that were previously stuck in the channels with lightning-cli withdraw all.

Since you’re not able to create or fund new channels without disrupting the recovery process, you will need to set up a second server to continue running a lightning node.

Errors and solutions

No address known, giving up

Not enough funds to open channel

# 1. Rescan outputs if funds are 'missing'
$ lightning-cli dev-rescan-outputs
# 2. Confirm all bitcoins are still there.
$ lightning-cli listfunds

Connection refused

Unable to fund a channel

# Outputs the nodes in Gossiping state
$ lightning-cli listpeers | jq '.peers[] | select(.state == "GOSSIPING") | .'

Fund each nodes returned:

# Fund channel
$ lightning-cli fundchannel <peer-id> <amount>

CHANNELD_AWAITING_LOCKIN and CHANNELD_SHUTTING_DOWN

# List all channels that were not opened correctly
$ lightning-cli listpeers | jq '.peers[].channels[] | select(.state != "CHANNELD_NORMAL") | .'

Ignore channels with status CHANNELD_AWAITING_LOCKIN:Funding needs more confirmations.

The issue is discussed in this GitHub issue, I‘m currently still waiting to see if it will resolve eventually, even though the channels are stuck in these states for about a week already.

Thanks

Was this post helpful?

# 1. Connect to punchbeef✅
$ lightning-cli connect 02060d0c8577cfc2a1962220a1cde4f623ca55ef80bd25e4be5a8b15fed78b11a3@178.62.237.239
# 2. Fund channel
$ lightning-cli fundchannel 02060d0c8577cfc2a1962220a1cde4f623ca55ef80bd25e4be5a8b15fed78b11a3 400000

Also, Read

Get Best Software Deals Directly In Your Inbox

Image for post
Image for post

Coinmonks

Coinmonks is a non-profit Crypto educational publication.

Sign up for Coinmonks

By Coinmonks

A newsletter that brings you week's best crypto and blockchain stories and trending news directly in your inbox, by CoinCodeCap.com Take a look

By signing up, you will create a Medium account if you don’t already have one. Review our Privacy Policy for more information about our privacy practices.

Check your inbox
Medium sent you an email at to complete your subscription.

Ronald Mannak

Written by

Open source blockchain developer.

Coinmonks

Coinmonks

Coinmonks is a non-profit Crypto educational publication. Follow us on Twitter @coinmonks Our other project — https://coincodecap.com

Ronald Mannak

Written by

Open source blockchain developer.

Coinmonks

Coinmonks

Coinmonks is a non-profit Crypto educational publication. Follow us on Twitter @coinmonks Our other project — https://coincodecap.com

Medium is an open platform where 170 million readers come to find insightful and dynamic thinking. Here, expert and undiscovered voices alike dive into the heart of any topic and bring new ideas to the surface. Learn more

Follow the writers, publications, and topics that matter to you, and you’ll see them on your homepage and in your inbox. Explore

If you have a story to tell, knowledge to share, or a perspective to offer — welcome home. It’s easy and free to post your thinking on any topic. Write on Medium

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store