extern crate walletd_bitcoin;
use hex;
use walletd_bitcoin::blockstream::{BTransaction, Input, Output, Status};
use walletd_bitcoin::{BitcoinPrivateKey, BitcoinWallet, Network};
fn main() {
println!("Recreating an example found online here for testing/validation");
let input1 = Input{
txid: "d1a92ad68a031c5324981aa920152bd16975686905db41e3fc9d51c7ff4a20ed".to_string(),
vout: 1,
prevout: Output {
scriptpubkey: "76a914b780d54c6b03b053916333b50a213d566bbedd1388ac".to_string(),
scriptpubkey_asm: "OP_DUP OP_HASH160 OP_PUSHBYTES_20 b780d54c6b03b053916333b50a213d566bbedd13 OP_EQUALVERIFY OP_CHECKSIG".to_string(),
scriptpubkey_type: "p2pkh".to_string(),
scriptpubkey_address: "mxFEHeSxxKjy9YcmFzXNpuE3FFJyby56jA".to_string(),
pubkeyhash: "b780d54c6b03b053916333b50a213d566bbedd13".to_string(),
value: 52000,
},
scriptsig: "76a914b780d54c6b03b053916333b50a213d566bbedd1388ac".to_string(),
scriptsig_asm: "".to_string(),
witness: Vec::new(),
is_coinbase: false,
sequence: 0xffffffff,
inner_redeemscript_asm: "".to_string(),
};
let input2_txid = BTransaction::hex_reverse_byte_order(
&"9cb872539fbe1bc0b9c5562195095f3f35e6e13919259956c6263c9bd53b20b7".to_string(),
)
.unwrap();
println!("input2_txid: {}", &input2_txid);
let input2 = Input {
txid: input2_txid,
vout: 1,
prevout: Output {
scriptpubkey: "0014594c2e3da92d1904f7e7c856220f8cae5efb5564".to_string(),
scriptpubkey_asm: "OP_0 OP_PUSHBYTES_20 594c2e3da92d1904f7e7c856220f8cae5efb5564"
.to_string(),
scriptpubkey_type: "v0_p2wpkh".to_string(),
scriptpubkey_address: "tb1qt9xzu0df95vsfal8eptzyruv4e00k4ty6d8zhh".to_string(),
pubkeyhash: "594c2e3da92d1904f7e7c856220f8cae5efb5564".to_string(),
value: 9300,
..Default::default()
},
scriptsig: "".to_string(),
scriptsig_asm: "".to_string(),
witness: Vec::new(),
is_coinbase: false,
sequence: 0xFFFFFFFF,
inner_redeemscript_asm: "".to_string(),
};
let input3_txid = BTransaction::hex_reverse_byte_order(
&"8012f1ec8aa9a63cf8b200c25ddae2dece42a2495cc473c1758972cfcd84d904".to_string(),
)
.unwrap();
println!("input3_txid: {}", &input3_txid);
let input3 = Input {
txid: input3_txid,
vout: 1,
prevout: Output {
scriptpubkey: "a9146a721dcca372f3c17b2c649b2ba61aa0fda98a9187".to_string(),
scriptpubkey_asm:
"OP_HASH160 OP_PUSHBYTES_20 6a721dcca372f3c17b2c649b2ba61aa0fda98a91 OP_EQUAL"
.to_string(),
scriptpubkey_type: "p2sh".to_string(),
scriptpubkey_address: "2N4yEhDwic9Tm4BRN9EP1hnSu9f6cWJrU31".to_string(),
pubkeyhash: "6a721dcca372f3c17b2c649b2ba61aa0fda98a91".to_string(),
value: 16029969,
},
scriptsig: "".to_string(),
scriptsig_asm: "".to_string(),
witness: Vec::new(),
is_coinbase: false,
sequence: 0xFFFFFFFF,
inner_redeemscript_asm: "".to_string(),
};
let output1 = Output {
scriptpubkey: "0014cb61ee4568082cb59ac26bb96ec8fbe0109a4c00".to_string(),
scriptpubkey_asm: "OP_0 OP_PUSHBYTES_20 cb61ee4568082cb59ac26bb96ec8fbe0109a4c00"
.to_string(),
scriptpubkey_type: "v0_p2wpkh".to_string(),
scriptpubkey_address: "tb1qeds7u3tgpqkttxkzdwukaj8muqgf5nqq6w05ak".to_string(),
value: 16089269,
pubkeyhash: "cb61ee4568082cb59ac26bb96ec8fbe0109a4c00".to_string(),
};
let transaction = BTransaction {
txid: "".to_string(),
version: 2,
locktime: 0,
vin: vec![input1, input2, input3],
vout: vec![output1],
size: 0,
weight: 0,
fee: 0,
status: Status {
..Default::default()
},
};
let unsigned_serialized = BTransaction::serialize(&transaction).unwrap();
println!("unsigned transaction serialized: {}", &unsigned_serialized);
let for_input1 = unsigned_serialized + "01000000";
println!("serialized transaction for input 1 signing: {}", for_input1);
let sighash_for_input1 = &transaction.txid().unwrap();
println!("sighash_for_input1: {}", sighash_for_input1);
let secret_key1 =
BitcoinPrivateKey::from_slice(
&hex::decode("DBFF11E0F2F1AA5089465A591C5E523D1CA92668DED893155CDFABC94CC14E30")
.unwrap()[..],
Network::Testnet,
)
.unwrap();
let first_signature =
BitcoinWallet::signature_sighashall_for_transaction_hash(&sighash_for_input1, &secret_key1)
.unwrap();
println!("first_signature: {}", first_signature);
let for_input2 = &transaction
.serialize_for_segwit_input_index_with_sighash(1, 1)
.unwrap();
println!("serialized transaction for input 2 signing: {}", for_input2);
let sighash_for_input2 = &transaction
.transaction_hash_for_signing_segwit_input_index(1, 1)
.unwrap();
println!("sighash_for_input2: {}", sighash_for_input2);
let secret_key2 =
BitcoinPrivateKey::from_slice(
&hex::decode("26F85CE8B2C635AD92F6148E4443FE415F512F3F29F44AB0E2CBDA819295BBD5")
.unwrap()[..],
Network::Testnet,
)
.unwrap();
let second_signature =
BitcoinWallet::signature_sighashall_for_transaction_hash(&sighash_for_input2, &secret_key2)
.unwrap();
println!("second_signature: {}", second_signature);
let for_input3 = &transaction
.serialize_for_segwit_input_index_with_sighash(2, 1)
.unwrap();
println!("serialized transaction for input 3 signing: {}", for_input3);
let sighash_for_input3 = &transaction
.transaction_hash_for_signing_segwit_input_index(2, 1)
.unwrap();
println!("sighash_for_input3: {}", sighash_for_input3);
let secret_key3 =
BitcoinPrivateKey::from_slice(
&hex::decode("D9172189D7700FDFB4B6A5C4A83990EAEAFE455441B7D43FF85678EB93AC2713")
.unwrap()[..],
Network::Testnet,
)
.unwrap();
let third_signature =
BitcoinWallet::signature_sighashall_for_transaction_hash(&sighash_for_input3, &secret_key3)
.unwrap();
println!("third_signature: {}", second_signature);
let mut signed_transaction = transaction;
signed_transaction.vin[0].scriptsig = "47".to_string()
+ first_signature.as_str()
+ "210242BF11B788DDFF450C791F16E83465CC67328CA945C703469A08E37EF0D0E061";
signed_transaction.vin[2].scriptsig =
"171600146a721dcca372f3c17b2c649b2ba61aa0fda98a91".to_string();
signed_transaction.vin[1].witness = vec![
second_signature,
"025972A1F2532B44348501075075B31EB21C02EEF276B91DB99D30703F2081B773".to_string(),
];
signed_transaction.vin[2].witness = vec![
third_signature,
"02AE68D299CBB8AB99BF24C9AF79A7B13D28AC8CD21F6F7F750300EDA41A589A5D".to_string(),
];
let raw_tx_hex = BTransaction::serialize(&signed_transaction).unwrap();
println!("raw_tx_hex: {}", raw_tx_hex);
}