Skip to content

Commit

Permalink
Adding taptree_of_horror example.
Browse files Browse the repository at this point in the history
Adding bitcoin_hashes as dev dependency.
  • Loading branch information
miketwenty1 committed Nov 4, 2024
1 parent acbd120 commit 0536e63
Show file tree
Hide file tree
Showing 6 changed files with 440 additions and 4 deletions.
17 changes: 13 additions & 4 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
[package]
name = "miniscript"
version = "12.2.0"
authors = ["Andrew Poelstra <[email protected]>, Sanket Kanjalkar <[email protected]>"]
authors = [
"Andrew Poelstra <[email protected]>, Sanket Kanjalkar <[email protected]>",
]
license = "CC0-1.0"
homepage = "https://github.com/rust-bitcoin/rust-miniscript/"
repository = "https://github.com/rust-bitcoin/rust-miniscript/"
description = "Miniscript: a subset of Bitcoin Script designed for analysis"
keywords = [ "crypto", "bitcoin", "miniscript", "script" ]
keywords = ["crypto", "bitcoin", "miniscript", "script"]
readme = "README.md"
edition = "2021"
rust-version = "1.63.0"
Expand All @@ -32,7 +34,8 @@ actual-serde = { package = "serde", version = "1.0.103", optional = true }
[dev-dependencies]
serde_test = "1.0.147"
bitcoin = { version = "0.32.0", features = ["base64"] }
secp256k1 = {version = "0.29.0", features = ["rand-std"]}
secp256k1 = { version = "0.29.0", features = ["rand-std"] }
bitcoin_hashes = "0.14.0"

[[example]]
name = "htlc"
Expand All @@ -56,7 +59,7 @@ required-features = ["std"]

[[example]]
name = "taproot"
required-features = ["compiler","std"]
required-features = ["compiler", "std"]

[[example]]
name = "psbt_sign_finalize"
Expand All @@ -66,6 +69,12 @@ required-features = ["std", "base64"]
name = "big"
required-features = ["std", "base64", "compiler"]

[[example]]
name = "taptree_of_horror"
path = "examples/taptree_of_horror/taptree_of_horror.rs"
required-features = ["compiler"]


[workspace]
members = ["fuzz"]
exclude = ["embedded", "bitcoind-tests"]
20 changes: 20 additions & 0 deletions examples/taptree_of_horror/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# Taptree of Horror Example

### Running this example:
- `cargo run --example taptree_of_horror --features "compiler"`

### Originally based on the TABConf 6, CTB.
The challenge can be found here:
- https://tabctb.com/six
- https://tabctb.com/six/thebeginning/thetree/grim/iacceptyourterms.html

### This example demonstrates:
- Providing multiple extended private key (xpriv) descriptors for sample personas.
- Creating a policy using logical 'and/or' conditions with preimages and signatures and timelocks.
- Structuring a Taproot tree (taptree) with an internal key into logical branches and leaves based on the policy.
- Implementing nine complex tapleaves within the taptree.
- Building a spending transaction that signs and satisfies one of the tapleaves using signatures, preimages and a timelock.

### Helpful Graphic to visualize using Excalidraw
![taptree_of_horror](./taptree_of_horror.png)

59 changes: 59 additions & 0 deletions examples/taptree_of_horror/helper_fns.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
use std::str::FromStr;

use bitcoin::{
bip32::{DerivationPath, Xpriv},
hashes::{ripemd160, sha256},
};
use bitcoin_hashes::Hash;
use miniscript::{descriptor::DescriptorSecretKey, ToPublicKey};
use secp256k1::Secp256k1;

pub fn produce_grim_hash(secret: &str) -> (sha256::Hash, ripemd160::Hash) {
let mut hash_holder = sha256::Hash::hash(secret.as_bytes());
for _i in 0..5 {
hash_holder = sha256::Hash::hash(hash_holder.as_byte_array());
//println!("{} hash: {}", i, hash_holder);
}

let ripemd_160_final = ripemd160::Hash::hash(hash_holder.as_byte_array());
(hash_holder, ripemd_160_final)
}

pub fn produce_kelly_hash(secret: &str) -> (sha256::Hash, sha256::Hash) {
let prepreimage: Vec<u8> = secret.as_bytes().to_vec();
let preimage_256_hash = sha256::Hash::hash(&prepreimage);
let result256_final = sha256::Hash::hash(&preimage_256_hash.to_byte_array());
(preimage_256_hash, result256_final)
}

pub fn produce_key_pairs(
desc: DescriptorSecretKey,
secp: &Secp256k1<secp256k1::All>,
derivation_without_index: &str,
_alias: &str,
) -> (Vec<bitcoin::PublicKey>, Vec<Xpriv>) {
let mut pks = Vec::new();
let mut prvs = Vec::new();

let xprv = match &desc {
DescriptorSecretKey::XPrv(xpriv) => xpriv,
_ => panic!("not an xpriv"),
};

for i in 0..9 {
let pk = desc
.to_public(secp)
.unwrap()
.at_derivation_index(i)
.unwrap()
.to_public_key();

let derivation_with_index = format!("{}/{}", derivation_without_index, i);
let derivation_path = DerivationPath::from_str(&derivation_with_index).unwrap();
let derived_xpriv: Xpriv = xprv.xkey.derive_priv(secp, &derivation_path).unwrap();

pks.insert(i.try_into().unwrap(), pk);
prvs.insert(i.try_into().unwrap(), derived_xpriv);
}
(pks, prvs)
}
57 changes: 57 additions & 0 deletions examples/taptree_of_horror/taptree_of_horror.excalidraw

Large diffs are not rendered by default.

Binary file added examples/taptree_of_horror/taptree_of_horror.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading

0 comments on commit 0536e63

Please sign in to comment.