extern crate bitcoin;
extern crate sapio_miniscript as miniscript;
use bitcoin::blockdata::witness::Witness;
use bitcoin::secp256k1; use miniscript::DescriptorTrait;
use std::collections::HashMap;
use std::str::FromStr;
fn main() {
type BitcoinDescriptor = miniscript::Descriptor<bitcoin::PublicKey>;
let mut tx = bitcoin::Transaction {
version: 2,
lock_time: 0,
input: vec![bitcoin::TxIn {
previous_output: Default::default(),
script_sig: bitcoin::Script::new(),
sequence: 0xffffffff,
witness: Witness::default(),
}],
output: vec![bitcoin::TxOut {
script_pubkey: bitcoin::Script::new(),
value: 100_000_000,
}],
};
#[cfg_attr(feature="cargo-fmt", rustfmt_skip)]
let public_keys = vec![
bitcoin::PublicKey::from_slice(&[2; 33]).expect("key 1"),
bitcoin::PublicKey::from_slice(&[
0x02,
0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
]).expect("key 2"),
bitcoin::PublicKey::from_slice(&[
0x03,
0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
]).expect("key 3"),
];
let bitcoin_sig = bitcoin::EcdsaSig {
sig: secp256k1::ecdsa::Signature::from_str(
"3045\
0221\
00f7c3648c390d87578cd79c8016940aa8e3511c4104cb78daa8fb8e429375efc1\
0220\
531d75c136272f127a5dc14acc0722301cbddc222262934151f140da345af177",
)
.unwrap(),
hash_ty: bitcoin::EcdsaSighashType::All,
};
let descriptor_str = format!(
"wsh(multi(2,{},{},{}))",
public_keys[0], public_keys[1], public_keys[2],
);
let my_descriptor =
BitcoinDescriptor::from_str(&descriptor_str[..]).expect("parse descriptor string");
assert_eq!(my_descriptor.max_satisfaction_weight().unwrap(), 258);
assert_eq!(
format!("{:x}", my_descriptor.script_pubkey()),
"00200ed49b334a12c37f3df8a2974ad91ff95029215a2b53f78155be737907f06163"
);
assert_eq!(
format!(
"{:x}",
my_descriptor
.explicit_script()
.expect("wsh descriptors have unique inner script")
),
"52\
21020202020202020202020202020202020202020202020202020202020202020202\
21020102030405060708010203040506070801020304050607080000000000000000\
21030102030405060708010203040506070801020304050607080000000000000000\
53ae"
);
let original_txin = tx.input[0].clone();
let mut sigs = HashMap::<bitcoin::PublicKey, miniscript::bitcoin::EcdsaSig>::new();
assert!(my_descriptor.satisfy(&mut tx.input[0], &sigs).is_err());
assert_eq!(tx.input[0], original_txin);
sigs.insert(public_keys[1], bitcoin_sig);
assert!(my_descriptor.satisfy(&mut tx.input[0], &sigs).is_err());
assert_eq!(tx.input[0], original_txin);
sigs.insert(public_keys[2], bitcoin_sig);
assert!(my_descriptor.satisfy(&mut tx.input[0], &sigs).is_ok());
assert_ne!(tx.input[0], original_txin);
assert_eq!(tx.input[0].witness.len(), 4); sigs.insert(public_keys[0], bitcoin_sig);
assert!(my_descriptor.satisfy(&mut tx.input[0], &sigs).is_ok());
assert_ne!(tx.input[0], original_txin);
assert_eq!(tx.input[0].witness.len(), 4); }