1use crate::prelude::*;
2use crate::types::LogLevel;
3
4pub(crate) mod env {
5 extern "C" {
6 pub(crate) fn fvm_storage_read(key_ptr: *const u8, key_len: u32, prefix_ptr: *const u8, prefix_len: u32,
7 val: *mut u8, vlen: u32, offset: u32) -> u32;
8 pub(crate) fn fvm_call_contract(addr: *const u8, input_ptr: *const u8, input_len: u32) -> u32;
9 pub(crate) fn fvm_cns_call_contract(cns: *const u8, cns_len: u32, input_ptr: *const u8, input_len: u32) -> u32;
10 pub(crate) fn fvm_storage_write(key_ptr: *const u8, key_len: u32, prefix_ptr: *const u8, prefix_len: u32, val: *const u8, vlen: u32);
11 pub(crate) fn fvm_storage_delete(key_ptr: *const u8, key_len: u32, prefix_ptr: *const u8, prefix_len: u32);
12 pub(crate) fn fvm_block_height() -> u64;
13 pub(crate) fn fvm_input_length() -> u32;
14 pub(crate) fn fvm_block_time() -> u64;
15 pub(crate) fn fvm_fetch_input(dst: *mut u8);
16 pub(crate) fn fvm_tx_hash(tx_hash: *const u8);
17 pub(crate) fn fvm_self_address(dest: *mut u8);
18 pub(crate) fn fvm_caller_address(dest: *mut u8);
19 pub(crate) fn fvm_origin_address(dest: *mut u8);
20 pub(crate) fn fvm_return(ptr: *const u8, len: u32);
21 pub(crate) fn fvm_revert(ptr: *const u8, len: u32) -> !;
22 pub(crate) fn fvm_log(ptr: *const u8, len: u32);
23 pub(crate) fn fvm_debug(class_prt: *const u8, class_len: u32, ptr: *const u8, len: u32, level: u32);
24 pub(crate) fn fvm_call_return(dst: *mut u8);
25 pub(crate) fn fvm_sha256(data_ptr: *const u8, len: u32, val: *mut u8);
26 pub(crate) fn fvm_add_list_key(list_name_ptr: *const u8, list_name_len: u32, index: u32) -> i64;
27 pub(crate) fn fvm_get_list_key(list_name_ptr: *const u8, list_name_len: u32, index: u32) -> i64;
28 pub(crate) fn fvm_remove_list_key(list_name_ptr: *const u8, list_name_len: u32, index: u32) -> i64;
29 pub(crate) fn fvm_write_list_keys(old_list_name_ptr: *const u8, old_list_name_len: u32, new_list_name_ptr: *const u8, new_list_name_len: u32, size: u32);
30 }
31}
32
33pub(crate) fn call_contract(addr: &Address, input: &[u8]) -> Vec<u8> {
34 let addr: &[u8] = addr.as_ref();
35 let size =
36 unsafe { env::fvm_call_contract(addr.as_ptr(), input.as_ptr(), input.len() as u32) };
37 let mut output = vec![0u8; size as usize];
38 if size != 0 {
39 let value = &mut output[..];
40 unsafe {
41 env::fvm_call_return(value.as_mut_ptr());
42 }
43 }
44
45 output
46}
47
48pub(crate) fn cns_call_contract(cns: &[u8], input: &[u8]) -> Vec<u8> {
49 let size =
50 unsafe { env::fvm_cns_call_contract(cns.as_ptr(), cns.len() as u32, input.as_ptr(), input.len() as u32) };
51 let mut output = vec![0u8; size as usize];
52 if size != 0 {
53 let value = &mut output[..];
54 unsafe {
55 env::fvm_call_return(value.as_mut_ptr());
56 }
57 }
58
59 output
60}
61
62
63pub(crate) fn storage_write(key: &[u8], prefix: &[u8], val: &[u8]) {
64 unsafe {
65 env::fvm_storage_write(key.as_ptr(), key.len() as u32,
66 prefix.as_ptr(), prefix.len() as u32,
67 val.as_ptr(), val.len() as u32);
68 }
69}
70
71pub(crate) fn storage_read(key: &[u8], prefix: &[u8]) -> Option<Vec<u8>> {
72 const INITIAL: usize = 32;
73 let mut val = vec![0; INITIAL];
74 let size = unsafe {
75 env::fvm_storage_read(
76 key.as_ptr(), key.len() as u32,
77 prefix.as_ptr(), prefix.len() as u32,
78 val.as_mut_ptr(),
79 val.len() as u32,
80 0,
81 )
82 };
83
84 if size == 0 {
86 return None;
87 }
88 let size = size as usize;
89 val.resize(size, 0);
90 if size > INITIAL {
91 let value = &mut val[INITIAL..];
92 debug_assert!(value.len() == size - INITIAL);
93 unsafe {
94 env::fvm_storage_read(
95 key.as_ptr(), key.len() as u32,
96 prefix.as_ptr(), prefix.len() as u32,
97 value.as_mut_ptr(),
98 value.len() as u32,
99 INITIAL as u32,
100 )
101 };
102 }
103
104 Some(val)
105}
106
107pub(crate) fn storage_delete(key: &[u8], prefix: &[u8]) {
108 unsafe {
109 env::fvm_storage_delete(key.as_ptr(), key.len() as u32,
110 prefix.as_ptr(), prefix.len() as u32);
111 }
112}
113
114pub(crate) fn block_time() -> u64 {
115 unsafe { env::fvm_block_time() }
116}
117
118pub(crate) fn block_height() -> u64 {
119 unsafe { env::fvm_block_height() }
120}
121
122pub(crate) fn self_address() -> Address {
123 let mut addr: Address = Address::zero();
124 unsafe {
125 env::fvm_self_address(addr.as_mut().as_mut_ptr());
126 }
127
128 addr
129}
130
131pub(crate) fn caller_address() -> Address {
132 let mut addr: Address = Address::zero();
133 unsafe {
134 env::fvm_caller_address(addr.as_mut().as_mut_ptr());
135 }
136 addr
137}
138
139pub(crate) fn origin_address() -> Address {
140 let mut addr: Address = Address::zero();
141 unsafe {
142 env::fvm_origin_address(addr.as_mut().as_mut_ptr());
143 }
144 addr
145}
146
147pub(crate) fn tx_hash() -> H256 {
148 let tx_hash = H256::zero();
149 unsafe {
150 env::fvm_tx_hash(tx_hash.as_ptr());
151 }
152 tx_hash
153}
154
155pub(crate) fn sha256(data: impl AsRef<[u8]>) -> H256 {
156 let data = data.as_ref();
157 let mut hash = H256::zero();
158 unsafe {
159 env::fvm_sha256(data.as_ptr(), data.len() as u32, hash.as_mut_ptr());
160 }
161 hash
162}
163
164
165pub(crate) fn input() -> Vec<u8> {
166 let len = unsafe { env::fvm_input_length() };
167
168 if len == 0 {
169 Vec::new()
170 } else {
171 let mut data = vec![0; len as usize];
172 unsafe {
173 env::fvm_fetch_input(data.as_mut_ptr());
174 }
175 data
176 }
177}
178
179pub(crate) fn ret(data: &[u8]) {
180 unsafe {
181 env::fvm_return(data.as_ptr(), data.len() as u32);
182 }
183}
184
185pub(crate) fn event(data: &[u8]) {
186 unsafe {
187 env::fvm_log(data.as_ptr(), data.len() as u32);
188 }
189}
190
191pub(crate) fn log(class_name: &[u8], data: &[u8], level: LogLevel) {
192 let level_type: u32 = match level {
193 LogLevel::CRITICAL => 0,
194 LogLevel::ERROR => 1,
195 LogLevel::WARNING => 2,
196 LogLevel::NOTICE => 3,
197 LogLevel::INFO => 4,
198 LogLevel::DEBUG => 5,
199 };
200 unsafe {
201 env::fvm_debug(class_name.as_ptr(), class_name.len() as u32, data.as_ptr(), data.len() as u32, level_type);
202 }
203}
204
205pub(crate) fn revert(msg: &str) -> ! {
206 unsafe {
207 env::fvm_revert(msg.as_ptr(), msg.len() as u32);
208 }
209}
210
211pub(crate) fn add_list_key(list_name: &[u8], index: u32) -> Option<i64> {
212 let key =
213 unsafe { env::fvm_add_list_key(list_name.as_ptr(), list_name.len() as u32, index) };
214 if key < 0 {
215 None
216 } else {
217 Some(key)
218 }
219}
220
221pub(crate) fn get_list_key(list_name: &[u8], index: u32) -> Option<i64> {
222 let key =
223 unsafe { env::fvm_get_list_key(list_name.as_ptr(), list_name.len() as u32, index) };
224 if key < 0 {
225 None
226 } else {
227 Some(key)
228 }
229}
230
231pub(crate) fn remove_list_key(list_name: &[u8], index: u32) -> Option<i64> {
232 let key =
233 unsafe { env::fvm_remove_list_key(list_name.as_ptr(), list_name.len() as u32, index) };
234 if key < 0 {
235 None
236 } else {
237 Some(key)
238 }
239}
240
241pub(crate) fn write_list_keys_back(old_list_name: &[u8], list_name: &[u8], size: u32) {
242 unsafe { env::fvm_write_list_keys(old_list_name.as_ptr(), old_list_name.len() as u32, list_name.as_ptr(), list_name.len() as u32, size) };
243}