library_blockchain/
transaction.rs

1
2use serde::{Serialize};
3use super::*;
4use std::{collections::HashSet};
5
6extern crate serde;
7
8/// The field of to_addr is the name of a account for example Lucy
9/// </br></br>
10/// The field of to_amount is the value of a account for 10000. Do not write 10_000 because of deserialized mechanism used in the program.
11#[derive( Debug,Clone, serde::Serialize)]
12pub struct Amount  {
13    pub to_addr:  Address,
14    pub amount:   u64,
15}
16
17
18
19/// Trx contain 2 pieces of info: Set of I/O that I=O - Value of TRXs=Sum(Inputs) Value of the Fee =Sum(Inputs)-Sum(Outputs)
20/// </br></br>
21/// We implement coinbase TRXs model: do not require inputs, produce an output - allow the miner to collect all the trx fees in that block and that block's block reward (coin genesis)
22
23#[derive(Debug,Clone,Serialize)]
24pub struct Transaction  {
25    pub inputs: Vec<Amount>,
26    pub outputs: Vec<Amount>,
27}
28
29/// Consume for IO hash,value clousures
30pub enum IO {
31    Input,
32    Output,
33}
34
35/// Parent trait is for expanding transaction component in the future.
36pub trait SuperTransaction {}
37
38/// Consume SuperTransaction(Child)
39pub trait Put
40where
41    Self: SuperTransaction,
42{
43    fn returns_closure_io(&self, io: &IO) -> Box<(dyn Fn() -> u64 + '_)>;
44    fn returns_closure_io_hash(&self, io: &IO) -> Box<(dyn Fn() -> HashSet<Hash> + '_)>;
45}
46
47impl  SuperTransaction for Transaction  {}
48
49impl  Put for Transaction  {
50    fn returns_closure_io(&self, io: &IO) -> Box<(dyn Fn() -> u64 + '_)> {
51        match io {
52            IO::Input => Box::new(|| self.inputs.iter().map(|input| input.amount).sum()),
53            IO::Output => Box::new(|| self.outputs.iter().map(|output| output.amount).sum()),
54        }
55    }
56
57    fn returns_closure_io_hash(&self, io: &IO) -> Box<(dyn Fn() -> HashSet<Hash> + '_)> {
58        match io {
59            IO::Input => Box::new(|| {
60                self.inputs
61                    .iter()
62                    .map(|input| input.hash())
63                    .collect::<HashSet<Hash>>()
64            }),
65            IO::Output => Box::new(|| {
66                self.outputs
67                    .iter()
68                    .map(|output| output.hash())
69                    .collect::<HashSet<Hash>>()
70            }),
71        }
72    }
73}
74
75impl  Transaction  {
76    pub fn default() -> Transaction {
77        Self::new(vec![
78
79        ], vec![
80            // transaction::Value {
81            //     to_addr: "Alice".to_owned(),
82            //     value: 47,
83            // },
84            // transaction::Value {
85            //     to_addr: "Bob".to_owned(),
86            //     value: 3
87            // },
88       ])
89    }
90    pub fn new(inputs: Vec<Amount >, outputs: Vec<Amount >) -> Transaction  {
91        Self {
92            inputs: inputs,
93            outputs: outputs,
94        }
95    }
96
97    //    pub fn trx_data<F>(&mut self, mut f: F) // We bring in self, but only f is generic F. f is the closure
98    //     where
99    //         F: FnMut(&mut Vec<Value>, &mut Vec<Value>), // The closure takes mutable vectors of u32
100    //                                                 // which are the year and population data
101    //     {
102    //         f(&mut self.inputs, &mut self.outputs) // Finally this is the actual function. It says
103    //                                                   // "use a closure on self.years and self.populations"
104    //                                                   // We can do whatever we want with the closure
105    //     }
106
107    pub fn is_coinbase(&self) -> bool {
108        (&self.inputs).len() as u8 == 0
109    }
110}
111
112impl  Hashable for Amount  {
113    fn bytes(&self) -> Vec<u8> {
114        let mut bytes = vec![];
115
116        bytes.extend(self.to_addr.as_bytes());
117        bytes.extend(&lib_block_u64_bytes(&self.amount));
118
119        bytes
120    }
121}
122
123impl  Hashable for Transaction  {
124    fn bytes(&self) -> Vec<u8> {
125        let mut bytes = vec![];
126
127        bytes.extend(
128            self.inputs
129                .iter()
130                .flat_map(|input| input.bytes())
131                .collect::<Vec<u8>>(),
132        );
133
134        bytes.extend(
135            self.outputs
136                .iter()
137                .flat_map(|output| output.bytes())
138                .collect::<Vec<u8>>(),
139        );
140
141        bytes
142    }
143}
144
145
146
147// macro_rules! call_on_self {
148//     ($receiver:ident, $F:ident) => {
149//         $receiver.$F()
150//     };
151// }
152// fn return_closure_hash_data(in_or_out: &str)-> impl Fn(&Vec<Output>)-> HashSet<Hash>
153//      {
154//          |ref inputs| {
155//                     inputs
156//                     .iter()
157//                     .map(|input| input.hash())
158//                     .collect::<HashSet<Hash>>()
159//     }
160// }
161// impl PartialEq<Value> for Value {
162//     fn eq(&self, other: &Value) -> bool {
163//         self.to_addr== other.to_addr && self.value== other.value
164//     }
165// }
166
167// impl  Deref for Transaction  {
168//     type Target =  Vec<u8> ;
169//     fn deref(&self) -> &Self::Target {          
170//         let mut trx_bytes:Vec<u8>= vec![];
171//         trx_bytes.extend(&self.inputs.iter()
172//                 .flat_map(|input| input.bytes())
173//                 .collect::<Vec<u8>>());
174//         trx_bytes.extend(&self.outputs.iter()
175//                 .flat_map(|output| output.bytes())
176//                 .collect::<Vec<u8>>());
177//         &trx_bytes.clone()
178        
179//     }
180// }
181// trait TraitOptionTransaction{}
182// impl TraitOptionTransaction for OptionTransaction<'_>{}
183
184//#[derive(Serialize, Deserialize)]
185//#[serde(remote = "OptionTransaction")]
186
187//#[derive(Serialize, Deserialize)]
188// pub struct OptionTransaction {
189//     pub puts:  Option<  Transaction>
190// }
191// impl  OptionTransaction {
192//     pub fn new(inputs: Vec<Amount>, outputs: Vec<Amount>) ->  Self {
193
194//         Some(Self {
195//              inputs,
196//              outputs,
197//          })
198//      }
199// pub fn new(&self) -> OptionTransaction  {
200//     let puts = self.puts;
201//     OptionTransaction { puts, }
202// }
203//}
204
205// impl  std::ops::DerefMut for OptionTransaction  {
206//     fn deref_mut(&mut self) -> &mut Self::Target {
207//         mut self.puts
208//     }
209// }
210// impl  Default for OptionTransaction {
211
212//     fn default () -> Self {
213//         OptionTransaction {
214//             puts: &None
215//         }
216//     }
217// }