use crate::crypto::sign_ed25519::{self as sign};
use crate::primitives::asset::Asset;
use crate::primitives::{
asset::TokenAmount,
transaction::{OutPoint, Transaction, TxIn, TxOut},
};
use crate::script::lang::Script;
use crate::utils::transaction_utils::{construct_address, construct_tx_in_out_signable_hash};
use std::collections::BTreeMap;
pub fn generate_tx_with_ins_and_outs_assets(
input_assets: &[(u64, Option<&str>, Option<String>)],
output_assets: &[(u64, Option<&str>)],
) -> (BTreeMap<OutPoint, TxOut>, Transaction) {
let (pk, sk) = sign::gen_keypair();
let spk = construct_address(&pk);
let mut tx = Transaction::new();
let mut utxo_set: BTreeMap<OutPoint, TxOut> = BTreeMap::new();
for (output_amount, genesis_hash) in output_assets {
let tx_out = match genesis_hash {
Some(drs) => {
let item = Asset::item(*output_amount, Some(drs.to_string()), None);
TxOut::new_asset(spk.clone(), item, None)
}
None => TxOut::new_token_amount(spk.clone(), TokenAmount(*output_amount), None),
};
tx.outputs.push(tx_out);
}
for (input_amount, genesis_hash, md) in input_assets {
let tx_previous_out = OutPoint::new("tx_hash".to_owned(), tx.inputs.len() as i32);
let tx_in_previous_out = match genesis_hash {
Some(drs) => {
let item = Asset::item(*input_amount, Some(drs.to_string()), md.clone());
TxOut::new_asset(spk.clone(), item, None)
}
None => TxOut::new_token_amount(spk.clone(), TokenAmount(*input_amount), None),
};
let signable_hash = construct_tx_in_out_signable_hash(
&TxIn {
previous_out: Some(tx_previous_out.clone()),
script_signature: Script::new(),
},
&tx.outputs,
);
let signature = sign::sign_detached(signable_hash.as_bytes(), &sk);
let tx_in = TxIn::new_from_input(
tx_previous_out.clone(),
Script::pay2pkh(signable_hash, signature, pk, None),
);
utxo_set.insert(tx_previous_out, tx_in_previous_out);
tx.inputs.push(tx_in);
}
(utxo_set, tx)
}