commit a387559048a6820bdcbdda48a6ea3121bb62ad9f
parent 7df83c62372cecc47be0cd67ef9022362bc73e39
Author: Jared Tobin <jared@jtobin.io>
Date: Sun, 19 Jan 2025 17:53:09 +0400
lib: remove script hashes
These feel a little out of place at present; we're mostly following
rust-bitcoin, which includes them here, so they may get reinserted at
some point if I better-understand why they should be stuffed in this
module rather than another. For now I'm biasing towards simplicity and
keeping them out.
Diffstat:
6 files changed, 24 insertions(+), 764 deletions(-)
diff --git a/bench/Main.hs b/bench/Main.hs
@@ -1,4 +1,3 @@
-{-# OPTIONS_GHC -fno-warn-unused-imports #-}
{-# OPTIONS_GHC -fno-warn-orphans #-}
{-# LANGUAGE BangPatterns #-}
{-# LANGUAGE DeriveGeneric #-}
diff --git a/flake.lock b/flake.lock
@@ -18,132 +18,6 @@
"type": "github"
}
},
- "flake-utils_2": {
- "inputs": {
- "systems": "systems_2"
- },
- "locked": {
- "lastModified": 1710146030,
- "narHash": "sha256-SZ5L6eA7HJ/nmkzGG7/ISclqe6oZdOZTNoesiInkXPQ=",
- "owner": "numtide",
- "repo": "flake-utils",
- "rev": "b1d9ab70662946ef0850d488da1c9019f3a9752a",
- "type": "github"
- },
- "original": {
- "owner": "numtide",
- "repo": "flake-utils",
- "type": "github"
- }
- },
- "flake-utils_3": {
- "inputs": {
- "systems": "systems_3"
- },
- "locked": {
- "lastModified": 1710146030,
- "narHash": "sha256-SZ5L6eA7HJ/nmkzGG7/ISclqe6oZdOZTNoesiInkXPQ=",
- "owner": "numtide",
- "repo": "flake-utils",
- "rev": "b1d9ab70662946ef0850d488da1c9019f3a9752a",
- "type": "github"
- },
- "original": {
- "owner": "numtide",
- "repo": "flake-utils",
- "type": "github"
- }
- },
- "flake-utils_4": {
- "inputs": {
- "systems": "systems_4"
- },
- "locked": {
- "lastModified": 1710146030,
- "narHash": "sha256-SZ5L6eA7HJ/nmkzGG7/ISclqe6oZdOZTNoesiInkXPQ=",
- "owner": "numtide",
- "repo": "flake-utils",
- "rev": "b1d9ab70662946ef0850d488da1c9019f3a9752a",
- "type": "github"
- },
- "original": {
- "owner": "numtide",
- "repo": "flake-utils",
- "type": "github"
- }
- },
- "flake-utils_5": {
- "inputs": {
- "systems": "systems_5"
- },
- "locked": {
- "lastModified": 1710146030,
- "narHash": "sha256-SZ5L6eA7HJ/nmkzGG7/ISclqe6oZdOZTNoesiInkXPQ=",
- "owner": "numtide",
- "repo": "flake-utils",
- "rev": "b1d9ab70662946ef0850d488da1c9019f3a9752a",
- "type": "github"
- },
- "original": {
- "owner": "numtide",
- "repo": "flake-utils",
- "type": "github"
- }
- },
- "flake-utils_6": {
- "inputs": {
- "systems": "systems_6"
- },
- "locked": {
- "lastModified": 1710146030,
- "narHash": "sha256-SZ5L6eA7HJ/nmkzGG7/ISclqe6oZdOZTNoesiInkXPQ=",
- "owner": "numtide",
- "repo": "flake-utils",
- "rev": "b1d9ab70662946ef0850d488da1c9019f3a9752a",
- "type": "github"
- },
- "original": {
- "owner": "numtide",
- "repo": "flake-utils",
- "type": "github"
- }
- },
- "flake-utils_7": {
- "inputs": {
- "systems": "systems_7"
- },
- "locked": {
- "lastModified": 1710146030,
- "narHash": "sha256-SZ5L6eA7HJ/nmkzGG7/ISclqe6oZdOZTNoesiInkXPQ=",
- "owner": "numtide",
- "repo": "flake-utils",
- "rev": "b1d9ab70662946ef0850d488da1c9019f3a9752a",
- "type": "github"
- },
- "original": {
- "owner": "numtide",
- "repo": "flake-utils",
- "type": "github"
- }
- },
- "flake-utils_8": {
- "inputs": {
- "systems": "systems_8"
- },
- "locked": {
- "lastModified": 1710146030,
- "narHash": "sha256-SZ5L6eA7HJ/nmkzGG7/ISclqe6oZdOZTNoesiInkXPQ=",
- "owner": "numtide",
- "repo": "flake-utils",
- "rev": "b1d9ab70662946ef0850d488da1c9019f3a9752a",
- "type": "github"
- },
- "original": {
- "owner": "numtide",
- "repo": "flake-utils",
- "type": "github"
- }
- },
"nixpkgs": {
"locked": {
"lastModified": 1725910328,
@@ -160,118 +34,6 @@
"type": "github"
}
},
- "nixpkgs_2": {
- "locked": {
- "lastModified": 1725910328,
- "narHash": "sha256-n9pCtzGZ0httmTwMuEbi5E78UQ4ZbQMr1pzi5N0LAG8=",
- "owner": "NixOS",
- "repo": "nixpkgs",
- "rev": "5775c2583f1801df7b790bf7f7d710a19bac66f4",
- "type": "github"
- },
- "original": {
- "owner": "NixOS",
- "ref": "nixpkgs-unstable",
- "repo": "nixpkgs",
- "type": "github"
- }
- },
- "nixpkgs_3": {
- "locked": {
- "lastModified": 1725910328,
- "narHash": "sha256-n9pCtzGZ0httmTwMuEbi5E78UQ4ZbQMr1pzi5N0LAG8=",
- "owner": "NixOS",
- "repo": "nixpkgs",
- "rev": "5775c2583f1801df7b790bf7f7d710a19bac66f4",
- "type": "github"
- },
- "original": {
- "owner": "NixOS",
- "ref": "nixpkgs-unstable",
- "repo": "nixpkgs",
- "type": "github"
- }
- },
- "nixpkgs_4": {
- "locked": {
- "lastModified": 1725910328,
- "narHash": "sha256-n9pCtzGZ0httmTwMuEbi5E78UQ4ZbQMr1pzi5N0LAG8=",
- "owner": "NixOS",
- "repo": "nixpkgs",
- "rev": "5775c2583f1801df7b790bf7f7d710a19bac66f4",
- "type": "github"
- },
- "original": {
- "owner": "NixOS",
- "ref": "nixpkgs-unstable",
- "repo": "nixpkgs",
- "type": "github"
- }
- },
- "nixpkgs_5": {
- "locked": {
- "lastModified": 1725910328,
- "narHash": "sha256-n9pCtzGZ0httmTwMuEbi5E78UQ4ZbQMr1pzi5N0LAG8=",
- "owner": "NixOS",
- "repo": "nixpkgs",
- "rev": "5775c2583f1801df7b790bf7f7d710a19bac66f4",
- "type": "github"
- },
- "original": {
- "owner": "NixOS",
- "ref": "nixpkgs-unstable",
- "repo": "nixpkgs",
- "type": "github"
- }
- },
- "nixpkgs_6": {
- "locked": {
- "lastModified": 1725910328,
- "narHash": "sha256-n9pCtzGZ0httmTwMuEbi5E78UQ4ZbQMr1pzi5N0LAG8=",
- "owner": "NixOS",
- "repo": "nixpkgs",
- "rev": "5775c2583f1801df7b790bf7f7d710a19bac66f4",
- "type": "github"
- },
- "original": {
- "owner": "NixOS",
- "ref": "nixpkgs-unstable",
- "repo": "nixpkgs",
- "type": "github"
- }
- },
- "nixpkgs_7": {
- "locked": {
- "lastModified": 1725910328,
- "narHash": "sha256-n9pCtzGZ0httmTwMuEbi5E78UQ4ZbQMr1pzi5N0LAG8=",
- "owner": "NixOS",
- "repo": "nixpkgs",
- "rev": "5775c2583f1801df7b790bf7f7d710a19bac66f4",
- "type": "github"
- },
- "original": {
- "owner": "NixOS",
- "ref": "nixpkgs-unstable",
- "repo": "nixpkgs",
- "type": "github"
- }
- },
- "nixpkgs_8": {
- "locked": {
- "lastModified": 1725910328,
- "narHash": "sha256-n9pCtzGZ0httmTwMuEbi5E78UQ4ZbQMr1pzi5N0LAG8=",
- "owner": "NixOS",
- "repo": "nixpkgs",
- "rev": "5775c2583f1801df7b790bf7f7d710a19bac66f4",
- "type": "github"
- },
- "original": {
- "owner": "NixOS",
- "ref": "nixpkgs-unstable",
- "repo": "nixpkgs",
- "type": "github"
- }
- },
"ppad-base16": {
"inputs": {
"flake-utils": "flake-utils",
@@ -292,253 +54,17 @@
"url": "git://git.ppad.tech/base16.git"
}
},
- "ppad-base58": {
- "inputs": {
- "flake-utils": [
- "ppad-base58",
- "ppad-sha256",
- "flake-utils"
- ],
- "nixpkgs": [
- "ppad-base58",
- "ppad-sha256",
- "nixpkgs"
- ],
- "ppad-sha256": "ppad-sha256"
- },
- "locked": {
- "lastModified": 1737143175,
- "narHash": "sha256-Soj/qor6EFXgWjqDgO1dJGh63+4zqxyIV4+LyDmGnjY=",
- "ref": "master",
- "rev": "08a271a7faf8fe4d5640e90ecabe107dbdda9dbb",
- "revCount": 15,
- "type": "git",
- "url": "git://git.ppad.tech/base58.git"
- },
- "original": {
- "ref": "master",
- "type": "git",
- "url": "git://git.ppad.tech/base58.git"
- }
- },
- "ppad-bech32": {
- "inputs": {
- "flake-utils": "flake-utils_3",
- "nixpkgs": "nixpkgs_3"
- },
- "locked": {
- "lastModified": 1736713898,
- "narHash": "sha256-NpTs+/zBwn6ibJekGOD1XsQSxjC9gx0vr4VBRJtVcm8=",
- "ref": "master",
- "rev": "a6e777c02e55e48442dbe5fa46a58d321570b6a6",
- "revCount": 59,
- "type": "git",
- "url": "git://git.ppad.tech/bech32.git"
- },
- "original": {
- "ref": "master",
- "type": "git",
- "url": "git://git.ppad.tech/bech32.git"
- }
- },
- "ppad-hmac-drbg": {
- "inputs": {
- "flake-utils": [
- "ppad-secp256k1",
- "ppad-hmac-drbg",
- "ppad-sha256",
- "flake-utils"
- ],
- "nixpkgs": [
- "ppad-secp256k1",
- "ppad-hmac-drbg",
- "ppad-sha256",
- "nixpkgs"
- ],
- "ppad-sha256": "ppad-sha256_2",
- "ppad-sha512": "ppad-sha512"
- },
- "locked": {
- "lastModified": 1731565487,
- "narHash": "sha256-ARrXvAIAaA3H1KuvZxWywh72s5KTIZ+BUHMZ3Rgp9dA=",
- "ref": "master",
- "rev": "e7ec90dfcbb3749148da69e3919c3c14880f92be",
- "revCount": 42,
- "type": "git",
- "url": "git://git.ppad.tech/hmac-drbg.git"
- },
- "original": {
- "ref": "master",
- "type": "git",
- "url": "git://git.ppad.tech/hmac-drbg.git"
- }
- },
- "ppad-ripemd160": {
- "inputs": {
- "flake-utils": "flake-utils_4",
- "nixpkgs": "nixpkgs_4"
- },
- "locked": {
- "lastModified": 1737140550,
- "narHash": "sha256-tmbu+Z33FC2VnAMOLYcyjBQK43BNXcTSKLto402Wd1I=",
- "ref": "master",
- "rev": "7ee1639639d7e7c85ebaa35a1da8fb0a0628ab8b",
- "revCount": 17,
- "type": "git",
- "url": "git://git.ppad.tech/ripemd160.git"
- },
- "original": {
- "ref": "master",
- "type": "git",
- "url": "git://git.ppad.tech/ripemd160.git"
- }
- },
- "ppad-secp256k1": {
- "inputs": {
- "flake-utils": [
- "ppad-secp256k1",
- "ppad-sha256",
- "flake-utils"
- ],
- "nixpkgs": [
- "ppad-secp256k1",
- "ppad-sha256",
- "nixpkgs"
- ],
- "ppad-hmac-drbg": "ppad-hmac-drbg",
- "ppad-sha256": "ppad-sha256_3"
- },
- "locked": {
- "lastModified": 1737143218,
- "narHash": "sha256-g7SDUf/gS5cDMQLA0y/3cecAoRJctqovyyILiuWzmXY=",
- "ref": "master",
- "rev": "a456a84a32574eec829bbb152bc07093e2039a88",
- "revCount": 133,
- "type": "git",
- "url": "git://git.ppad.tech/secp256k1.git"
- },
- "original": {
- "ref": "master",
- "type": "git",
- "url": "git://git.ppad.tech/secp256k1.git"
- }
- },
- "ppad-sha256": {
- "inputs": {
- "flake-utils": "flake-utils_2",
- "nixpkgs": "nixpkgs_2"
- },
- "locked": {
- "lastModified": 1737140591,
- "narHash": "sha256-jsIDUQuxf7iv/r0Yxn6yCMRVhgq7Sk0SNjwdQ9GhASU=",
- "ref": "master",
- "rev": "c1d5aa2a01d183f2ef71573cdba4591ce0f7b59c",
- "revCount": 86,
- "type": "git",
- "url": "git://git.ppad.tech/sha256.git"
- },
- "original": {
- "ref": "master",
- "type": "git",
- "url": "git://git.ppad.tech/sha256.git"
- }
- },
- "ppad-sha256_2": {
- "inputs": {
- "flake-utils": "flake-utils_5",
- "nixpkgs": "nixpkgs_5"
- },
- "locked": {
- "lastModified": 1726493969,
- "narHash": "sha256-toJ5A5+0/xijqVELjXfE3AdWV24B672R16JWq+gKLFk=",
- "ref": "master",
- "rev": "e92f4e13d6afa962109e76d35c6fcb38045e28ed",
- "revCount": 69,
- "type": "git",
- "url": "git://git.ppad.tech/sha256.git"
- },
- "original": {
- "ref": "master",
- "type": "git",
- "url": "git://git.ppad.tech/sha256.git"
- }
- },
- "ppad-sha256_3": {
- "inputs": {
- "flake-utils": "flake-utils_7",
- "nixpkgs": "nixpkgs_7"
- },
- "locked": {
- "lastModified": 1737140591,
- "narHash": "sha256-jsIDUQuxf7iv/r0Yxn6yCMRVhgq7Sk0SNjwdQ9GhASU=",
- "ref": "master",
- "rev": "c1d5aa2a01d183f2ef71573cdba4591ce0f7b59c",
- "revCount": 86,
- "type": "git",
- "url": "git://git.ppad.tech/sha256.git"
- },
- "original": {
- "ref": "master",
- "type": "git",
- "url": "git://git.ppad.tech/sha256.git"
- }
- },
- "ppad-sha256_4": {
- "inputs": {
- "flake-utils": "flake-utils_8",
- "nixpkgs": "nixpkgs_8"
- },
- "locked": {
- "lastModified": 1737140591,
- "narHash": "sha256-jsIDUQuxf7iv/r0Yxn6yCMRVhgq7Sk0SNjwdQ9GhASU=",
- "ref": "master",
- "rev": "c1d5aa2a01d183f2ef71573cdba4591ce0f7b59c",
- "revCount": 86,
- "type": "git",
- "url": "git://git.ppad.tech/sha256.git"
- },
- "original": {
- "ref": "master",
- "type": "git",
- "url": "git://git.ppad.tech/sha256.git"
- }
- },
- "ppad-sha512": {
- "inputs": {
- "flake-utils": "flake-utils_6",
- "nixpkgs": "nixpkgs_6"
- },
- "locked": {
- "lastModified": 1728147405,
- "narHash": "sha256-KQ56eDSkXNvy7VXPC2+L64b94nqYjxU0JkZxKFtIePA=",
- "ref": "master",
- "rev": "c454a32a4a39b0e18601b8139a12ae895c9b631e",
- "revCount": 8,
- "type": "git",
- "url": "git://git.ppad.tech/sha512.git"
- },
- "original": {
- "ref": "master",
- "type": "git",
- "url": "git://git.ppad.tech/sha512.git"
- }
- },
"root": {
"inputs": {
"flake-utils": [
- "ppad-sha256",
+ "ppad-base16",
"flake-utils"
],
"nixpkgs": [
- "ppad-sha256",
+ "ppad-base16",
"nixpkgs"
],
- "ppad-base16": "ppad-base16",
- "ppad-base58": "ppad-base58",
- "ppad-bech32": "ppad-bech32",
- "ppad-ripemd160": "ppad-ripemd160",
- "ppad-secp256k1": "ppad-secp256k1",
- "ppad-sha256": "ppad-sha256_4"
+ "ppad-base16": "ppad-base16"
}
},
"systems": {
@@ -555,111 +81,6 @@
"repo": "default",
"type": "github"
}
- },
- "systems_2": {
- "locked": {
- "lastModified": 1681028828,
- "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
- "owner": "nix-systems",
- "repo": "default",
- "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
- "type": "github"
- },
- "original": {
- "owner": "nix-systems",
- "repo": "default",
- "type": "github"
- }
- },
- "systems_3": {
- "locked": {
- "lastModified": 1681028828,
- "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
- "owner": "nix-systems",
- "repo": "default",
- "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
- "type": "github"
- },
- "original": {
- "owner": "nix-systems",
- "repo": "default",
- "type": "github"
- }
- },
- "systems_4": {
- "locked": {
- "lastModified": 1681028828,
- "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
- "owner": "nix-systems",
- "repo": "default",
- "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
- "type": "github"
- },
- "original": {
- "owner": "nix-systems",
- "repo": "default",
- "type": "github"
- }
- },
- "systems_5": {
- "locked": {
- "lastModified": 1681028828,
- "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
- "owner": "nix-systems",
- "repo": "default",
- "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
- "type": "github"
- },
- "original": {
- "owner": "nix-systems",
- "repo": "default",
- "type": "github"
- }
- },
- "systems_6": {
- "locked": {
- "lastModified": 1681028828,
- "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
- "owner": "nix-systems",
- "repo": "default",
- "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
- "type": "github"
- },
- "original": {
- "owner": "nix-systems",
- "repo": "default",
- "type": "github"
- }
- },
- "systems_7": {
- "locked": {
- "lastModified": 1681028828,
- "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
- "owner": "nix-systems",
- "repo": "default",
- "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
- "type": "github"
- },
- "original": {
- "owner": "nix-systems",
- "repo": "default",
- "type": "github"
- }
- },
- "systems_8": {
- "locked": {
- "lastModified": 1681028828,
- "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
- "owner": "nix-systems",
- "repo": "default",
- "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
- "type": "github"
- },
- "original": {
- "owner": "nix-systems",
- "repo": "default",
- "type": "github"
- }
}
},
"root": "root",
diff --git a/flake.nix b/flake.nix
@@ -1,45 +1,19 @@
{
- description = "Haskell Bitcoin primitives.";
+ description = "Primitive Script support for Haskell.";
inputs = {
- ppad-sha256 = {
- type = "git";
- url = "git://git.ppad.tech/sha256.git";
- ref = "master";
- };
ppad-base16 = {
type = "git";
url = "git://git.ppad.tech/base16.git";
ref = "master";
};
- ppad-base58 = {
- type = "git";
- url = "git://git.ppad.tech/base58.git";
- ref = "master";
- };
- ppad-bech32 = {
- type = "git";
- url = "git://git.ppad.tech/bech32.git";
- ref = "master";
- };
- ppad-ripemd160 = {
- type = "git";
- url = "git://git.ppad.tech/ripemd160.git";
- ref = "master";
- };
- ppad-secp256k1 = {
- type = "git";
- url = "git://git.ppad.tech/secp256k1.git";
- ref = "master";
- };
- flake-utils.follows = "ppad-sha256/flake-utils";
- nixpkgs.follows = "ppad-sha256/nixpkgs";
+ flake-utils.follows = "ppad-base16/flake-utils";
+ nixpkgs.follows = "ppad-base16/nixpkgs";
};
outputs = { self, nixpkgs, flake-utils
- , ppad-sha256, ppad-ripemd160
- , ppad-bech32, ppad-base58, ppad-base16
- , ppad-secp256k1 }:
+ , ppad-base16
+ }:
flake-utils.lib.eachDefaultSystem (system:
let
lib = "ppad-script";
@@ -47,27 +21,12 @@
pkgs = import nixpkgs { inherit system; };
hlib = pkgs.haskell.lib;
- sha256 = ppad-sha256.packages.${system}.default;
- bech32 = ppad-bech32.packages.${system}.default;
base16 = ppad-base16.packages.${system}.default;
- base58 = ppad-base58.packages.${system}.default;
- ripemd160 = ppad-ripemd160.packages.${system}.default;
- secp256k1 = ppad-secp256k1.packages.${system}.default;
hpkgs = pkgs.haskell.packages.ghc981.extend (new: old: {
- ppad-sha256 = sha256;
- ppad-bech32 = bech32;
ppad-base16 = base16;
- ppad-base58 = base58;
- ppad-ripemd160 = ripemd160;
- ppad-secp256k1 = secp256k1;
${lib} = old.callCabal2nixWithOptions lib ./. "--enable-profiling" {
- ppad-sha256 = new.ppad-sha256;
- ppad-bech32 = new.ppad-bech32;
ppad-base16 = new.ppad-base16;
- ppad-base58 = new.ppad-base58;
- ppad-ripemd160 = new.ppad-ripemd160;
- ppad-secp256k1 = new.ppad-secp256k1;
};
});
diff --git a/lib/Bitcoin/Prim/Script.hs b/lib/Bitcoin/Prim/Script.hs
@@ -16,13 +16,6 @@
-- including abstract syntax, 'ByteArray', and base16-encoded
-- 'ByteString' versions, as well as fast conversion utilities for
-- working with them.
---
--- Also included are the 'ScriptHash' and
--- 'WitnessScriptHash' types representing
--- [BIP16](https://github.com/bitcoin/bips/blob/master/bip-0016.mediawiki)
--- redeem script and
--- [BIP141](https://github.com/bitcoin/bips/blob/master/bip-0141.mediawiki)
--- witness script hashes.
module Bitcoin.Prim.Script (
-- * Script and Script Terms
@@ -36,22 +29,12 @@ module Bitcoin.Prim.Script (
, to_script
, from_script
- -- * Script Hashes
- , ScriptHash
- , WitnessScriptHash
- , to_scripthash
- , to_witness_scripthash
-
-- for testing etc.
- , _MAX_REDEEM_SCRIPT_SIZE
- , _MAX_WITNESS_SCRIPT_SIZE
, ba_to_bs
, bs_to_ba
) where
import Control.Monad (guard)
-import qualified Crypto.Hash.RIPEMD160 as RIPEMD160
-import qualified Crypto.Hash.SHA256 as SHA256
import qualified Data.Bits as B
import Data.Bits ((.&.), (.|.))
import qualified Data.ByteString as BS
@@ -64,16 +47,6 @@ import Data.Word (Word8, Word16, Word32)
import GHC.ForeignPtr
import System.IO.Unsafe
--- constants ------------------------------------------------------------------
-
--- max redeem script size for a p2sh output
-_MAX_REDEEM_SCRIPT_SIZE :: Int
-_MAX_REDEEM_SCRIPT_SIZE = 520
-
--- max witness script size
-_MAX_WITNESS_SCRIPT_SIZE :: Int
-_MAX_WITNESS_SCRIPT_SIZE = 10_000
-
-- utilities ------------------------------------------------------------------
fi :: (Num a, Integral b) => b -> a
@@ -109,7 +82,7 @@ hilo b =
lo = BU.unsafeIndex hex_charset (fi b .&. 0b00001111)
in (hi, lo)
--- script, hash, and term representation --------------------------------------
+-- script and term representation ---------------------------------------------
-- | A Script program, represented as a 'ByteArray'.
newtype Script = Script BA.ByteArray
@@ -127,41 +100,6 @@ instance Show Term where
let (hi, lo) = hilo w
in "0x" <> (C.chr (fi hi) : C.chr (fi lo) : [])
--- XX we're following rust-bitcoin, but should these really be included
--- in this particular library?
-
--- | A p2sh scripthash, i.e. HASH160 of a 'Script'.
---
--- The underlying 'Script' is guaranteed to be at most 520 bytes, to
--- guarantee in-principle p2sh spendability per
--- [BIP16](https://github.com/bitcoin/bips/blob/master/bip-0016.mediawiki).
-newtype ScriptHash = ScriptHash BS.ByteString
- deriving Eq
-
-instance Show ScriptHash where
- show (ScriptHash bs) = "ScriptHash 0x" <> go bs where
- go b = case BS.uncons b of
- Nothing -> mempty
- Just (h, t) ->
- let (hi, lo) = hilo h
- in C.chr (fi hi) : C.chr (fi lo) : go t
-
--- | A p2wsh witness scripthash, i.e. SHA256 of a 'Script'.
---
--- The underlying 'Script' is guaranteed to be at most 10,000 bytes, to
--- guarantee in-principle p2wsh spendability per
--- [BIP141](https://github.com/bitcoin/bips/blob/master/bip-0141.mediawiki).
-newtype WitnessScriptHash = WitnessScriptHash BS.ByteString
- deriving Eq
-
-instance Show WitnessScriptHash where
- show (WitnessScriptHash bs) = "WitnessScriptHash 0x" <> go bs where
- go b = case BS.uncons b of
- Nothing -> mempty
- Just (h, t) ->
- let (hi, lo) = hilo h
- in C.chr (fi hi) : C.chr (fi lo) : go t
-
-- script conversions ---------------------------------------------------------
-- | Convert a 'Script' to a base16-encoded ByteString.
@@ -234,24 +172,6 @@ from_script (Script bs) = go 0 where
_ -> go (succ j)
--- script hashes --------------------------------------------------------------
-
--- | Convert a 'Script' to a 'ScriptHash', ensuring that it doesn't exceed
--- the maximum redeemscript size.
-to_scripthash :: Script -> Maybe ScriptHash
-to_scripthash (Script bs)
- | BA.sizeofByteArray bs > _MAX_REDEEM_SCRIPT_SIZE = Nothing
- | otherwise = Just $!
- ScriptHash (RIPEMD160.hash (SHA256.hash (ba_to_bs bs)))
-
--- | Convert a 'Script' to a 'WitnessScriptHash', ensuring that it doesn't
--- the maximum witness script size.
-to_witness_scripthash :: Script -> Maybe WitnessScriptHash
-to_witness_scripthash (Script bs)
- | BA.sizeofByteArray bs > _MAX_WITNESS_SCRIPT_SIZE = Nothing
- | otherwise = Just $!
- WitnessScriptHash (SHA256.hash (ba_to_bs bs))
-
-- opcodes and utilities ------------------------------------------------------
-- | Primitive opcodes.
diff --git a/ppad-script.cabal b/ppad-script.cabal
@@ -1,7 +1,7 @@
cabal-version: 3.0
name: ppad-script
version: 0.1.0
-synopsis: Script and utilities.
+synopsis: Primitive (Bitcoin) Script support.
license: MIT
license-file: LICENSE
author: Jared Tobin
@@ -11,7 +11,10 @@ build-type: Simple
tested-with: GHC == { 9.8.1 }
extra-doc-files: CHANGELOG
description:
- A representation of Script, as well as utilities for working with it.
+ Representations for [Script](https://en.bitcoin.it/wiki/Script),
+ including abstract syntax, 'ByteArray', and base16-encoded
+ 'ByteString' versions, as well as fast conversion utilities for
+ working with them.
source-repository head
type: git
@@ -29,11 +32,6 @@ library
, bytestring >= 0.9 && < 0.13
, primitive >= 0.8 && < 0.10
, ppad-base16 >= 0.1 && < 0.2
- , ppad-base58 >= 0.1 && < 0.2
- , ppad-bech32 >= 0.2 && < 0.3
- , ppad-ripemd160 >= 0.1 && < 0.2
- , ppad-secp256k1 >= 0.2.1 && < 0.3
- , ppad-sha256 >= 0.2 && < 0.3
test-suite script-tests
type: exitcode-stdio-1.0
@@ -48,11 +46,7 @@ test-suite script-tests
, base
, bytestring
, ppad-base16
- , ppad-base58
, ppad-script
- , ppad-ripemd160
- , ppad-secp256k1
- , ppad-sha256
, primitive
, tasty
, tasty-hunit
diff --git a/test/Main.hs b/test/Main.hs
@@ -1,5 +1,4 @@
{-# OPTIONS_GHC -fno-warn-orphans #-}
-{-# OPTIONS_GHC -fno-warn-unused-imports #-}
{-# LANGUAGE BangPatterns #-}
{-# LANGUAGE NumericUnderscores #-}
{-# LANGUAGE OverloadedStrings #-}
@@ -7,12 +6,9 @@
module Main where
import Bitcoin.Prim.Script
-import qualified Crypto.Hash.SHA256 as SHA256
-import qualified Crypto.Hash.RIPEMD160 as RIPEMD160
import qualified Data.ByteString as BS
import qualified Data.ByteString.Base16 as B16
import qualified Data.Primitive.ByteArray as BA
-import Data.Word (Word8)
import Test.Tasty
import qualified Test.Tasty.HUnit as H
import qualified Test.Tasty.QuickCheck as Q
@@ -53,29 +49,18 @@ newtype RawScript = RawScript Script
instance Q.Arbitrary RawScript where
arbitrary = fmap (RawScript . Script) Q.arbitrary
--- XX better generators for valid and invalid redeemscripts would be nice.
+-- XX better generators would be nice.
-- pushdata generation needs to be handled carefully.
-newtype ValidRedeemScript = ValidRedeemScript Script
+newtype NonPathologicalScript = NonPathologicalScript Script
deriving (Eq, Show)
-instance Q.Arbitrary ValidRedeemScript where
+instance Q.Arbitrary NonPathologicalScript where
arbitrary = do
- l <- Q.chooseInt (0, _MAX_REDEEM_SCRIPT_SIZE)
+ l <- Q.chooseInt (0, 1_024)
-- pushdata must be added with care; easy to blow up quickcheck
- bs <- fmap BS.pack (Q.vectorOf l (Q.chooseEnum (100, 255)))
- pure (ValidRedeemScript (Script (bs_to_ba bs)))
-
--- too large
-newtype InvalidRedeemScript = InvalidRedeemScript Script
- deriving (Eq, Show)
-
-instance Q.Arbitrary InvalidRedeemScript where
- arbitrary = do
- l <- Q.chooseInt (_MAX_REDEEM_SCRIPT_SIZE + 1, 20_000)
- -- pushdata must be added with care; easy to blow up quickcheck
- bs <- fmap BS.pack (Q.vectorOf l (Q.chooseEnum (100, 255)))
- pure (InvalidRedeemScript (Script (bs_to_ba bs)))
+ bs <- fmap BS.pack (Q.vectorOf l (Q.chooseEnum (80, 255)))
+ pure (NonPathologicalScript (Script (bs_to_ba bs)))
-- properties -----------------------------------------------------------------
@@ -101,25 +86,13 @@ to_base16_inverts_from_base16 (HexBS bs) =
-- we can only use 'from_script' on non-pathological scripts
--
--- note the converse is not true
-to_script_inverts_from_script :: ValidRedeemScript -> Bool
-to_script_inverts_from_script (ValidRedeemScript s) =
+-- note the converse (from_script . to_script ~ id) is not true
+to_script_inverts_from_script :: NonPathologicalScript -> Bool
+to_script_inverts_from_script (NonPathologicalScript s) =
let !terms = from_script s
!script = to_script terms
in script == s
-valid_redeem_script_produces_hash :: ValidRedeemScript -> Bool
-valid_redeem_script_produces_hash (ValidRedeemScript s) =
- case to_scripthash s of
- Just {} -> True
- _ -> False
-
-invalid_redeem_script_doesnt_produce_hash :: InvalidRedeemScript -> Bool
-invalid_redeem_script_doesnt_produce_hash (InvalidRedeemScript s) =
- case to_scripthash s of
- Nothing -> True
- _ -> False
-
-- assertions -----------------------------------------------------------------
decodes_to :: BS.ByteString -> [Term] -> H.Assertion
@@ -221,13 +194,7 @@ main = defaultMain $
, Q.testProperty "to_script . from_script ~ id" $
Q.withMaxSuccess 1000 to_script_inverts_from_script
]
- , testGroup "hashes" [
- Q.testProperty "valid redeem script produces scripthash" $
- Q.withMaxSuccess 100 valid_redeem_script_produces_hash
- , Q.testProperty "invalid redeem script doesn't produce scripthash" $
- Q.withMaxSuccess 100 invalid_redeem_script_doesnt_produce_hash
- ]
- ]
+ ]
, testGroup "unit tests" [
H.testCase "p2pkh script decodes to expected terms"
p2pkh_script_decodes_as_expected