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// }