1use crate::{
2 vec,
3 vec::Vec,
4};
5
6use crate::vmapi::eosio::{
7 send_inline,
8 check,
9};
10
11use crate::vmapi::eosio_ex;
12
13use crate::varint::{
14 VarUint32,
15};
16
17use crate::name::{
18 Name,
19};
20
21use crate::serializer::{
22 Packer,
23 Encoder,
24 Decoder,
25};
26
27use crate::structs::{
28 Checksum256,
29};
30
31#[cfg_attr(feature = "std", derive(eosio_scale_info::TypeInfo))]
33#[derive(Copy, Clone, Debug, Eq, PartialEq, Default)]
34pub struct PermissionLevel {
35 pub actor: Name,
37 pub permission: Name,
39}
40
41impl PermissionLevel {
42 pub fn new(actor: Name, permission: Name) -> Self {
44 Self { actor, permission }
45 }
46}
47
48impl Packer for PermissionLevel {
50 fn size(&self) -> usize {
52 return 16;
53 }
54
55 fn pack(&self, enc: &mut Encoder) -> usize {
57 let pos = enc.get_size();
58 self.actor.pack(enc);
59 self.permission.pack(enc);
60 enc.get_size() - pos
61 }
62
63 fn unpack(&mut self, data: &[u8]) -> usize {
65 check(data.len() >= self.size(), "PermissionLevel.unpack: buffer overflow");
66 let mut dec = Decoder::new(data);
67 dec.unpack(&mut self.actor);
68 dec.unpack(&mut self.permission);
69 return 16;
70 }
71}
72
73#[cfg_attr(feature = "std", derive(eosio_scale_info::TypeInfo))]
75#[derive(Clone, Eq, PartialEq)]
76pub struct Action {
77 pub account: Name,
79 pub name: Name,
81 pub authorization: Vec<PermissionLevel>,
83 pub data: Vec<u8>,
85}
86
87impl Action {
88 pub fn new(account: Name, name: Name, authorization: PermissionLevel, data: &dyn Packer) -> Self {
90 let mut enc = Encoder::new(data.size());
91 data.pack(&mut enc);
92 Self {
93 account,
94 name,
95 authorization: vec![authorization],
96 data: enc.get_bytes().to_vec()
97 }
98 }
99
100 pub fn new_ex(account: Name, name: Name, authorizations: Vec<PermissionLevel>, data: &dyn Packer) -> Self {
101 let mut enc = Encoder::new(data.size());
102 data.pack(&mut enc);
103 Self {
104 account,
105 name,
106 authorization: authorizations,
107 data: enc.get_bytes().to_vec()
108 }
109 }
110
111 pub fn send(&self) {
113 let raw = Encoder::pack(self);
114 send_inline(&raw);
115 }
116}
117
118impl Default for Action {
120 fn default() -> Self {
121 Self { account: Name{n: 0}, name: Name{n: 0}, authorization: Vec::new(), data: Vec::new() }
122 }
123}
124
125impl Packer for Action {
127 fn size(&self) -> usize {
129 let mut size: usize;
130 size = 16;
131 size += VarUint32::new(self.authorization.len() as u32).size()+ self.authorization.len() * 16;
132 size += VarUint32::new(self.data.len() as u32).size() + self.data.len();
133 return size
134 }
135
136 fn pack(&self, enc: &mut Encoder) -> usize {
138 let pos = enc.get_size();
139
140 self.account.pack(enc);
141 self.name.pack(enc);
142 self.authorization.pack(enc);
143 self.data.pack(enc);
144
145 enc.get_size() - pos
146 }
147
148 fn unpack(&mut self, data: &[u8]) -> usize {
150 check(data.len() >= self.size(), "Action.unpack: buffer overflow");
151
152 let mut dec = Decoder::new(data);
153 dec.unpack(&mut self.account);
154 dec.unpack(&mut self.name);
155 dec.unpack(&mut self.authorization);
156 dec.unpack(&mut self.data);
157 dec.get_pos()
158 }
159}
160
161#[derive(Default)]
162pub struct GetCodeHashResult {
163 struct_version: VarUint32,
164 code_sequence: u64,
165 code_hash: Checksum256,
166 vm_type: u8,
167 vm_version: u8,
168}
169
170impl Packer for GetCodeHashResult {
171 fn size(&self) -> usize {
172 self.struct_version.size() + 8 + 32 + 1 + 1
173 }
174
175 fn pack(&self, enc: &mut Encoder) -> usize {
177 let pos = enc.get_size();
178
179 self.struct_version.pack(enc);
180 self.code_sequence.pack(enc);
181 self.code_hash.pack(enc);
182 self.vm_type.pack(enc);
183 self.vm_version.pack(enc);
184
185 enc.get_size() - pos
186 }
187
188 fn unpack(&mut self, data: &[u8]) -> usize {
190 check(data.len() >= self.size(), "Action.unpack: buffer overflow");
191
192 let mut dec = Decoder::new(data);
193 dec.unpack(&mut self.struct_version);
194 dec.unpack(&mut self.code_sequence);
195 dec.unpack(&mut self.code_hash);
196 dec.unpack(&mut self.vm_type);
197 dec.unpack(&mut self.vm_version);
198 dec.get_pos()
199 }
200}
201
202pub fn get_code_hash(account: Name) -> Checksum256 {
203 let data = eosio_ex::get_code_hash(account, 0u32);
204 let mut dec = Decoder::new(&data);
205 let mut result = GetCodeHashResult::default();
206 dec.unpack(&mut result);
207 return result.code_hash;
208}