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.
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
revocation_public_key is constructed using
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_b1, sends them to Bob. The corresponding private keys
alice_prikey_tx_b1are kept to herself.
- For Bob, he creates public keys
bob_pubkey_tx_b1, sends them to Alice. The private keys
bob_prikey_tx_b1are kept to himself.
- Alice uses
bob_pubkey_tx_a1to generate the
revocation_pubkey_tx_a1, which can validate
- Bob uses
bob_pubkey_tx_b1to generate the
revocation_pubkey_tx_b1, which can validate
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 as
prikey, and signature is
sig. For example,
alice_funding_sigmeans 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, a
revocation_pubkey_tx_a1is generated using
revocation_prikey_tx_a1is generated using
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_a1is used to revoke Alice’s transaction
TX A01. For now, Bob’s transactions do not incorporate revocation yet, but soon it will be used.
revocation_sig_tx_a1is produced by
revocation_prikey_tx_a1, and can be validated using
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,
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,
bob_pubkey_tx_b2 are exchanged to produce
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 A02to 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 have
revocation_prikey_tx_a2, which is derived from
- If Alice broadcasts
TX A01, she has to wait two weeks before it’s spendable. Meanwhile, Bob will use
revocation_prikey_tx_a1, which can produce
revocation_sig_tx_a1to 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_secretand keeps it to himself.
- Bob hashes the
payment_secretto produce a
payment_hashand 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_secretin 3 days, he shall get the money. If 3 days passed, even if Bob provides
payment_secret, he shall not get the money. In other words, the condition for Bob to own the money needs a) he knows
payment_secretand b) he reveals it to Alice within 3 days. In our case, since Bob generated the
payment_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_secretin 3 days. In other words, if Bob reveals the
payment_secretwithin 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
nSequencefield 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 a
CheckSequenceVerify(CSV) specifies a relative timelock.
- In the transaction level, an
nLocktimeis used to specify an absolute timelock.
The lightning network has implemented
CheckLockTimeVerify in its design. An
nLocktime controls when a transaction can enter the blockchain. If a transaction with
2140/01/01 12am is encoded, it cannot be broadcasted until over a hundred years later.
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
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
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
nLocktimeof 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
- 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.
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.
TX A02, it consumes an output from the funding transaction, which requires both Alice and Bob’s signatures(
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(
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 in
TX A02even 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
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
TX A02, the revocation can only be invoked by Bob as Alice doesn’t have the private key
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 A03or Bob can broadcast
TX B03to 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 the
- 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_secretto 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_secretbefore 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_secretto Bob before 5 p.m. to claim his money from Bob.
- Bob reveals the
payment_charlie_secretbefore 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,
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.