README.md (3593B)
1 # ppad-tx 2 3 [](https://hackage.haskell.org/package/ppad-tx) 4  5 [](https://docs.ppad.tech/tx) 6 7 Minimal Bitcoin transaction primitives in pure Haskell: raw transaction 8 types, serialisation to and from bytes (legacy and BIP144 segwit), 9 txid computation, and sighash calculation (legacy, [BIP143][bp143] 10 segwit and [BIP341][bp341] taproot). 11 12 ## Usage 13 14 A sample GHCi session: 15 16 ``` 17 > :set -XOverloadedStrings 18 > import qualified Data.ByteString as BS 19 > import qualified Data.ByteString.Base16 as B16 20 > import qualified Data.List.NonEmpty as NE 21 > import Bitcoin.Prim.Tx 22 > import Bitcoin.Prim.Tx.Sighash 23 > 24 > -- the Satoshi -> Hal transaction from block 170 25 > :{ 26 > let raw = mconcat 27 > [ "0100000001c997a5e56e104102fa209c6a852dd90660a20b2d9c352423edce25" 28 > , "857fcd3704000000004847304402204e45e16932b8af514961a1d3a1a25fdf3f" 29 > , "4f7732e9d624c6c61548ab5fb8cd410220181522ec8eca07de4860a4acdd1290" 30 > , "9d831cc56cbbac4622082221a8768d1d0901ffffffff0200ca9a3b0000000043" 31 > , "4104ae1a62fe09c5f51b13905f07f06b99a2f7159b2225f374cd378d71302fa2" 32 > , "8414e7aab37397f554a7df5f142c21c1b7303b8a0626f1baded5c72a704f7e6c" 33 > , "d84cac00286bee0000000043410411db93e1dcdb8a016b49840f8c53bc1eb68a" 34 > , "382e97b1482ecad7b148a6909a5cb2e0eaddfb84ccf9744464f82e160bfa9b8b" 35 > , "64f9d4c03f999b8643f656b412a3ac00000000" 36 > ] 37 > :} 38 > let Just tx = from_base16 raw 39 > 40 > -- txids are displayed byte-reversed 41 > B16.encode (BS.reverse (un_txid (txid tx))) 42 "f4184fc596403b9d638783cf57adfe4c75c605f6356fbc91338530e9831e9e16" 43 > 44 > from_bytes (to_bytes tx) == Just tx 45 True 46 > 47 > -- the legacy sighash Satoshi signed: input 0 spends a P2PK output 48 > -- whose scriptPubKey is the same as this tx's change output 49 > let spk = txout_script_pubkey (NE.last (tx_outputs tx)) 50 > B16.encode (sighash_legacy tx 0 spk (encode_sighash SIGHASH_ALL)) 51 "7a05c6145f10101e9d6325494245adf1297d80f8f38d4d576d57cdba220bcb19" 52 > 53 > -- segwit and taproot sighashes validate their arguments 54 > sighash_segwit tx 1 spk 1000000000 (encode_sighash SIGHASH_ALL) 55 Nothing 56 ``` 57 58 ## Documentation 59 60 Haddocks (API documentation, etc.) are hosted at 61 [docs.ppad.tech/tx][hadoc]. 62 63 ## Performance 64 65 The aim is best-in-class performance for pure Haskell code. Run the 66 benchmarks (criterion for wall time, weigh for allocation) with: 67 68 ``` 69 $ cabal bench 70 ``` 71 72 ## Security 73 74 This library handles no secret material. Parsing is total and 75 rejects malformed, non-minimal or trailing-byte encodings, matching 76 Bitcoin Core's serialisation rules; it doesn't validate transactions 77 against consensus or policy rules (amounts, script validity, etc.). 78 Sighash computation follows Bitcoin Core, including its legacy quirks 79 (the SIGHASH_SINGLE "bug" value, OP_CODESEPARATOR removal, raw 32-bit 80 hashTypes), and is tested against Bitcoin Core's `sighash.json` and 81 the BIP143 and BIP341 vectors. 82 83 ## Development 84 85 You'll require [Nix][nixos] with [flake][flake] support enabled. Enter a 86 development shell with: 87 88 ``` 89 $ nix develop 90 ``` 91 92 Then do e.g.: 93 94 ``` 95 $ cabal repl ppad-tx 96 ``` 97 98 to get a REPL for the main library. 99 100 [bp143]: https://github.com/bitcoin/bips/blob/master/bip-0143.mediawiki 101 [bp341]: https://github.com/bitcoin/bips/blob/master/bip-0341.mediawiki 102 [nixos]: https://nixos.org/ 103 [flake]: https://nixos.org/manual/nix/unstable/command-ref/new-cli/nix3-flake.html 104 [hadoc]: https://docs.ppad.tech/tx