Updating the balance of a Payment Channel
In this article we will look in detail at how the balance of a Lighting Network channel gets updated without any of the participants risking their funds.
Lightning Network is an adversarial network, participants do not trust the other side. In fact they expect that the “others” will try to cheat them.
A participant signs only what it knows to be safe. At any moment it must have the option to take out the money and leave the agreement (close the channel).
For this article we assume that the payment channel has already been open and it has a balance of 0.10 BTC for Alice and 0.0 BTC for Bob.
After the payment channel has been open, Alice wants to pay Bob 0.02 BTC. The payments between the two parties are executed using a special type of transaction called a Commitment Transaction.
These transactions are special because they:
- can be revoked (canceled) if both parties agree to do so
- always spend from the 2-of-2 multisig Output of the Funding Transaction
The Commitment Transactions are intended to be used inside the payment channel, without hitting the main-chain. However, they are fully valid Bitcoin transactions and can be broadcast to the main-chain if one of the parties decides to do so.
In order to pay Bob, Alice must create two transactions, both of which will pay 0.02 BTC to Bob, but the outputs have different conditions for spending.
We will refer to these transactions as the Pay-Me-First transaction and the Pay-Other-First transaction. Remember that both transactions are created by Alice without any direct input from Bob. Alice got all the information she needed when Bob sent the
In the Pay-Me-First transaction Alice can spend her output immediately, while Bob has to comply with the RSM Contract. A Revocable Sequence Maturity Contract puts several restrictions on spending the Output:
- the beneficiary of the funds can only spend them after a “maturation” period has passed (is delayed)
- the contract can be revoked (by the beneficiary)
- if the contract was revoked and the beneficiary still tries to spend the funds then it risks penalty (loosing all the funds)
More details about Revocable Sequence Maturity Contracts here.
This transaction is more advantageous for Alice. You can view a sample of this transaction here.
In the Pay-Other-First transaction Bob can spend his output immediately, while Alice has to comply with the RSM Contract. This transaction is more advantageous for Bob. You can view a sample of this transaction here.
Note: Transaction outputs are sorted in ascending order by amount.
Alice will only send signatures to Bob for the Pay-Me-First transaction (me=Alice). She will never send signatures directly to Bob for the Pay-Other-First transaction (other=Bob).
The only time Alice will sign the Pay-Other-First transaction is if she intends to broadcast that transaction to the Bitcoin network (without sending it to Bob).
The outputs of the Pay-Other-First transaction are called to_local (the one that pays Alice) and to_remote (the one that pays Bob).
In a similar manner, Bob will create a Pay-Me-First transaction and a Pay-Other-First transaction.
Channel State Update — Step By Step
Next we will take a look in detail at what happens when Alice pays Bob 0.02 BTC using a Lightning Network payment channel.
Below are the steps taken by Alice and Bob to update the balance from Alice 0.10 BTC and Bob 0.0 BTC (State01) to Alice 0.08 BTC and Bob 0.02 BTC (State02).
The party making the payment initiates the flow, in this case Alice.
Alice Builds and Signs
BuildPayMeFirstTx( alice)— Alice builds the transaction that pays her 0.08 BTC with no restrictions and 0.02 BTC to Bob under the RSM Contract. We name this transaction
Sign(payAliceFirstTx)— Alice signs
payAliceFirstTxtransaction and creates a signature named
Send(payAliceFirstSignature)— Alice sends the
payAliceFirstSignatureto Bob. There is no risk for her sending this signature. The worst case scenario is that Bob will close the channel and will broadcast
payAliceFirstTx, which is fine for Alice since she can spend her output right away, while Bob has to wait.
payAliceFirstTx, Bob also discloses that he received the 0.02 BTC from Alice. If instead of closing the channel Bob becomes unresponsive then Alice can safely broadcast the previous transaction where she has a larger amount (State01) since she has not revoked the current commitment transaction yet.
Bob checks and revokes
Receive(payAliceFirstSignature) — Bob receives the
payAliceFirstSignature message. Note that Alice sends only the signature and not the full transaction. Bob can reconstruct the exact same transaction.
BuildPayOtherFirstTx(alice) — Bob builds the transaction that pays him 0.02 BTC under the RSM Contract and 0.08 BTC to Alice with no restrictions. We name this transaction
payOtherFirstTx. It is identical with the
payAliceFirstTx (that Alice built).
CheckSignature(payOtherFirstTx, payAliceFirstSignature) — Bob checks if the signature received from Alice (
payAliceFirstSignature) is valid for the transaction that he just built (
payAliceFirstTx). If the signature from Alice is valid then Bob has a valid new commitment transaction (State02). He can continue to use the channel or he can sign and broadcast the transaction, thus closing the channel. However, if Bob broadcasts the transaction he will be restricted in spending it by the RSM Contract, while Alice will be able to spend her funds immediately.
Store(payAliceFirstSignature) — Bob persists the signature together with the data that allows him to reconstruct
payAliceFirstTx. He might need this data if Alice becomes unresponsive.
BuildRevokeCommitmentMsg() — Bob does not need the older state (where he had less money) so he wants to make State02 (
payAliceFirstTx) the current state and revoke (invalidate) the old one (State01). He builds the
revokeMessage message that invalidates State01.
Send(revokeMessage) — Bob sends the
revokeMessage to Alice. There is no risk for him to send this message which revokes the previous state (State01). The worst case scenario is that Alice becomes unresponsive and Bob has to broadcast the
By revoking the previous state (State01), Bob assures Alice that it is OK for her to take the next steps.
ReceiveRevokeMsg(revokeMessage) — Alice receives the revocation message from Bob. Alice now has the possibility to penalize Bob if he broadcasts the revoked commitment transaction (State01).
She will not revoke her current state yet since she has not received a signature from Bob for State02.
Bob builds and signs
BuildPayMeFirstTx(bob) — Bob does not simply sign the
payAliceFirstTx transaction and sends it to Alice. This transaction is unfavorable to him since he has to comply with the RSM Contract while Alice is free to spend her funds immediately. But most importantly, he will have no power to penalize Alice if she decides to broadcast the
payAliceFirstTx transaction sometime in the future when this old transaction becomes favorable to her (more money).
Bob builds a transaction that pays him with no restrictions, but pays Alice under the RSM Contract restrictions. This is the
Sign(payBobFirstTx) — Bob creates the
payBobFirstSignature by signing the
Send(payBobFirstSignature) — Bob sends the
payBobFirstSignature message to Alice.
Alice checks and revokes
Receive(signatureBob) — Alice receives the
payBobFirstSignature message. Note that Bob sends only the signature and not the full transaction. Alice can reconstruct the exact same transaction.
BuildPayOtherFirstTx(bob) — Alice builds the transaction that pays her 0.08 BTC under the RSM Contract and pays Bob 0.02 with no restrictions. We name this transaction
payOtherFirstTx. It must be identical with the
payBobFirstTx (built by Bob).
CheckSignature(payOtherFirstTx, signatureBob) — Alice checks if the signature received from Bob (
payBobFirstSignature) is valid for the transaction that she just built (
payBobFirstTx). If the signature from Bob is valid then Alice has a valid new commitment transaction (State02). She can continue to use the channel or she can sign and broadcast the transaction therefore closing the channel. If Alice chooses to broadcast this transaction, Bob will be able to spend his funds immediately while she has to comply with the RSM Contract.
Store(signatureBob) — Alice persists the
signatureBob message together with the data that allows her to reconstruct
payBobFirstTx. She can use this data if Bob becomes unresponsive.
BuildRevokeCommitmentMsg() — Alice builds the
revokeMessage, that will penalize her if she tries to broadcast the old state (State01) where she had 0.10 BTC.
Send(revokeMessage) — Alice sends the
revokeMessage to Bob. She can now consider the payment complete. The payment channel has moved to State02.
Receive(revokeMessage) — Bob receives the
revocationMessage from Alice. He now can consider the payment complete. The payment channel has moved to State02.