Skip to content

Instantly share code, notes, and snippets.

@ekrembal
Created February 4, 2025 14:34
Show Gist options
  • Select an option

  • Save ekrembal/2b26e224873a5a0a179d25a4b5f6e58a to your computer and use it in GitHub Desktop.

Select an option

Save ekrembal/2b26e224873a5a0a179d25a4b5f6e58a to your computer and use it in GitHub Desktop.

image

Bitcoin Light Client on Bitcoin

The Bitcoin Light Client is designed to prove that a specific Bitcoin transaction occurred on-chain by verifying the existence of a designated UTXO. In combination with BitVM’s optimistic verification of arbitrary computations, this mechanism forms the backbone of a trust-minimized bridge between Bitcoin and a sidesystem. In essence, by proving that a withdrawal transaction has been executed on Bitcoin and confirming consensus via BitVM, one can securely build a bridge.

Actors

  • Operator: Initiates the process by broadcasting transactions and providing necessary proofs.
  • Watchtowers: Monitor the process and can issue challenges by presenting Bitcoin chain data.
  • Signers: Sign N-of-N key deletion covenants, thereby ensuring the integrity of setup and execution.

Protocol Flow

1. Kickoff Transaction

  • Initialization:

    The Operator starts by broadcasting a kickoff transaction. Its input contains a Winternitz signature (32 bytes) that represents the blockhash in which the target transaction is included.

  • Output Structure:

    The transaction is designed with W + 2 outputs:

    • The first W outputs are reserved for Watchtowers to submit challenges.
    • The remaining outputs are used for BitVM proof submission and timeout cases.

2. Challenge Phase

  • Watchtower Challenges:

    Each Watchtower may issue a challenge by submitting a longest chain proof that demonstrates the existence of a valid Bitcoin header chain with a total accumulated work (tw).

  • Operator Acknowledgment:

    On receiving a challenge, the Operator must respond by broadcasting an operator_challenge_ack_tx. This transaction requires the Operator to reveal a preimage (whose hash was committed in advance). Note that a unique random preimage is generated for each Watchtower, akin to a one-bit Winternitz signature.

3. Challenge Timeout

  • Non-Acknowledgment:

    If the Operator fails to acknowledge a challenge within t1 blocks (approximately 0.5 weeks), any party may broadcast an operator_challenge_nack_tx. This transaction burns the (W+1)th output from the kickoff transaction.

  • Locked Output for BitVM Proof:

    The (W+1)th output is intended for the BitVM proof but remains locked for t2 blocks (approximately 2.5 weeks). If the Operator does not begin providing the BitVM proof within t3 blocks (approximately 2.7 weeks), any participant can spend this output.

  • Additional Requirement:

    To spend the (W+1)th output, the Operator must also provide a Winternitz signature (32 bytes) representing the latest Bitcoin blockhash known to the Operator.

4. Assertion Phase

  • Proof Submission:

    After challenges have been addressed, the Operator sends an Assert_begin_tx. This is followed by the mandatory submission of an assert_end_tx within t4 blocks (approximately 3 weeks).

  • Failure Case:

    If the Operator fails to send the assert_end_tx in time, any participant may broadcast a Kickoff_timeout_tx, which spends the final output of the kickoff transaction, indicating that the proof has failed.

5. Final BitVM Proof

  • Disprove Scripts via Taproot:

    The assert_end_tx contains a Taproot output that incorporates all disprove scripts. This BitVM proof must validate that the challenges and Bitcoin chain data are consistent and correct.

Detailed Pseudocode Explanation

The BitVM proof is structured in two layers: a main verification process and a helper for verifying the chain’s total work.

Main Verification Pseudocode

Input:
  - Winternitz_Signatures[W]
  - Longest_Chain_Proofs[W]
  - Total_Works[W]
  - All_Bitcoin_Block_Headers[]
  - Payout_Tx_Blockhash
  - Payout_Txid
  - Payout_Tx_SPV_Proof

Initialize:
  Max_Work ← 0
  Correct_Challengers[W] ← array of zeros

For each index i from 0 to W-1 do:
  If Winternitz_Verify(Winternitz_PubKey[i], Winternitz_Signatures[i],
                         Longest_Chain_Proofs[i], Total_Works[i]) then:
    Correct_Challengers[i] ← 1
    If Zk_Proof_Verify(Longest_Chain_Proofs[i], Total_Works[i]) then:
      Max_Work ← max(Max_Work, Total_Works[i])
  
total_work ← Verify_Headers_and_Calculate_Work(All_Bitcoin_Block_Headers)

If total_work < Max_Work then:
  FAIL

If Payout_Tx_Blockhash is not in All_Bitcoin_Block_Headers then:
  FAIL

If Verify_SPV_Proof(Payout_Tx_SPV_Proof, Payout_Tx_Blockhash, Payout_Txid) fails then:
  FAIL

Return (Correct_Challengers, Payout_Tx_Blockhash,
        LastBlockHash(All_Bitcoin_Block_Headers), Payout_Txid)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment