Till it’s lightning-fast — Uncover the Lightning Network Transactions
A down-to-earth explanation of how the implementation of the lightning network works. Prior knowledge of the UTXO, Bitcoin Script, and digital signature are required. A good understanding of the rationality of the Revocable Sequence Maturing Contract and Hash Time Locked Contract is recommended.
The lightning network, like Bitcoin, is a masterpiece created by the open source community. The Lightning Network Specifications guide the deployment of the network, while few educational resources can be found online. This article is meant to be a supplement, explaining in detail how and why the transaction works in the lightning network.
Overview
The transactions in the lightning network are no more than a chain of commitment transactions spending the outputs in the funding transaction. Today’s lightning network took the idea of the RSMC and made several enhancements. First, it applied a commitment scheme(the hide-and-reveal scheme) to enable payment forwarding. Second, it replaced the multisig function with elliptic curve point multiplication in revocations.
Structure of Transactions
There are four types of transactions in the lightning network, two of them transfer money between the lighting network and the Bitcoin network(cross-layer transactions), the other two update balances in the lightning network(layer-two transactions).
- Funding transaction. A funding transaction is created during the channel opening. It moves money from the Bitcoin network into the lightning network and puts the funds into a multisig address.
- Commitment transaction and HTLC transactions. The commitment transaction serves as the building block of the lightning network. Whenever a balance update is made, commitment transactions are created. HTLC transactions, or the HTLC-Success and HTLC-Timeout transactions, were originally put in the commitment transaction and taken out in the final design. As explained later, HTLC transactions can be viewed as part of the commitment transaction as it’s their mere purpose to spend the outputs specified in the commitment transaction.
- Closing transaction. A closing transaction is created when two participants decide to close the channel corporately. It moves money from the lightning network into the Bitcoin network.
Commitment Transaction as A Means of Accounting
A commitment transaction has two to four types of outputs, depending on whether it’s forwarding payments or not, and listed as below,
- Local Output, which records how much money the local participant has.
- Remote Output, which records how much money the remote participant has.
- Credit Output, or the incoming HTLC, the received HTLC, which records how much money the local participant is receiving.
- Debit Output, or the outgoing HTLC, the offered HTLC, which records how much money the local participant is sending.
Credit Output and Debit Output are created when the participant is making or forwarding payments to others. To visualize,
The lightning network has intensively worked on the Bitcoin scripts, securing the outputs to make sure they will be spent as intended.
Revocation — Keys and More Keys
Overall, for a layer-two transaction to function, it shall be refundable and revocable, which corresponding to two scenarios,
- When one participant stays unresponsive for a given period, the counterparty gets refunded.
- When a new transaction is made, the old transaction gets revoked.
The revocation transaction, sometimes called the Breach Remedy Transaction, exists to be the deterrence against any malicious activities, which is the core element that makes the lightning network safe.
The implementation of the lightning network uses revocation key pairs instead of the multisig function. The cryptographic hash function involved is the Elliptic Curve Digital Signature Algorithm(ECDSA), along with the Elliptic Curve Point Multiplication. The process is as follows,
Alice and Bob each generate a private-public key pair based on the ECDSA, marked as alice_public_key
, alice_secret_key
, bob_public_key
and bob_secret_key
.
A revocation_public_key
is constructed using alice_public_key
and bob_public_key
. For simplicity, it’s formula can be viewed as,
revocation_public_key = alice_public_key + bob_public_key
And it’s corresponding private key revocation_private_key
is calculated as
revocation_private_key = alice_private_key + bob_private_key
Since it’s a private-public key pair, messages signed by the revocation_private_key
will produce a revocation_signature
, and anyone can verify the signature by looking at the revocation_public_key
with the message. While the math is different, it requires keys from both Alice and Bob to generate a valid signature like the multisig function. This method is more favorable because it’s believed to be more intuitive and efficient.
With the above background, we will analyze how the open/update/close a channel works in detail.
Open A Channel — Funding Transaction and the First Commitment Transaction
The process to open a channel between Alice and Bob with Alice funding 1 BTC is as follows,
First, before any transactions, initial settings of the channel are negotiated and settled, such as the minimal confirmations needed for the funding transaction and public keys for producing the revocation keys, which,
- For Alice, she creates public keys
alice_pubkey_tx_a1
andalice_pubkey_tx_b1
, sends them to Bob. The corresponding private keysalice_prikey_tx_a1
andalice_prikey_tx_b1
are kept to herself. - For Bob, he creates public keys
bob_pubkey_tx_a1
andbob_pubkey_tx_b1
, sends them to Alice. The private keysbob_prikey_tx_a1
andbob_prikey_tx_b1
are kept to himself. - Alice uses
alice_pubkey_tx_a1
andbob_pubkey_tx_a1
to generate therevocation_pubkey_tx_a1
, which can validaterevocation_sig_tx_a1
. - Bob uses
alice_pubkey_tx_b1
andbob_pubkey_tx_b1
to generate therevocation_pubkey_tx_b1
, which can validaterevocation_sig_tx_b1
.
Second, Alice creates a funding transaction, signs it, and shares its Transaction ID
and Output Number
with Bob.
Third, Alice and Bob each create the first commitment transaction based on the funding transaction, sign it, and exchange their signatures.
Finally, Alice confirms the signatures match and broadcasts the funding transaction.
About the naming of the keys
Abbreviations are used to shorten the names of the keys. Public key is abbreviated as
pubkey
, private key is abbreviated asprikey
, and signature issig
. For example,alice_funding_sig
means the signature used for unlocking the funding transaction from Alice.Whenever there is a
revocation_
in a key, it means it’s generated from Alice and Bob’s keys. For example, arevocation_pubkey_tx_a1
is generated usingalice_pubkey_tx_a1
andbob_pubkey_tx_a1
. Arevocation_prikey_tx_a1
is generated usingalice_prikey_tx_a1
andbob_prikey_tx_a1
.Whenever there is a
tx_
in the revocation key, it means the key is used to revoke that particular transaction. For example,revocation_sig_tx_a1
is used to revoke Alice’s transactionTX A01
. For now, Bob’s transactions do not incorporate revocation yet, but soon it will be used.Finally, a
revocation_sig_tx_a1
is produced byrevocation_prikey_tx_a1
, and can be validated usingrevocation_pubkey_tx_a1
.
Once the funding transaction gets the minimal N
confirmations, the channel is established and remains open. The value N
is proposed by Alice and can get rejected by Bob if it’s unreasonably large.
A Remote Output is treated differently compared to a Local Output, as a local participant a) cannot spend a Remote Output and b) has no interest in broadcasting it. For example, Bob has no interest in broadcasting TX B01
, as doing so won’t do him any good and that’s why a revocation key(revocation_sig_tx_b1
) is not put. However, a Local Output needs to have both revocation and timeout because the local participant has the motivation to cheat while the ability to refund is required in case the remote participant becomes unresponsive. The rationality is illustrated in the following section.
Update Channel Balances — the Second and Many Commitment Transactions
The most complicated process happens during updating channel balances. When the channel balances change, it’s reflected in the new commitment transactions. The money received/sent is recorded in the Credit/Debit Outputs, and their old revocation-related private keys are exchanged.
For instance, if Alice sends Bob 0.1 BTC, they will both create new transactions and exchange keys. First is their old revocation-related private keys, alice_prikey_tx_a1
and bob_prikey_tx_b1
are exchanged. Now that Bob has the alice_prikey_tx_a1
, he can derive the revocation_prikey_tx_a1
to generate revocation_sig_tx_a1
, which unlocks the Local Output in TX A01
. Second is their new revocation-related public keys, alice_pubkey_tx_a2
, alice_pubkey_tx_b2
, bob_pubkey_tx_a2
and bob_pubkey_tx_b2
are exchanged to produce revocation_pubkey_tx_a2
and revocation_pubkey_tx_b2
, which are used in their new commitment transactions.
In Alice new commitment transaction, TX A02
, it has two outputs,
- A Local Output, which records her current balance, 0.9 BTC.
- A Debit Output, which records the money she has sent to Bob, the 0.1 BTC.
And for Bob, TX B02
, similarly,
- A Remote Output, which records Alice’s balance, 0.9 BTC.
- A Credit Output, which records the money he has received, the 0.1 BTC.
Before tackling the design of the Credit/Debit Outputs, let’s first review why the Local and Remote Outputs are solid.
Secure Local and Remote Outputs
It’s clear that Bob has no motivation to broadcast the older transaction TX B01
because his money is in TX B02
. However, for Alice
- If Bob disappears, she can broadcast
TX A02
to refund herself and spend the money in two weeks. - If Alice broadcasts
TX A02
, Bob has no way to spend its Local Output because he doesn’t haverevocation_prikey_tx_a2
, which is derived fromalice_prikey_tx_a2
andbob_prikey_tx_a2
. - If Alice broadcasts
TX A01
, she has to wait two weeks before it’s spendable. Meanwhile, Bob will usealice_prikey_tx_a1
andbob_prikey_tx_a1
to deriverevocation_prikey_tx_a1
, which can producerevocation_sig_tx_a1
to unlock the output, and take all the money as a penalty to Alice.
Thus updating Local and Remote Outputs is safe. The receiver won’t worry the sender will cheat, and the sender won’t worry the receiver may disappear(a detailed analysis is covered in Till it’s lightning-fast — Uncover the Development of the Lightning Network, check the Update Channel Balances part if needed).
The harder question is how can we secure the Credit/Debit Outputs?
Make Payments with Revocation
Suppose Bob has a golden goose and agrees to sell it to Alice for 0.1 BTC(why? Because chicken is our best friend!). It’s up to Bob to initiate the payment request. The process is as follows,
- Bob generates a secret
payment_secret
and keeps it to himself. - Bob hashes the
payment_secret
to produce apayment_hash
and sends it to Alice. - Alice creates a new commitment transaction, in which the Debit Output can be spent with either condition — if 3 days passed, Alice gets the money or if Bob can provide the
payment_secret
, Bob gets the money. - Bob creates a new commitment transaction, in which the Credit Output can be spent with the same conditions.
Keep in mind that,
- If Bob provides
payment_secret
in 3 days, he shall get the money. If 3 days passed, even if Bob providespayment_secret
, he shall not get the money. In other words, the condition for Bob to own the money needs a) he knowspayment_secret
and b) he reveals it to Alice within 3 days. In our case, since Bob generated thepayment_secret
, he knew the value from the beginning. - If 3 days passed, the money shall go to Alice, under the condition that Bob cannot provide the
payment_secret
in 3 days. In other words, if Bob reveals thepayment_secret
within 3 days but he doesn’t spend the output, Alice shall not own the money when 3 days passed.
It’s perplexing, I know. As the principle of the lightning network is to make sure the transactions hit the Bitcoin network as infrequent as possible, we want to design a way that Alice and Bob can both feel safe about their money without broadcasting their commitment transactions and keep the channel long open. In our case, if Bob knows the payment_secret
within 3 days, it doesn’t require him to broadcast the transaction to prove that statement.
So before Bob ships his beloved golden goose, we need to understand the timelock in depth.
Timelock in Bitcoin
Two types of timelock are used in Bitcoin, one is an absolute timelock, the other is a relative one. Their difference is as simple as “meet me at 3:00 p.m.” verses “meet me in 2 hours”, with the relative timelock starts the countdown when the transaction is mined. Depending on where the timelock is placed, it can control when a transaction can be broadcasted or its outputs can be spent. Inside each transaction, three locations are used to specify a timelock,
- In the input section, each input has a
nSequence
field that is used to specify a relative timelock. - In the output section, inside each output’s locking script, a
CheckLockTimeVerify
(CLTV) specifies an absolute timelock, and aCheckSequenceVerify
(CSV) specifies a relative timelock. - In the transaction level, an
nLocktime
is used to specify an absolute timelock.
The lightning network has implemented nLocktime
, CheckSequenceVerify
and CheckLockTimeVerify
in its design. An nLocktime
controls when a transaction can enter the blockchain. If a transaction with nLocktime
, 2140/01/01 12am
is encoded, it cannot be broadcasted until over a hundred years later. CheckSequenceVerify
and CheckLockTimeVerify
control when outputs can be spent. If a CheckSequenceVerify
with 30 days is put, the transaction outputs cannot be spent until 30 days later. If a CheckLockTimeVerify
with 2140/01/01 12am
is put, the outputs cannot be spent unless the time 2140/01/01 12am
has reached. Simply put, an nLocktime
controls the transaction’s broadcast time, while CheckSequenceVerify
and CheckLockTimeVerify
control the outputs’ spend time.
Timelock used in the outputs
Outputs with revocation, i.e., the Local and Remote Outputs, use relative timelock because the act of broadcasting an old transaction needs to be exposed. Therefore it will only make sense to start the countdown when an old transaction is broadcasted and mined. For instance, if Alice decides to cheat by broadcasting TX A01
, the moment the transaction gets mined by the miners, she has to wait an extra two weeks to spend its outputs, which leaves time for Bob to react. However, if an absolute timelock is used, e.g., 2019/12/31 23:59:59
, she can wait till the New Year’s Eve, broadcasts and spends it immediately, without Bob’s notice.
Outputs for recording payments, i.e., the Credit and Debit Outputs use the absolute timelock because it’s meant to place pressure on payment claimers(e.g., Bob) without broadcasting the transaction. If Bob cannot provide the payment_secret
before an absolute time, say 6pm today
, Alice will retain the ability to spend the money after 6 p.m. If a relative timelock 3 days
, is used, Bob would be in no rush unless he sees the transaction being broadcasted by Alice, which she cannot spend the outputs until 3 days have passed. Suppose they make this payment at 8:00 am today, and Alice gives Bob 10 hours to reveal his payment_secret
, our updated outputs now look like,
The timelock can solve the aforementioned problem, as neither participant needs to prove their statements by broadcasting their transactions.
Secure Credit and Debit Outputs
It’s already at 5 p.m. Just one hour away, Alice can take the money back by spending her Debit Output in TX A02
. Although Bob has the payment_secret
, it seems that he has to broadcast TX B02
to secure his payment as he has already shipped his golden goose to Alice. Is there a way to stop Alice from cheating? Sure thing. Alice’s Debit Output can be further locked with a relative timelock, say 2 weeks, as shown below,
If Alice broadcasts TX A02
, she has to wait two weeks to spend her money. Meanwhile, once Bob monitors the Bitcoin network and finds out, he will spend the Debit Output immediately with his payment_secret
. Now it’s Alice’s turn to worry. After 6 p.m., if Alice broadcasts TX A02
, Bob with the payment_secret
can still spend the Debit Output, while he is only designed to spend it before 6 p.m. Is there a way to stop Bob from spending it after 6 p.m.?
Instead of putting a timelock in the Debit Output, Alice can spend it anytime she wants, with one condition — she has to create a special transaction to spend it, the HTLC-Timeout transaction.
An HTLC-Timeout transaction uses an absolute timelock(nLocktime
), as shown above,
- It consumes an output from
TX A02
, Output Number 1, which is Alice’s Debit Output. - It has an
nLocktime
of 6 p.m. today, which means this transaction cannot be broadcasted before 6 p.m.
The Debit Output is also changed,
The problem is almost solved. For Alice to claim her money, two steps are involved,
- She needs to broadcast
TX A02
first. - After 6 p.m., she needs to broadcast her HTLC-Timeout transaction.
Before 6 p.m., Alice has no interest in broadcasting TX A02
because she cannot spend its outputs via an HTLC-Timeout transaction due to the nLocktime
and Bob will take the money using the payment_secret
. Once 6 p.m. has passed, even Bob has the payment_secret
, he cannot spend it because the Debit Output has already been consumed by Alice’s HTLC-Timeout transaction. Essentially, the Bitcoin network makes sure every transaction output can only be spent once, although the locking script provides two possible scenarios.
However, the TX A02
and HTLC-Timeout transactions are created by Alice, why would she follow the specified scheme to create the locking scripts?
She won’t, and there is a final change which enables Bob to check the transactions created by Alice are as expected. If Alice wants to spend the Debit Output via an HTLC-Timeout transaction, she will need Bob’s approval.
When creating TX A02
, it consumes an output from the funding transaction, which requires both Alice and Bob’s signatures(alice_funding_sig
and bob_funding_sig
) to unlock. Thus Bob can check TX A02
is created as intended before signing TX A02
and sending his signature bob_funding_sig
to Alice.
The new HTLC-Timeout transaction,
When creating the HTLC-Timeout transaction, it consumes the Debit Output from TX A02
, which requires both Alice and Bob’s signatures(alice_htlc_sig
and bob_htlc_sig
) to unlock. Bob can then check it’s created as intended before signing the HTLC-Timeout transaction and sending his signature bob_htlc_sig
to Alice. This way, Alice will always behave as expected. Overall, we want the participants to feel safe about their money without broadcasting their transactions, thus a great effort has been spent to develop such a complicated scheme. For transaction TX A02
and the HTLC-Timeout, it works as,
- If Bob has the
payment_secret
, he knows for sure that he can get his money before 6 p.m. Because Alice cannot spend the Local Output inTX A02
even if she is willing to broadcast it. - After 6 p.m., Bob won’t be able to spend the output because it will be spent by Alice’s HTLC-Timeout transaction.
By this design, Alice will have no interest in broadcasting TX A02
unless necessary. For Bob, the transaction TX B02
will have a similar structure, followed by an HTLC-Success transaction much like the HTLC-Timeout Transaction.
Bob’s Credit Output can be spent with payment_secret
, alice_htlc_sig
and bob_htlc_sig
together via an HTLC-Success transaction. Like Alice’s HTLC-Timeout transaction, the HTLC-Success is checked and signed by Alice to ensure it’s created as expected.
For Bob to claim his money, he needs to broadcast both TX B02
and HTLC-Success transaction before 6 p.m. Otherwise, Alice can take the money once it’s after 6 p.m.
Update Credit and Debit Balances
Being able to record balances is not enough, we need to update them too. Back to our golden goose case, now Alice is interested in Bob’s golden eggs and she will buy them for 0.05 BTC. To make the deal happen, Alice and Bob have each created the transaction TX A03
and TX B03
to reflect their latest balances.
Similar to how the local and remote balances are secured, the timelock and revocation are used in the Debit and Credit Outputs too.
Prior to the creation of TX A03
and TX B03
, Alice and Bob would exchange their corresponding private keys — Alice gives Bob alice_prikey_tx_a2
and Bob gives Alice bob_prikey_tx_b2
. For TX A02
, the revocation can only be invoked by Bob as Alice doesn’t have the private key bob_prikey_tx_a2
. For TX B02
, it’s reversed as Bob doesn’t have the private key alice_prikey_tx_b2
, the revocation can only be invoked by Alice.
Revocation also goes for the HTLC-Timeout and HTLC-Success transactions.
Notice that the revocation has to exist in both Credit/Debit Outputs and HTLC-Timeout/Success outputs. If only the Debit output has the revocation, Alice could broadcast the old transaction TX A02
and spend its outputs with her HTLC-Timeout transaction. Although Bob can revoke TX A02
, by the time he noticed, the Debit Output would have already been consumed by Alice’s HTLC-Timeout transaction. On the other hand, if only the HTLC-Timeout/Success transactions have the revocation, Alice can broadcast TX A02
only, causing Bob’s money being locked for a while(check the ongoing discussion if interested).
Close the Channel — Hit the Bitcoin Network
There are three ways to close the channel, for Alice and Bob, they can,
- Mutual close, the good way. Alice and Bob can make a closing transaction to close the channel and collect their money immediately.
- Unilateral close via timeout or payment hash, which is considered the bad way as it requires funds being locked for a given time. In our case, Alice can broadcast
TX A03
or Bob can broadcastTX B03
to collect their money, but they have to wait 2 weeks before it’s spendable. - Revocation, the ugly way. If anyone broadcasts an older transaction, the counterparty will use the revocation key to collect the money as a punishment to the cheater.
The Final Analysis — Forwarding Payments
A great effort has been put into the design of HTLC outputs so that the lightning network can forward payments seamlessly. Suppose there are two channels, one between Alice and Bob with Alice’s fund 1 BTC, the other between Bob and Charlie with Bob’s fund 2 BTC. Alice wants to send Charlie 0.1 BTC via Bob, here’s what they need to do.
Between Bob and Charlie,
- Charlie generates a
payment_charlie_secret
, hashes it to produce thepayment_charlie_secret
. - Charlie and Bob create similar commitment transactions — Charlie has a Credit Output(the offered HTLC output) of 0.1 BTC and Bob has a Debit Output(the received HTLC output) of 0.1 BTC.
- Charlie has to reveal the
payment_charlie_secret
to Bob before 5 p.m., otherwise, Bob will take back his money. - Charlie and Bob create similar HTLC-Timeout and HTLC-Success transactions.
Between Alice and Bob, they will repeat the process, while Bob now becomes the debt collector. In their commitment transactions,
- Bob has a Credit Output(the offered HTLC output) of 0.1 BTC.
- Alice has a Debit Output(the received HTLC output) of 0.1 BTC.
- Bob has to reveal the
payment_charlie_secret
before 6 p.m., otherwise, Alice will take her money back.
Bob and Alice will create similar HTLC-Timeout and HTLC-Success transactions.
To fulfill the payment,
- Charlie reveals the
payment_charlie_secret
to Bob before 5 p.m. to claim his money from Bob. - Bob reveals the
payment_charlie_secret
before 6 p.m. to claim his money from Alice.
In reality, Bob, who forwards the payment, may charge a small fee in terms of his service. Though the technology is already in use today, it’s fascinating to see what economic and political effects it will eventually play out!
Clarifications — For Developer/Researcher
For brevity, I’ve deliberately shortened the locking script to focus on a bigger picture. Still, I think it would be nice to clarify the actual script used, especially if you are a developer/researcher.
When we say “check Alice’s signature is presented” in the locking script, what’s been put in the script is <Alice's public key> OP_CHECKSIG
. When Alice wants to spend it, she then put <Alice's signature>
in the input of the spending transaction. The same goes for the revocation signature and payment secret too. Please check the Notes and References to find all the details.
Another clarification is the algorithm used to derive the revocation key pairs. Previously it’s described as simple addition, while the actual math is as follows,
revocation_public_key = bob_public_key * SHA256(bob_public_key || alice_public_key) + alice_public_key * SHA256(alice_public_key || bob_public_key)revocation_private_key = bob_secret_key * SHA256(bob_public_key || alice_public_key) + alice_secret_key * SHA256(alice_public_key || bob_public_key)
If name mapping to the RFC is wanted, suppose Bob being the local node and Alice being remote, replace them as following,
bob_public_key
isrevocation_basepoint
.bob_secret_key
isrevocation_basepoint_secret
.alice_public_key
isper_commitment_point
.alice_secret_key
isper_commitment_secret
.
You will get the same formula as specified.
Notes and References
- The Bitcoin Lightning Network: Scalable Off-Chain Instant Payments, Joseph Poon, Thaddeus Dryja
- Reaching the ground with lightning, Rusty Russell
- Elliptic Curve Point Multiplication
- The Lightning Network Specifications is a great place to find all the details, though it’s difficult to read. Regarding how transactions work, BOLT #2: Peer Protocol for Channel Management, BOLT #3: Bitcoin Transaction and Script Formats and BOLT #5: Recommendations for On-chain Transaction Handling explain it in technical detail.
- Rene Pickhardt, who works with Andreas M. Antonopoulos to write the book, Mastering the Lightning Network. He has helped to explain the general process of the transaction, how the keys exchanged and created this presentation, which I found very helpful.
- Hongchao wrote Payment Channels in Lightning Network which gave an overview of how the lightning network works, it’s easy to understand for readers with knowledge on Bitcoin script.
- Rusty Russell(the main contributor to the lightning-RFC) has summarized the rationality behind the two-stage HTLC outputs design in his blog, The #Bitcoin #Lightning Spec Part 3/8: Peer Protocol for Channel Management.
- About the timelock, James Prestwich’s Bitcoin’s Time Locks has provided great insight, in addition to the Bitcoin Developer Guide and Andreas M. Antonopoulos’s Mastering Bitcoin, Advanced Transactions and Scripting.
- I’ve set up a testing environment using bitcoind and lnd to help me understand the whole process. Here’s the gist of the trimmed log generated from lnd, which recorded how Alice sent Bob money.
- A clarification on the locking scripts. The red boxes represent the actual format of the locking script. To unlock it, you need to supply the unlocking script in the corresponding green box.