Skip to content

Instantly share code, notes, and snippets.

@kannapoix
Last active April 17, 2022 09:02
Show Gist options
  • Save kannapoix/81cb82b6d21b1f84d004e0f00ee65711 to your computer and use it in GitHub Desktop.
Save kannapoix/81cb82b6d21b1f84d004e0f00ee65711 to your computer and use it in GitHub Desktop.
Sample code for unlock P2SH multisig transaction of Bitcoin. Related article is https://zenn.dev/kanna/articles/de3ebb85face02
use std::str::FromStr;
use bitcoin::Address;
use bitcoin::secp256k1::{Secp256k1, Message, SecretKey};
use bitcoin::blockdata::script::{Builder, Script};
use bitcoin::{Transaction, TxIn, OutPoint, hashes::hex::FromHex, SigHashType};
use bitcoin::hashes::Hash;
use bitcoin::consensus::{encode::{serialize_hex}};
fn main() {
let prev_tx_id = "56e9d34f8bff598068df6d3e4c712308500f706b49610f2b245d48a1cc5551e4";
let vout = 1;
let mut input = TxIn::default();
let outpoint = OutPoint::from_str(&format!("{}:{}", prev_tx_id, vout)).unwrap();
input.previous_output = outpoint;
let redeem_script = Script::from_hex("522102a83a8b76e592f576f45d2f429139a97e9247dedceabc26773a85638def7474742102b270fc21d62683e28dd1762845e8d800a8b44f1776b45c43d432da8b2c4e1ce152ae").unwrap();
let output_script = &Address::from_str("bcrt1qnzhemlf4ezzdz4yza3na5nrmv5hq52u58n0fuj").unwrap().script_pubkey();
let output = bitcoin::TxOut {
value: 9000000,
script_pubkey: output_script.clone()
};
let mut tx = Transaction{
version: 1,
lock_time: 0,
input: vec![input],
output: vec![output]
};
let sighash = tx.signature_hash(0, &redeem_script, SigHashType::All.as_u32());
let alice_secret_key = SecretKey::from_str("bdfc1eab7cbc719286a30e48bee298742022707ae065fb8e4098b22408bb57ae").unwrap();
let bob_secret_key = SecretKey::from_str("66683d5ab7d799661fbafe1083d18dc35fe8242a8e09ac425e3b8cbe7512cb81").unwrap();
let secp = Secp256k1::new();
let alice_sig = secp.sign(&Message::from_slice(&sighash.into_inner()[..]).unwrap(), &alice_secret_key);
let mut alice_final_signature = Vec::with_capacity(75);
alice_final_signature.extend_from_slice(&alice_sig.serialize_der());
alice_final_signature.push(SigHashType::All.as_u32() as u8);
let bob_sig = secp.sign(&Message::from_slice(&sighash.into_inner()[..]).unwrap(), &bob_secret_key);
let mut bob_final_signature = Vec::with_capacity(75);
bob_final_signature.extend_from_slice(&bob_sig.serialize_der());
bob_final_signature.push(SigHashType::All.as_u32() as u8);
println!("alice sig: {:?}",serialize_hex(&alice_final_signature));
println!("bob sig: {:?}",serialize_hex(&bob_final_signature));
let script_sig = Builder::new()
.push_int(0)
.push_slice(&alice_final_signature)
.push_slice(&bob_final_signature)
.push_slice(&redeem_script.as_bytes())
.into_script();
tx.input[0].script_sig = script_sig;
let hex_tx = serialize_hex(&tx);
println!("{:?}", &hex_tx);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment