Skip to content

Release 9.0.0 #488

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Nov 14, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
# 9.0.0 - November 5, 2022

- Fixed a bug dealing with dissatisfying pkh inside thresh
- Changed the signature of `Satisfier::lookup_raw_pkh_pk` API. Only custom implementations
of `Satisfier` need to be updated. The psbt APIs are unchanged.
- Fixed a bug related to display of `raw_pk_h`. These descriptors are experimental
and only usable by opting via `ExtParams` while parsing string.
# 8.0.0 - October 20, 2022

This release contains several significant API overhauls, as well as a bump
Expand Down
6 changes: 5 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "miniscript"
version = "8.0.0"
version = "9.0.0"
authors = ["Andrew Poelstra <apoelstra@wpsoftware.net>, Sanket Kanjalkar <sanket1729@gmail.com>"]
license = "CC0-1.0"
homepage = "https://github.com/rust-bitcoin/rust-miniscript/"
Expand Down Expand Up @@ -60,3 +60,7 @@ required-features = ["std"]
[[example]]
name = "taproot"
required-features = ["compiler","std"]

[[example]]
name = "psbt_sign_finalize"
required-features = ["std"]
1 change: 1 addition & 0 deletions contrib/test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ then
cargo run --example psbt
cargo run --example xpub_descriptors
cargo run --example taproot --features=compiler
cargo run --example psbt_sign_finalize
fi

if [ "$DO_NO_STD" = true ]
Expand Down
179 changes: 179 additions & 0 deletions examples/psbt_sign_finalize.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,179 @@
use std::collections::BTreeMap;
use std::str::FromStr;

use bitcoin::consensus::serialize;
use bitcoin::util::sighash::SighashCache;
use bitcoin::{PackedLockTime, PrivateKey};
use bitcoind::bitcoincore_rpc::jsonrpc::base64;
use bitcoind::bitcoincore_rpc::RawTx;
use miniscript::bitcoin::consensus::encode::deserialize;
use miniscript::bitcoin::hashes::hex::FromHex;
use miniscript::bitcoin::util::psbt;
use miniscript::bitcoin::util::psbt::PartiallySignedTransaction as Psbt;
use miniscript::bitcoin::{
self, secp256k1, Address, Network, OutPoint, Script, Sequence, Transaction, TxIn, TxOut,
};
use miniscript::psbt::{PsbtExt, PsbtInputExt};
use miniscript::Descriptor;

fn main() {
let secp256k1 = secp256k1::Secp256k1::new();

let s = "wsh(t:or_c(pk(027a3565454fe1b749bccaef22aff72843a9c3efefd7b16ac54537a0c23f0ec0de),v:thresh(1,pkh(032d672a1a91cc39d154d366cd231983661b0785c7f27bc338447565844f4a6813),a:pkh(03417129311ed34c242c012cd0a3e0b9bca0065f742d0dfb63c78083ea6a02d4d9),a:pkh(025a687659658baeabdfc415164528065be7bcaade19342241941e556557f01e28))))#7hut9ukn";
let bridge_descriptor = Descriptor::from_str(&s).unwrap();
//let bridge_descriptor = Descriptor::<bitcoin::PublicKey>::from_str(&s).expect("parse descriptor string");
assert!(bridge_descriptor.sanity_check().is_ok());
println!(
"Bridge pubkey script: {}",
bridge_descriptor.script_pubkey()
);
println!(
"Bridge address: {}",
bridge_descriptor.address(Network::Regtest).unwrap()
);
println!(
"Weight for witness satisfaction cost {}",
bridge_descriptor.max_satisfaction_weight().unwrap()
);

let master_private_key_str = "cQhdvB3McbBJdx78VSSumqoHQiSXs75qwLptqwxSQBNBMDxafvaw";
let _master_private_key =
PrivateKey::from_str(master_private_key_str).expect("Can't create private key");
println!(
"Master public key: {}",
_master_private_key.public_key(&secp256k1)
);

let backup1_private_key_str = "cWA34TkfWyHa3d4Vb2jNQvsWJGAHdCTNH73Rht7kAz6vQJcassky";
let backup1_private =
PrivateKey::from_str(backup1_private_key_str).expect("Can't create private key");

println!(
"Backup1 public key: {}",
backup1_private.public_key(&secp256k1)
);

let backup2_private_key_str = "cPJFWUKk8sdL7pcDKrmNiWUyqgovimmhaaZ8WwsByDaJ45qLREkh";
let backup2_private =
PrivateKey::from_str(backup2_private_key_str).expect("Can't create private key");

println!(
"Backup2 public key: {}",
backup2_private.public_key(&secp256k1)
);

let backup3_private_key_str = "cT5cH9UVm81W5QAf5KABXb23RKNSMbMzMx85y6R2mF42L94YwKX6";
let _backup3_private =
PrivateKey::from_str(backup3_private_key_str).expect("Can't create private key");

println!(
"Backup3 public key: {}",
_backup3_private.public_key(&secp256k1)
);

let spend_tx = Transaction {
version: 2,
lock_time: PackedLockTime(5000),
input: vec![],
output: vec![],
};

// Spend one input and spend one output for simplicity.
let mut psbt = Psbt {
unsigned_tx: spend_tx,
unknown: BTreeMap::new(),
proprietary: BTreeMap::new(),
xpub: BTreeMap::new(),
version: 0,
inputs: vec![],
outputs: vec![],
};

let hex_tx = "020000000001018ff27041f3d738f5f84fd5ee62f1c5b36afebfb15f6da0c9d1382ddd0eaaa23c0000000000feffffff02b3884703010000001600142ca3b4e53f17991582d47b15a053b3201891df5200e1f50500000000220020c0ebf552acd2a6f5dee4e067daaef17b3521e283aeaa44a475278617e3d2238a0247304402207b820860a9d425833f729775880b0ed59dd12b64b9a3d1ab677e27e4d6b370700220576003163f8420fe0b9dc8df726cff22cbc191104a2d4ae4f9dfedb087fcec72012103817e1da42a7701df4db94db8576f0e3605f3ab3701608b7e56f92321e4d8999100000000";
let depo_tx: Transaction = deserialize(&Vec::<u8>::from_hex(hex_tx).unwrap()).unwrap();

let receiver = Address::from_str("bcrt1qsdks5za4t6sevaph6tz9ddfjzvhkdkxe9tfrcy").unwrap();

let amount = 100000000;

let (outpoint, witness_utxo) = get_vout(&depo_tx, bridge_descriptor.script_pubkey());

let mut txin = TxIn::default();
txin.previous_output = outpoint;

txin.sequence = Sequence::from_height(26); //Sequence::MAX; //
psbt.unsigned_tx.input.push(txin);

psbt.unsigned_tx.output.push(TxOut {
script_pubkey: receiver.script_pubkey(),
value: amount / 5 - 500,
});

psbt.unsigned_tx.output.push(TxOut {
script_pubkey: bridge_descriptor.script_pubkey(),
value: amount * 4 / 5,
});

// Generating signatures & witness data

let mut input = psbt::Input::default();
input
.update_with_descriptor_unchecked(&bridge_descriptor)
.unwrap();

input.witness_utxo = Some(witness_utxo.clone());
psbt.inputs.push(input);
psbt.outputs.push(psbt::Output::default());

let mut sighash_cache = SighashCache::new(&psbt.unsigned_tx);

let msg = psbt
.sighash_msg(0, &mut sighash_cache, None)
.unwrap()
.to_secp_msg();

// Fixme: Take a parameter
let hash_ty = bitcoin::EcdsaSighashType::All;

let sk1 = backup1_private.inner;
let sk2 = backup2_private.inner;

// Finally construct the signature and add to psbt
let sig1 = secp256k1.sign_ecdsa(&msg, &sk1);
let pk1 = backup1_private.public_key(&secp256k1);
assert!(secp256k1.verify_ecdsa(&msg, &sig1, &pk1.inner).is_ok());

// Second key just in case
let sig2 = secp256k1.sign_ecdsa(&msg, &sk2);
let pk2 = backup2_private.public_key(&secp256k1);
assert!(secp256k1.verify_ecdsa(&msg, &sig2, &pk2.inner).is_ok());

psbt.inputs[0].partial_sigs.insert(
pk1,
bitcoin::EcdsaSig {
sig: sig1,
hash_ty: hash_ty,
},
);

println!("{:#?}", psbt);

let serialized = serialize(&psbt);
println!("{}", base64::encode(&serialized));

psbt.finalize_mut(&secp256k1).unwrap();
println!("{:#?}", psbt);

let tx = psbt.extract_tx();
println!("{}", tx.raw_hex());
}

// Find the Outpoint by spk
fn get_vout(tx: &Transaction, spk: Script) -> (OutPoint, TxOut) {
for (i, txout) in tx.clone().output.into_iter().enumerate() {
if spk == txout.script_pubkey {
return (OutPoint::new(tx.txid(), i as u32), txout);
}
}
panic!("Only call get vout on functions which have the expected outpoint");
}
4 changes: 2 additions & 2 deletions src/miniscript/astelem.rs
Original file line number Diff line number Diff line change
Expand Up @@ -253,7 +253,7 @@ impl<Pk: MiniscriptKey, Ctx: ScriptContext> fmt::Debug for Terminal<Pk, Ctx> {
match *self {
Terminal::PkK(ref pk) => write!(f, "pk_k({:?})", pk),
Terminal::PkH(ref pk) => write!(f, "pk_h({:?})", pk),
Terminal::RawPkH(ref pkh) => write!(f, "pk_h({:?})", pkh),
Terminal::RawPkH(ref pkh) => write!(f, "expr_raw_pk_h({:?})", pkh),
Terminal::After(t) => write!(f, "after({})", t),
Terminal::Older(t) => write!(f, "older({})", t),
Terminal::Sha256(ref h) => write!(f, "sha256({})", h),
Expand Down Expand Up @@ -307,7 +307,7 @@ impl<Pk: MiniscriptKey, Ctx: ScriptContext> fmt::Display for Terminal<Pk, Ctx> {
match *self {
Terminal::PkK(ref pk) => write!(f, "pk_k({})", pk),
Terminal::PkH(ref pk) => write!(f, "pk_h({})", pk),
Terminal::RawPkH(ref pkh) => write!(f, "pk_h({})", pkh),
Terminal::RawPkH(ref pkh) => write!(f, "expr_raw_pk_h({})", pkh),
Terminal::After(t) => write!(f, "after({})", t),
Terminal::Older(t) => write!(f, "older({})", t),
Terminal::Sha256(ref h) => write!(f, "sha256({})", h),
Expand Down
Loading