use crate::script::LockingScript;
#[derive(Debug, Clone, Default)]
pub struct TransactionOutput {
pub satoshis: Option<u64>,
pub locking_script: LockingScript,
pub change: bool,
}
impl TransactionOutput {
pub fn new(satoshis: u64, locking_script: LockingScript) -> Self {
Self {
satoshis: Some(satoshis),
locking_script,
change: false,
}
}
pub fn new_change(locking_script: LockingScript) -> Self {
Self {
satoshis: None,
locking_script,
change: true,
}
}
pub fn get_satoshis(&self) -> u64 {
self.satoshis.unwrap_or(0)
}
pub fn has_satoshis(&self) -> bool {
self.satoshis.is_some()
}
pub fn serialized_size(&self) -> usize {
let script_bytes = self.locking_script.to_binary();
let script_len = script_bytes.len();
let varint_size = if script_len < 0xFD {
1
} else if script_len <= 0xFFFF {
3
} else if script_len <= 0xFFFFFFFF {
5
} else {
9
};
8 + varint_size + script_len
}
}
impl PartialEq for TransactionOutput {
fn eq(&self, other: &Self) -> bool {
self.satoshis == other.satoshis
&& self.locking_script.to_binary() == other.locking_script.to_binary()
&& self.change == other.change
}
}
impl Eq for TransactionOutput {}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_new_output() {
let locking = LockingScript::new();
let output = TransactionOutput::new(100_000, locking);
assert_eq!(output.satoshis, Some(100_000));
assert!(!output.change);
}
#[test]
fn test_new_change_output() {
let locking = LockingScript::new();
let output = TransactionOutput::new_change(locking);
assert!(output.satoshis.is_none());
assert!(output.change);
}
#[test]
fn test_get_satoshis() {
let locking = LockingScript::new();
let output = TransactionOutput::new(50_000, locking.clone());
assert_eq!(output.get_satoshis(), 50_000);
let change = TransactionOutput::new_change(locking);
assert_eq!(change.get_satoshis(), 0);
}
#[test]
fn test_serialized_size() {
let locking = LockingScript::new();
let output = TransactionOutput::new(100_000, locking);
assert_eq!(output.serialized_size(), 9);
}
#[test]
fn test_serialized_size_with_script() {
let locking =
LockingScript::from_hex("76a914000000000000000000000000000000000000000088ac").unwrap();
let output = TransactionOutput::new(100_000, locking);
assert_eq!(output.serialized_size(), 34);
}
}