use std::io::Cursor;
use bsv::primitives::private_key::PrivateKey;
use bsv::script::templates::p2pkh::P2PKH;
use bsv::script::templates::ScriptTemplateLock;
use bsv::transaction::beef::{Beef, BEEF_V1};
use bsv::transaction::beef_tx::BeefTx;
use bsv::transaction::transaction::Transaction;
use bsv::transaction::transaction_input::TransactionInput;
use bsv::transaction::transaction_output::TransactionOutput;
fn main() -> Result<(), Box<dyn std::error::Error>> {
let sender_key = PrivateKey::from_hex("1")?;
let sender_p2pkh = P2PKH::from_private_key(sender_key.clone());
let source_locking_script = sender_p2pkh.lock()?;
let source_satoshis: u64 = 100_000;
let mut tx = Transaction::new();
let input = TransactionInput {
source_txid: Some(
"d477af6b2667c29670467e4e0728b685ee07b240235771862318e29ddbe58458".to_string(),
),
source_output_index: 0,
sequence: 0xFFFFFFFF,
..Default::default()
};
tx.add_input(input);
let lock_script = sender_p2pkh.lock()?;
tx.add_output(TransactionOutput {
satoshis: Some(99_500),
locking_script: lock_script,
change: false,
});
let sighash_type = 0x41;
tx.sign(
0,
&sender_p2pkh,
sighash_type,
source_satoshis,
&source_locking_script,
)?;
let original_txid = tx.id()?;
println!("Original transaction ID: {}", original_txid);
let beef_tx = BeefTx::from_tx(tx, None)?;
let mut beef = Beef::new(BEEF_V1);
beef.txs.push(beef_tx);
let mut beef_bytes = Vec::new();
beef.to_binary(&mut beef_bytes)?;
println!("BEEF bytes length: {}", beef_bytes.len());
println!(
"BEEF hex: {}",
beef_bytes
.iter()
.map(|b| format!("{:02x}", b))
.collect::<String>()
);
println!();
let mut cursor = Cursor::new(&beef_bytes);
let decoded_beef = Beef::from_binary(&mut cursor)?;
println!("Decoded BEEF version: {}", decoded_beef.version);
println!("Decoded BEEF bump count: {}", decoded_beef.bumps.len());
println!("Decoded BEEF tx count: {}", decoded_beef.txs.len());
let decoded_txid = &decoded_beef.txs[0].txid;
println!();
println!("Original txid: {}", original_txid);
println!("Decoded BEEF txid: {}", decoded_txid);
if original_txid == *decoded_txid {
println!();
println!("BEEF round-trip verification PASSED: txids match.");
} else {
eprintln!();
eprintln!("BEEF round-trip verification FAILED: txids do not match!");
std::process::exit(1);
}
let mut re_serialized = Vec::new();
decoded_beef.to_binary(&mut re_serialized)?;
if beef_bytes == re_serialized {
println!("Byte-level round-trip verification PASSED: identical bytes.");
} else {
eprintln!("Byte-level round-trip verification FAILED: bytes differ!");
eprintln!(" Original: {} bytes", beef_bytes.len());
eprintln!(" Re-serialized: {} bytes", re_serialized.len());
std::process::exit(1);
}
Ok(())
}