@@ -19,7 +19,8 @@ extern crate miniscript;
1919
2020use bitcoin:: consensus:: Decodable ;
2121use bitcoin:: secp256k1; // secp256k1 re-exported from rust-bitcoin
22- use miniscript:: NullCtx ;
22+ use std:: str:: FromStr ;
23+
2324fn main ( ) {
2425 // tx `f27eba163c38ad3f34971198687a3f1882b7ec818599ffe469a8440d82261c98`
2526 #[ cfg_attr( feature="cargo-fmt" , rustfmt_skip) ]
@@ -83,30 +84,32 @@ fn main() {
8384 0x49 , 0xe5 , 0x32 , 0xde , 0x59 , 0xf4 , 0xbc , 0x87 ,
8485 ] ) ;
8586
86- let ( desc , stack ) = miniscript:: descriptor :: from_txin_with_witness_stack (
87+ let mut interpreter = miniscript:: Interpreter :: from_txdata (
8788 & spk_input_1,
8889 & transaction. input [ 0 ] . script_sig ,
8990 & transaction. input [ 0 ] . witness ,
91+ 0 ,
92+ 0 ,
9093 )
9194 . unwrap ( ) ;
9295
93- println ! ( "Descriptor: {}" , desc) ;
96+ let desc_string = interpreter. inferred_descriptor_string ( ) ;
97+ println ! ( "Descriptor: {}" , desc_string) ;
98+ miniscript:: Descriptor :: < bitcoin:: PublicKey > :: from_str ( & desc_string)
99+ . expect ( "this descriptor can be reparsed with sanity checks passing" ) ;
100+ interpreter
101+ . inferred_descriptor ( )
102+ . expect ( "we can use this method to do the above from_str for us" ) ;
94103
95104 // 1. Example one: learn which keys were used, not bothering
96105 // to verify the signatures (trusting that if they're on
97106 // the blockchain, standardness would've required they be
98107 // either valid or 0-length.
99- let iter = miniscript:: descriptor:: SatisfiedConstraints :: from_descriptor (
100- & desc,
101- stack. clone ( ) ,
102- |_, _| true , // Don't bother checking signatures
103- 0 ,
104- 0 ,
105- ) ;
106108 println ! ( "\n Example one" ) ;
107- for elem in iter {
109+ for elem in interpreter. iter ( |_, _| true ) {
110+ // Don't bother checking signatures
108111 match elem. expect ( "no evaluation error" ) {
109- miniscript:: descriptor :: SatisfiedConstraint :: PublicKey { key, sig } => {
112+ miniscript:: interpreter :: SatisfiedConstraint :: PublicKey { key, sig } => {
110113 println ! ( "Signed with {}: {}" , key, sig) ;
111114 }
112115 _ => { }
@@ -120,22 +123,28 @@ fn main() {
120123 // from the MiniscriptKey which can supplied by `to_pk_ctx` parameter. For example,
121124 // when calculating the script pubkey of a descriptor with xpubs, the secp context and
122125 // child information maybe required.
123- let sighash = transaction. signature_hash ( 0 , & desc. witness_script ( NullCtx ) , 1 ) ;
124- let message = secp256k1:: Message :: from_slice ( & sighash[ ..] ) . expect ( "32-byte hash" ) ;
125-
126- let iter = miniscript:: descriptor:: SatisfiedConstraints :: from_descriptor (
127- & desc,
128- stack. clone ( ) ,
129- |pk, ( sig, sighashtype) | {
130- sighashtype == bitcoin:: SigHashType :: All && secp. verify ( & message, & sig, & pk. key ) . is_ok ( )
131- } ,
126+ let mut interpreter = miniscript:: Interpreter :: from_txdata (
127+ & spk_input_1,
128+ & transaction. input [ 0 ] . script_sig ,
129+ & transaction. input [ 0 ] . witness ,
132130 0 ,
133131 0 ,
134- ) ;
132+ )
133+ . unwrap ( ) ;
134+
135+ // We can set the amount passed to `sighash_verify` to 0 because this is a legacy
136+ // transaction and so the amount won't actually be checked by the signature
137+ let vfyfn = interpreter. sighash_verify ( & secp, & transaction, 0 , 0 ) ;
138+ // Restrict to sighash_all just to demonstrate how to add additional filters
139+ // `&_` needed here because of https://github.com/rust-lang/rust/issues/79187
140+ let vfyfn = move |pk : & _ , bitcoinsig : miniscript:: BitcoinSig | {
141+ bitcoinsig. 1 == bitcoin:: SigHashType :: All && vfyfn ( pk, bitcoinsig)
142+ } ;
143+
135144 println ! ( "\n Example two" ) ;
136- for elem in iter {
145+ for elem in interpreter . iter ( vfyfn ) {
137146 match elem. expect ( "no evaluation error" ) {
138- miniscript:: descriptor :: SatisfiedConstraint :: PublicKey { key, sig } => {
147+ miniscript:: interpreter :: SatisfiedConstraint :: PublicKey { key, sig } => {
139148 println ! ( "Signed with {}: {}" , key, sig) ;
140149 }
141150 _ => { }
@@ -147,15 +156,18 @@ fn main() {
147156 let secp = secp256k1:: Secp256k1 :: new ( ) ;
148157 let message = secp256k1:: Message :: from_slice ( & [ 0x01 ; 32 ] [ ..] ) . expect ( "32-byte hash" ) ;
149158
150- let iter = miniscript:: descriptor:: SatisfiedConstraints :: from_descriptor (
151- & desc,
152- stack. clone ( ) ,
153- |pk, ( sig, sighashtype) | {
154- sighashtype == bitcoin:: SigHashType :: All && secp. verify ( & message, & sig, & pk. key ) . is_ok ( )
155- } ,
159+ let mut interpreter = miniscript:: Interpreter :: from_txdata (
160+ & spk_input_1,
161+ & transaction. input [ 0 ] . script_sig ,
162+ & transaction. input [ 0 ] . witness ,
156163 0 ,
157164 0 ,
158- ) ;
165+ )
166+ . unwrap ( ) ;
167+
168+ let iter = interpreter. iter ( |pk, ( sig, sighashtype) | {
169+ sighashtype == bitcoin:: SigHashType :: All && secp. verify ( & message, & sig, & pk. key ) . is_ok ( )
170+ } ) ;
159171 println ! ( "\n Example three" ) ;
160172 for elem in iter {
161173 let error = elem. expect_err ( "evaluation error" ) ;
0 commit comments