Updating the balance of a Payment Channel

Vlad Stan
8 min readFeb 19, 2021

--

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.

Commitment Transactions

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.

Multiple Commitment Transactions inside a Payment Channel

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 accept_channel message.

Pay-Me-First Transaction

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.

The Pay-Me-First transaction created by Alice

Pay-Other-First Transaction

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.

The Pay-Other-First transaction created by Alice
The Pay-Other-First transaction created by Alice

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

Alice builds and signs her Pay-Me-First transaction
Alice builds and signs her Pay-Me-First transaction
  1. 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 payAliceFirstTx.
  2. Sign(payAliceFirstTx) — Alice signs payAliceFirstTx transaction and creates a signature named payAliceFirstSignature.
  3. Send(payAliceFirstSignature) — Alice sends the payAliceFirstSignature to 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.
    By broadcasting 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

Bob checks the signature from Alice and revokes the previous state
Bob checks the signature from Alice and revokes the previous state

4. 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.

5. 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).

6. 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.

7. 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.

8. 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.

9. 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 payAliceFirstTx transaction.
By revoking the previous state (State01), Bob assures Alice that it is OK for her to take the next steps.

Alice receives the revocation message for State01
Alice receives the revocation message for State01

10. 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

Bob builds and signs the Pay-Me-First transaction
Bob builds and signs the Pay-Me-First transaction

11. 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 payBobFirstTx transaction.

12. Sign(payBobFirstTx) — Bob creates the payBobFirstSignature by signing the payBobFirstTx transaction.

13. Send(payBobFirstSignature) — Bob sends the payBobFirstSignature message to Alice.

Alice checks and revokes

14. 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.

15. 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).

16. 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.

17. 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.

18. BuildRevokeCommitmentMsg() — Alice builds the revokeMessage, that will penalize her if she tries to broadcast the old state (State01) where she had 0.10 BTC.

19. Send(revokeMessage) — Alice sends the revokeMessage to Bob. She can now consider the payment complete. The payment channel has moved to State02.

20. Receive(revokeMessage) — Bob receives the revocationMessage from Alice. He now can consider the payment complete. The payment channel has moved to State02.

--

--