use bsv_primitives::util::{BsvReader, BsvWriter, VarInt};
use bsv_script::Script;
use crate::TransactionError;
const MAX_SATOSHIS: u64 = 21_000_000 * 100_000_000;
#[derive(Clone, Debug)]
pub struct TransactionOutput {
pub satoshis: u64,
pub locking_script: Script,
pub change: bool,
}
impl TransactionOutput {
pub fn new() -> Self {
TransactionOutput {
satoshis: 0,
locking_script: Script::new(),
change: false,
}
}
pub fn read_from(reader: &mut BsvReader) -> Result<Self, TransactionError> {
let satoshis = reader.read_u64_le().map_err(|e| {
TransactionError::SerializationError(format!("reading satoshis: {}", e))
})?;
let script_len = reader.read_varint().map_err(|e| {
TransactionError::SerializationError(format!("reading script length: {}", e))
})?;
let script_bytes = reader
.read_bytes(script_len.value() as usize)
.map_err(|e| {
TransactionError::SerializationError(format!("reading locking script: {}", e))
})?;
if satoshis > MAX_SATOSHIS {
return Err(TransactionError::SerializationError(format!(
"satoshi value {} exceeds maximum supply ({})",
satoshis, MAX_SATOSHIS
)));
}
Ok(TransactionOutput {
satoshis,
locking_script: Script::from_bytes(script_bytes),
change: false,
})
}
pub fn write_to(&self, writer: &mut BsvWriter) {
writer.write_u64_le(self.satoshis);
let script_bytes = self.locking_script.to_bytes();
writer.write_varint(VarInt::from(script_bytes.len()));
writer.write_bytes(script_bytes);
}
pub fn to_bytes(&self) -> Vec<u8> {
let mut writer = BsvWriter::new();
self.write_to(&mut writer);
writer.into_bytes()
}
pub fn bytes_for_sig_hash(&self) -> Vec<u8> {
self.to_bytes()
}
pub fn locking_script_hex(&self) -> String {
self.locking_script.to_hex()
}
}
impl Default for TransactionOutput {
fn default() -> Self {
Self::new()
}
}