> ## Documentation Index
> Fetch the complete documentation index at: https://docs.garden.finance/llms.txt
> Use this file to discover all available pages before exploring further.

# Bitcoin

> Implement atomic swaps on Bitcoin using scripts for initiate, redeem, refund, and instant refund operations

<Info>
  Learn about [P2TR (Pay To Taproot)](https://learnmeabitcoin.com/technical/script/p2tr/) to understand how to spend from a HTLC script.
</Info>

## Script architecture

Instead of contract functions, Bitcoin implements atomic swap logic through scripts that are executed when UTXOs are spent. Let's explore the four core operations:

<CardGroup cols={4}>
  <Card title="Initiate" icon="play" href="#initiate" />

  <Card title="Redeem" icon="check" href="#redeem" />

  <Card title="Refund" icon="rotate-left" href="#refund" />

  <Card title="Instant refund" icon="bolt" href="#instant-refund" />
</CardGroup>

We will use the following struct for passing swap info:

```go theme={null}
type HTLC struct {
    // X-only pubkey of the initiator
    InitiatorPubkey []byte
    // X-only pubkey of the redeemer
    RedeemerPubkey []byte
    // sha256(preimage)
    SecretHash     []byte
    // expiry in blocks
    Timelock uint32
}
```

## Core operations

### Initiate

Initiating an atomic swap on Bitcoin involves creating a transaction that locks funds in an HTLC script. Here's what happens during initiation:

<Steps>
  <Step title="Create transaction">
    The initiator creates a Bitcoin transaction that:

    * Spends from their wallet (input).
    * Creates an output that pays to the HTLC script address (derived from the HTLC parameters — pubkeys, secret hash, timelock, and destination data)
  </Step>

  <Step title="Set script conditions">
    The HTLC script ensures that the locked funds can only be spent if either:

    * The redeemer provides the correct secret and their signature (redeem path)
    * The initiator claims back after timelock expiry (refund path)
    * Both parties agree to cancel (instant refund path)
  </Step>
</Steps>

The amount locked in the script is used as the swap amount.

### Redeem

Redeeming an atomic swap means claiming the locked funds by providing the secret that matches the hash used during initiation.

The redeem process involves:

1. Creating a transaction that spends from the HTLC script address.
2. Providing the secret that matches the hash.
3. Signing the transaction with the redeemer's private key.

Let's understand this through a high-level function similar to an EVM contract:

```go theme={null}
func Redeem(htlc *HTLC, secret []byte, signature []byte) {
    if sha256(secret) != htlc.SecretHash || recover(sig) != htlc.RedeemerPubkey {
        panic("script verification failed")
    }
    withdraw()
}
```

This function performs two critical checks:

* Secret validation: Ensures the provided secret hashes to the expected value.
* Signature verification: Confirms the redeemer is authorized to claim.

When translated to Bitcoin Script, we need to consider its stack-based nature. Here's how the script works:

```javascript theme={null}
OP_SHA256
OP_DATA_32 {secretHash}
OP_EQUALVERIFY
OP_DATA_32 {redeemerPubkey}
OP_CHECKSIG
```

<Info>
  Stack-based execution provides deterministic behavior and prevents many classes of smart contract vulnerabilities.
</Info>

#### Stack visualization

```
Initial State:          After OP_SHA256:       After Push secretHash:
+----------------+      +----------------+      +----------------+
|     secret     |      | hashed_secret  |      |   secretHash   | ← Known hash from HTLC
+----------------+      +----------------+      +----------------+
|   signature    |      |   signature    |      | hashed_secret  | ← Computed hash from provided secret
+----------------+      +----------------+      +----------------+
                                                |   signature    |
                                                +----------------+

After EQUALVERIFY:     After Push pubkey:     After CHECKSIG:
+----------------+      +----------------+      +----------------+
|   signature    |      | redeemerPubkey |      |     true      | ← Script succeeds only if true
+----------------+      +----------------+      +----------------+
                        |   signature    |
                        +----------------+
```

<Info>
  Notes:

  * The stack grows and shrinks from the top (top element is consumed first)
  * `OP_SHA256` consumes the secret and produces its hash (proves knowledge of preimage)
  * `OP_EQUALVERIFY` is critical — it fails immediately if the hashes don't match
  * Signature verification happens only if the secret is valid
</Info>

If all conditions are met, the script returns true and the funds can be sent to the redeemer's address.

### Refund

The refund mechanism is a critical safety feature in atomic swaps that prevents funds from being locked forever if the swap fails to complete.

Key concepts in refunding:

* Timelock: A waiting period measured in blocks.
* Relative time: Measured from when the swap was initiated.
* Initiator authentication: Only the initiator can refund.

The refund process involves:

* Waiting for the timelock to expire
* Creating a transaction that spends from the HTLC script
* Providing proof of being the initiator (signature)

Let's look at the high-level function:

```go theme={null}
func Refund(htlc *HTLC, currentBlockHeight uint32, initiatedBlockHeight uint32, signature []byte) {
    if currentBlockHeight - initiateBlockHeight > htlc.Timelock {
        panic("not expired")
    }
    if recover(signature) != htlc.InitiatorPubkey {
        panic("invalid signature")
    }
    withdraw()
}
```

This translates to the following Bitcoin Script:

```javascript theme={null}
OP_10
OP_CHECKSEQUENCEVERIFY
OP_DROP
OP_DATA_32 {initiatorPubkey}
OP_CHECKSIG
```

#### Stack visualization

```
Initial State:          After OP_10:           After CSV:
+----------------+      +----------------+      +----------------+
|   signature    |      |      10        |      |      10        |
+----------------+      +----------------+      +----------------+
                        |   signature    |      |   signature    |
                        +----------------+      +----------------+

After OP_DROP:         After Push pubkey:     After CHECKSIG:
+----------------+      +----------------+      +----------------+
|   signature    |      | initiatorPubkey|      |     true      |
+----------------+      +----------------+      +----------------+
                        |   signature    |
                        +----------------+
```

<Info>
  Notes:

  * `OP_CHECKSEQUENCEVERIFY` verifies that enough time has passed (relative to when UTXO was created).
  * CSV fails and prevents spending if the timelock hasn't expired.
  * CSV doesn't consume the timelock value, so `OP_DROP` is needed to remove it.
  * The final signature check ensures only the original initiator can refund.
</Info>

<Note>
  Relative timelock with CSV provides more flexibility than absolute block numbers, as it's measured from when the UTXO was created rather than a specific block height.
</Note>

This provides a secure way to recover funds if:

* The counterparty never participates.
* Network issues prevent completion.
* The counterparty abandons the swap.

### Instant refund

Instant refund is a cooperative cancellation mechanism that allows both parties to mutually agree to terminate the swap early, without waiting for the timelock to expire.

Key concepts in instant refund:

* Multi-signature: Requires both parties to agree.
* No timelock: Can be executed at any time.
* Mutual authentication: Both parties must provide valid signatures.

The instant refund process involves creating a transaction that spends from the HTLC script address, having both parties sign the transaction, and providing both signatures in the correct order.

Let's understand this through a high-level function similar to an EVM contract:

```go theme={null}
func InstantRefund(htlc *HTLC, initiatorSignature []byte, redeemerSignature []byte) {
    if recover(initiatorSignature) != htlc.InitiatorPubkey {
        panic("invalid initiator signature")
    }
    if recover(redeemerSignature) != htlc.RedeemerPubkey {
        panic("invalid redeemer signature")
    }
    withdraw()
}
```

This function performs two critical checks:

* Initiator signature validation: Ensures the initiator has agreed to cancel
* Redeemer signature validation: Ensures the redeemer has agreed to cancel

When translated to Bitcoin Script, we need to consider its stack-based nature. Here's how the script works:

```javascript theme={null}
OP_DATA_32 {initiatorPubkey}
OP_CHECKSIG
OP_DATA_32 {redeemerPubkey}
OP_CHECKSIGADD
OP_2
OP_NUMEQUAL
```

#### Stack visualization

```
Initial State:              After Push initiatorPubkey:   After First CHECKSIG:
+----------------------+    +----------------------+    +----------------------+
| initiatorSignature   |    | initiatorPubkey      |    | 1 or 0              |
+----------------------+    +----------------------+    +----------------------+
| redeemerSignature    |    | initiatorSignature   |    | redeemerSignature    |
+----------------------+    +----------------------+    +----------------------+
                            | redeemerSignature    |
                            +----------------------+

After Push redeemerPubkey:    After CHECKSIGADD:         After Push 2:
+----------------------+    +----------------------+    +----------------------+
| redeemerPubkey      |    | 1+1 or 1+0 or 0+0    |    | 2                    |
+----------------------+    +----------------------+    +----------------------+
| 1 or 0              |                                | 1+1 or 1+0 or 0+0    |
+----------------------+                                +----------------------+
| redeemerSignature    |
+----------------------+

After NUMEQUAL:
+----------------------+
| true/false          |
+----------------------+
```

<Info>
  Notes about `OP_CHECKSIGADD`:

  It consumes three stack elements:

  * A public key (redeemerPubkey)
  * A numeric value to add to (result of first CHECKSIG)
  * A signature to verify (redeemerSignature)

  It performs these operations:

  * Verifies if the signature is valid for the pubkey
  * Adds 1 (if valid) or 0 (if invalid) to the numeric value
  * Pushes the sum back onto the stack

  The final state:

  * Sum = 2: Both signatures valid (1+1)
  * Sum = 1: Only one signature valid (1+0 or 0+1)
  * Sum = 0: Neither signature valid (0+0)

  `OP_NUMEQUAL` with 2 ensures both signatures must be valid
</Info>

<Note>
  The `OP_CHECKSIGADD` operation provides efficient multi-signature verification using Tapscript's enhanced capabilities.
</Note>

This approach efficiently implements a 2-of-2 multisignature requirement using Tapscript's enhanced capabilities.

The script ensures that both signatures are valid and match their respective public keys, confirming that both parties have mutually agreed to cancel the swap.

## Bitcoin-specific considerations

### Transaction construction

* Input selection: Choose appropriate UTXOs to fund the HTLC script, considering transaction fees and optimal UTXO management.
* Script address generation: Generate the script address using Taproot's address format for better privacy, efficiency and cost optimization.
* Fee calculation: Calculate appropriate fees based on current network conditions and transaction size.
