use serde::{Serialize};
use super::*;
use std::{collections::HashSet};
extern crate serde;
#[derive( Debug,Clone, serde::Serialize)]
pub struct Amount {
pub to_addr: Address,
pub amount: u64,
}
#[derive(Debug,Clone,Serialize)]
pub struct Transaction {
pub inputs: Vec<Amount>,
pub outputs: Vec<Amount>,
}
pub enum IO {
Input,
Output,
}
pub trait SuperTransaction {}
pub trait Put
where
Self: SuperTransaction,
{
fn returns_closure_io(&self, io: &IO) -> Box<(dyn Fn() -> u64 + '_)>;
fn returns_closure_io_hash(&self, io: &IO) -> Box<(dyn Fn() -> HashSet<Hash> + '_)>;
}
impl SuperTransaction for Transaction {}
impl Put for Transaction {
fn returns_closure_io(&self, io: &IO) -> Box<(dyn Fn() -> u64 + '_)> {
match io {
IO::Input => Box::new(|| self.inputs.iter().map(|input| input.amount).sum()),
IO::Output => Box::new(|| self.outputs.iter().map(|output| output.amount).sum()),
}
}
fn returns_closure_io_hash(&self, io: &IO) -> Box<(dyn Fn() -> HashSet<Hash> + '_)> {
match io {
IO::Input => Box::new(|| {
self.inputs
.iter()
.map(|input| input.hash())
.collect::<HashSet<Hash>>()
}),
IO::Output => Box::new(|| {
self.outputs
.iter()
.map(|output| output.hash())
.collect::<HashSet<Hash>>()
}),
}
}
}
impl Transaction {
pub fn default() -> Transaction {
Self::new(vec![
], vec![
])
}
pub fn new(inputs: Vec<Amount >, outputs: Vec<Amount >) -> Transaction {
Self {
inputs: inputs,
outputs: outputs,
}
}
pub fn is_coinbase(&self) -> bool {
(&self.inputs).len() as u8 == 0
}
}
impl Hashable for Amount {
fn bytes(&self) -> Vec<u8> {
let mut bytes = vec![];
bytes.extend(self.to_addr.as_bytes());
bytes.extend(&lib_block_u64_bytes(&self.amount));
bytes
}
}
impl Hashable for Transaction {
fn bytes(&self) -> Vec<u8> {
let mut bytes = vec![];
bytes.extend(
self.inputs
.iter()
.flat_map(|input| input.bytes())
.collect::<Vec<u8>>(),
);
bytes.extend(
self.outputs
.iter()
.flat_map(|output| output.bytes())
.collect::<Vec<u8>>(),
);
bytes
}
}