README.md (3815B)
1 # script 2 3 [](https://hackage.haskell.org/package/ppad-script) 4  5 6 Representations for [Script](https://en.bitcoin.it/wiki/Script), 7 including abstract syntax, 'ByteArray', and base16-encoded 'ByteString' 8 versions, as well as fast conversion utilities for working with them. 9 10 ## Usage 11 12 A sample GHCi session: 13 14 ``` 15 > :set -XOverloadedStrings 16 > 17 > -- import qualified 18 > import qualified Bitcoin.Prim.Script as S 19 > 20 > -- base16-encoded p2pkh scriptPubKey 21 > let p2pkh = "76a91489abcdefabbaabbaabbaabbaabbaabbaabbaabba88ac" 22 > 23 > -- bytearray-encoded 24 > let Just script = S.from_base16 p2pkh 25 > script 26 Script [ 0x76, 0xa9, 0x14, 0x89, 0xab, 0xcd, 0xef 27 , 0xab, 0xba, 0xab, 0xba, 0xab, 0xba, 0xab 28 , 0xba, 0xab, 0xba, 0xab, 0xba, 0xab, 0xba 29 , 0xab, 0xba, 0x88, 0xac 30 ] 31 > 32 > -- abstract syntax-encoded 33 > let terms = S.from_script script 34 > terms 35 [ OP_DUP, OP_HASH160, OP_PUSHBYTES_20, 0x89, 0xab, 0xcd, 0xef 36 , 0xab, 0xba, 0xab, 0xba, 0xab, 0xba, 0xab 37 , 0xba, 0xab, 0xba, 0xab, 0xba, 0xab, 0xba 38 , 0xab, 0xba, OP_EQUALVERIFY, OP_CHECKSIG 39 ] 40 > 41 > -- round-trip 42 > S.to_base16 (S.to_script terms) 43 "76a91489abcdefabbaabbaabbaabbaabbaabbaabbaabba88ac" 44 ``` 45 46 ## Documentation 47 48 Haddocks (API documentation, etc.) are hosted at 49 [docs.ppad.tech/script](https://docs.ppad.tech/script). 50 51 ## Performance 52 53 The aim is best-in-class performance for highly-auditable Haskell code. 54 55 Current benchmark figures on my mid-2020 MacBook Air look like (use 56 `cabal bench` to run the benchmark suite): 57 58 ``` 59 benchmarking to_script 60 time 484.9 ns (478.3 ns .. 491.4 ns) 61 0.998 R² (0.997 R² .. 0.999 R²) 62 mean 496.2 ns (485.8 ns .. 508.1 ns) 63 std dev 37.17 ns (30.08 ns .. 49.95 ns) 64 variance introduced by outliers: 83% (severely inflated) 65 66 benchmarking from_script 67 time 380.8 ns (374.3 ns .. 387.5 ns) 68 0.998 R² (0.996 R² .. 0.999 R²) 69 mean 383.0 ns (375.3 ns .. 395.4 ns) 70 std dev 31.88 ns (22.41 ns .. 43.86 ns) 71 variance introduced by outliers: 86% (severely inflated) 72 73 benchmarking to_base16 74 time 291.3 ns (285.6 ns .. 297.9 ns) 75 0.996 R² (0.995 R² .. 0.998 R²) 76 mean 298.3 ns (291.8 ns .. 308.1 ns) 77 std dev 26.38 ns (21.25 ns .. 34.27 ns) 78 variance introduced by outliers: 87% (severely inflated) 79 80 benchmarking from_base16 81 time 439.1 ns (429.9 ns .. 448.2 ns) 82 0.997 R² (0.996 R² .. 0.998 R²) 83 mean 437.9 ns (429.9 ns .. 450.0 ns) 84 std dev 32.67 ns (26.12 ns .. 44.04 ns) 85 variance introduced by outliers: 83% (severely inflated) 86 ``` 87 88 where the inputs to the above functions are variations of the script found 89 in the 'Usage' section. 90 91 ## Security 92 93 This library aims at the maximum security achievable in a 94 garbage-collected language under an optimizing compiler such as GHC, in 95 which strict constant-timeness can be challenging to achieve. 96 97 If you discover any vulnerabilities, please disclose them via 98 security@ppad.tech. 99 100 ## Development 101 102 You'll require [Nix][nixos] with [flake][flake] support enabled. Enter a 103 development shell with: 104 105 ``` 106 $ nix develop 107 ``` 108 109 Then do e.g.: 110 111 ``` 112 $ cabal repl ppad-script 113 ``` 114 115 to get a REPL for the main library. 116 117 ## Attribution 118 119 The list of opcodes was originally taken 120 verbatim from the 'opcode' crate found in 121 [rust-bitcoin](https://github.com/rust-bitcoin/rust-bitcoin). 122 123 [nixos]: https://nixos.org/ 124 [flake]: https://nixos.org/manual/nix/unstable/command-ref/new-cli/nix3-flake.html