rust_chain/
action.rs

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/// A structure representing a permission level for an action in a smart contract system.
32#[cfg_attr(feature = "std", derive(eosio_scale_info::TypeInfo))]
33#[derive(Copy, Clone, Debug, Eq, PartialEq, Default)]
34pub struct PermissionLevel {
35    /// The account holding the permission.
36    pub actor: Name,
37    /// The permission type.
38    pub permission: Name,
39}
40
41impl PermissionLevel {
42    /// Creates a new permission level with the specified actor and permission.
43    pub fn new(actor: Name, permission: Name) -> Self {
44        Self { actor, permission }
45    }
46}
47
48/// Implements the Packer trait for PermissionLevel to enable serialization and deserialization.
49impl Packer for PermissionLevel {
50    /// Returns the packed size of the PermissionLevel structure.
51    fn size(&self) -> usize {
52        return 16;
53    }
54
55    /// Packs the PermissionLevel structure into the provided Encoder.
56    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    /// Unpacks the PermissionLevel structure from the provided data slice.
64    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/// A structure representing an action to be executed in a smart contract system.
74#[cfg_attr(feature = "std", derive(eosio_scale_info::TypeInfo))]
75#[derive(Clone, Eq, PartialEq)]
76pub struct Action {
77    /// The account on which the action is executed.
78    pub account: Name,
79    /// The name of the action.
80    pub name: Name,
81    /// A list of permission levels required to execute the action.
82    pub authorization: Vec<PermissionLevel>,
83    /// The action's payload data.
84    pub data: Vec<u8>,
85}
86
87impl Action {
88    /// Creates an action by specifying contract account, action name, authorization and data.
89    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    /// Send inline action to contract.
112    pub fn send(&self) {
113        let raw = Encoder::pack(self);
114        send_inline(&raw);
115    }
116}
117
118/// Implements the Default trait for Action.
119impl 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
125/// Implements the Packer trait for Action to enable serialization and deserialization.
126impl Packer for Action {
127    /// Returns the packed size of the Action structure.
128    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    /// Packs the Action structure into the provided Encoder.
137    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    /// Unpacks the Action structure from the provided data slice.
149    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    /// Packs the Action structure into the provided Encoder.
176    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    /// Unpacks the Action structure from the provided data slice.
189    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}