smart_contract/
transaction.rs1use alloc::{vec, vec::Vec};
2
3use crate::payload::{Readable, Writeable};
4
5#[repr(u8)]
6pub enum TransactionTag {
7 Nop,
8 Transfer,
9 Contract,
10 Stake,
11}
12
13pub trait Transaction: Writeable + Readable + Sized {
14 fn send_transaction(self) {
15 let mut payload = vec![];
16 self.write_to(&mut payload);
17
18 unsafe {
19 crate::sys::_send_transaction(self.tag() as u8, payload.as_ptr(), payload.len());
20 }
21 }
22
23 fn tag(&self) -> TransactionTag;
24}
25
26#[derive(Default)]
27pub struct Transfer {
28 pub destination: [u8; 32],
29 pub amount: u64,
30
31 pub invocation: Option<Invocation>,
32}
33
34#[derive(Default)]
35pub struct Invocation {
36 pub gas_limit: u64,
37 pub gas_deposit: u64,
38 pub func_name: Vec<u8>,
39 pub func_params: Vec<u8>,
40}
41
42impl Writeable for Transfer {
43 fn write_to(&self, buffer: &mut Vec<u8>) {
44 self.destination.write_to(buffer);
45 self.amount.write_to(buffer);
46
47 if let Some(ref invocation) = self.invocation {
48 invocation.gas_limit.write_to(buffer);
49 invocation.gas_deposit.write_to(buffer);
50 invocation.func_name.write_to(buffer);
51 invocation.func_params.write_to(buffer);
52 }
53 }
54}
55
56impl Readable for Transfer {
57 fn read_from(buffer: &[u8], pos: &mut u64) -> Transfer {
58 let mut params = Transfer::default();
59
60 params.destination = <[u8; 32]>::read_from(buffer, pos);
61 params.amount = u64::read_from(buffer, pos);
62
63 if *pos < buffer.len() as u64 {
64 let mut invocation = Invocation::default();
65
66 u64::read_from(buffer, pos); u64::read_from(buffer, pos); if *pos < buffer.len() as u64 {
70 invocation.func_name = Vec::<u8>::read_from(buffer, pos); }
72 if *pos < buffer.len() as u64 {
73 invocation.func_params = Vec::<u8>::read_from(buffer, pos) }
75 params.invocation = Some(invocation);
76 }
77
78 params
79 }
80}
81
82impl Transaction for Transfer {
83 fn tag(&self) -> TransactionTag {
84 TransactionTag::Transfer
85 }
86}
87
88#[derive(Default)]
89pub struct Contract {
90 pub payload: Vec<u8>,
91 pub code: Vec<u8>,
92}
93
94impl Writeable for Contract {
95 fn write_to(&self, buffer: &mut Vec<u8>) {
96 0u64.write_to(buffer); 0u64.write_to(buffer); self.payload.write_to(buffer);
99 buffer.append(&mut self.code.clone());
100 }
101}
102
103impl Readable for Contract {
104 fn read_from(buffer: &[u8], pos: &mut u64) -> Contract {
105 let mut params = Contract::default();
106
107 u64::read_from(buffer, pos); u64::read_from(buffer, pos); params.payload = Vec::<u8>::read_from(buffer, pos);
110 params.code = buffer[*pos as usize..].to_vec();
111
112 *pos = buffer.len() as u64;
113
114 params
115 }
116}