bolt3

Lightning transaction and script formats, per BOLT #3 (docs.ppad.tech/bolt3).
git clone git://git.ppad.tech/bolt3.git
Log | Files | Refs | README | LICENSE

README.md (4735B)


      1 # ppad-bolt3
      2 
      3 [![](https://img.shields.io/hackage/v/ppad-bolt3?color=blue)](https://hackage.haskell.org/package/ppad-bolt3)
      4 ![](https://img.shields.io/badge/license-MIT-brightgreen)
      5 [![](https://img.shields.io/badge/haddock-bolt3-lightblue)](https://docs.ppad.tech/bolt3)
      6 
      7 A pure Haskell implementation of [BOLT #3][bolt3], the Lightning
      8 Network's Bitcoin transaction and script formats: commitment, HTLC and
      9 closing transactions, their output scripts and witnesses,
     10 per-commitment key derivation, and per-commitment secret generation and
     11 storage.
     12 
     13 Amounts, points and secrets use the types of [ppad-bolt1][bolt1], and
     14 transactions convert to [ppad-tx][tx] for txids, sighashes and
     15 serialization.
     16 
     17 ## Usage
     18 
     19 A sample GHCi session:
     20 
     21 ```
     22   > :set -XOverloadedStrings
     23   > import qualified Bitcoin.Prim.Tx as BT
     24   > import qualified Data.ByteString as BS
     25   > import qualified Lightning.Protocol.BOLT1 as BOLT1
     26   > import Lightning.Protocol.BOLT3
     27   >
     28   > -- per-commitment secrets come from a seed; secrets aren't shown
     29   > let Just sd = seed (BS.replicate 32 0xff)
     30   > let Just cn = commitment_number 0
     31   > let i = commitment_secret_index cn
     32   > let secret = generate_from_seed sd i
     33   > secret
     34   PerCommitmentSecret <redacted>
     35   >
     36   > -- the peer keeps revealed secrets in compact storage
     37   > let Just store = insert_secret secret i empty_secret_store
     38   > fmap (== secret) (derive_old_secret i store)
     39   Just True
     40   >
     41   > -- the commitment's per-commitment point, and a private key for it
     42   > let Just pcp = derive_per_commitment_point secret
     43   > let Just base = seckey (BS.pack [1 .. 32])
     44   > derive_privkey base pcp
     45   Just (Seckey <redacted>)
     46   >
     47   > -- fees and HTLC trimming
     48   > commitment_fee (FeeratePerKw 5000) StaticRemotekey 2
     49   Satoshi 5340
     50   > let Just dust = fmap DustLimit (BOLT1.satoshi 546)
     51   > htlc_trim_threshold dust (FeeratePerKw 5000) StaticRemotekey HTLCOffered
     52   Satoshi 3861
     53   >
     54   > -- an option_simple_close transaction: the closer pays the fee, and
     55   > -- its OP_RETURN output has amount zero
     56   > let Just txid = BT.mkTxId (BS.replicate 32 0x01)
     57   > let Just [closer, closee] = traverse BOLT1.milli_satoshi [6000000, 4000000]
     58   > let Just fee = BOLT1.satoshi 500
     59   > let p2wpkh = Script . BS.append "\x00\x14" . BS.replicate 20
     60   :{
     61   ghci| let close = ClosingContext {
     62   ghci|         clc_funding_outpoint = BT.OutPoint txid 0
     63   ghci|       , clc_closer_msat      = closer
     64   ghci|       , clc_closee_msat      = closee
     65   ghci|       , clc_closer_script    = Script "\x6a"
     66   ghci|       , clc_closee_script    = p2wpkh 0x22
     67   ghci|       , clc_fee              = fee
     68   ghci|       , clc_locktime         = Locktime 0
     69   ghci|       , clc_outputs          = CloserAndCloseeOutputs
     70   ghci|       }
     71   ghci| :}
     72   > let Just tx = build_closing_tx close
     73   > fmap clo_value (cltx_outputs tx)
     74   Satoshi 0 :| [Satoshi 4000]
     75   > BS.length (encode_closing_tx tx)
     76   92
     77 ```
     78 
     79 ## Documentation
     80 
     81 Haddocks (API documentation, etc.) are hosted at
     82 [docs.ppad.tech/bolt3](https://docs.ppad.tech/bolt3).
     83 
     84 ## Specification
     85 
     86 This library implements BOLT #3 as of lightning/bolts commit
     87 [1aadb719][spec] (2026-09-21); a copy lives in `etc/`. Every test
     88 vector in Appendices B through F is checked byte for byte.
     89 
     90 Not implemented:
     91 
     92 * `zero_fee_commitments` (version 3 commitment and HTLC transactions,
     93   the `shared_anchor` P2A output, and Appendix H). Only the
     94   `option_static_remotekey` and `option_anchors` commitment formats are
     95   supported.
     96 * Funding transaction construction (including Appendix G's dual-funded
     97   vectors): the library provides the funding output's script and
     98   witness only.
     99 
    100 The library builds unsigned transactions; signatures are made with
    101 [ppad-secp256k1][secp] over sighashes from ppad-tx. Spending
    102 transactions for on-chain resolution belong to BOLT #5.
    103 
    104 ## Performance
    105 
    106 The aim is best-in-class performance for pure Haskell code. Run the
    107 benchmarks with:
    108 
    109 ```
    110 $ cabal bench
    111 ```
    112 
    113 ## Security
    114 
    115 This library has received no security audit. Secret material (seeds,
    116 secret keys, per-commitment secrets and their storage) is kept out of
    117 `Show` output, and private-key derivation uses constant-time
    118 arithmetic.
    119 
    120 ## Development
    121 
    122 You'll require [Nix][nixos] with [flake][flake] support enabled. Enter a
    123 development shell with:
    124 
    125 ```
    126 $ nix develop
    127 ```
    128 
    129 Then do e.g.:
    130 
    131 ```
    132 $ cabal repl ppad-bolt3
    133 ```
    134 
    135 to get a REPL for the main library.
    136 
    137 [bolt3]: https://github.com/lightning/bolts/blob/master/03-transactions.md
    138 [bolt1]: https://git.ppad.tech/bolt1
    139 [tx]: https://git.ppad.tech/tx
    140 [secp]: https://git.ppad.tech/secp256k1
    141 [spec]: https://github.com/lightning/bolts/tree/1aadb719b4007c4cea0ba6e36b08c4fb53788dee
    142 [nixos]: https://nixos.org/
    143 [flake]: https://nixos.org/manual/nix/unstable/command-ref/new-cli/nix3-flake.html