4.5 KiB
- Title: Revocation in more detail
- Summary: In this chapter we will dig deeper into the scripts used in commitment transactions and the revocation process.
Let's take a look at Alice's commitment transaction again. It spends from the funding transaction and has two outputs: a to_local output and a to_remote output.
to_remote
The to_remote output is simply a P2WPKH sending to Bob's pubkey.
<remotepubkey>
to_local
The to_local output has 2 spending paths.
- A
<revocationpubkey> - A pubkey belonging to Alice but is only spendable after the
to_self_delaynumber of blocks.
OP_IF
# Penalty transaction
<revocationpubkey>
OP_ELSE
`to_self_delay`
OP_CHECKSEQUENCEVERIFY
OP_DROP
<local_delayedpubkey>
OP_ENDIF
OP_CHECKSIG
In Chapter 2, we described the revocation as follows:
- Alice generates a temporary private key
dA1and a corresponding public keyPA1and sends the public key to Bob. - Alice then creates a commitment transaction where the
to_localoutput is immediately spendable by Bob if he has the private keydA1. - If Alice and Bob update their channel state, then they will swap the previous private keys with each other to invalidate the previous commitment, i.e. Alice will send Bob
dA1.
This description is mostly correct but not complete. If we take another look at the to_self_delay script above, it looks like the revocation path doesn't have any condition that says only Bob can spend it. It just seems like anyone with the private key corresponding to the revocation pubkey can spend it. Since Alice is the one who generated the temporary private key in the first place, doesn't that mean she can also spend it?
A clever trick is used to make sure that only Bob can spend via the revocation path. Before constructing the commitment transactions, both Alice and Bob derive two temporary keys and associated public keys.
- A
revocation_basepoint(r -> R) keypair - A
per_commitment_point(c -> C) keypair
In other words, Alice will have:
- her
revocation_basepointkeypair:rA1->RA1 - her
per_commitment_pointkeypair:cA1->CA1
Bob will have:
- his
revocation_basepointkeypair:rB1->RB1 - his
per_commitment_pointkeypair:cB1->CB1
Now, when it's time for Alice to construct the commitment transaction, she will send Bob her commitment point pubkey CA1. Bob will send her his revocation basepoint pubkey RB1. Alice can now derive the revocation pubkey to be included in the commitment transaction as follows:
Rev_A2 = R_B1 * sha256( R_B1 || C_A1 ) + C_A1 * sha256( C_A1 || R_B1 )
Now Alice's to_local output looks like this:
OP_IF
<Rev_A2>
OP_ELSE
`to_self_delay`
OP_CHECKSEQUENCEVERIFY
OP_DROP
<alice_delayedpubkey>
OP_ENDIF
OP_CHECKSIG
When it's time for Alice and Bob to update state and invalidate the old state, Alice sends Bob her private key for the commitment point cA2. With this key, Bob now has both Alice's per commitment point private key cA1 as well as his own revocation basepoint private key rB1 which corresponds to the public key RB1 he sent Alice earlier when Alice was constructing the commitment transaction. So now with these two pieces of information, Bob can derive the private key corresponding to the public key Rev_A1 and therefore spend via the revocation output. He can calculate the private key as follows:
rev_A2 = r_B1 * sha256( R_B1 || C_A1 ) + c_A1 * sha256( C_A1 || R_B1 )
Alice will never be able to derive this private key because she does not have and will never have Bob's revocation basepoint private key rB2.
Now let's update the diagrams from Chapter 2 to reflect the new things we've learned in this chapter.
State 1:
State 2:
Review
- Two keypairs are generated when constructing the commitment transactions
- Private keys from both keypairs are needed to be able to spend from the revocation path
References
- BOLT3:
revocationpubkeyDerivation - LN Things Part 3: Revocation in more detail by nostr:nprofile1qqswrt9pnxatlplu49h6meld8svmwqt87wwvk256rqk07n6eu4qeh5gpz3mhxue69uhhyetvv9ujuerpd46hxtnfduqs6amnwvaz7tmwdaejumr0dszpfjtz

