1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
#![no_std]
#![feature(slice_concat_ext)]
#![deny(unused_extern_crates)]
#![allow(unused_attributes)]
#[macro_use]
extern crate serde_json;
extern crate serde;
#[macro_use]
mod internal_std;
mod rand_wasm;
pub extern crate eng_pwasm_abi;
pub use internal_std::*;
pub use rand_wasm::*;
pub use serde_json::Value;
pub use eng_pwasm_abi::types::*;
pub mod external {
extern "C" {
pub fn write_state (key: *const u8, key_len: u32, value: *const u8, value_len: u32);
pub fn read_state_len (key: *const u8, key_len: u32) -> i32;
pub fn read_state (key: *const u8, key_len: u32, value_holder: *const u8);
pub fn remove_from_state (key: *const u8, key_len: u32);
pub fn eprint(str_ptr: *const u8, str_len: u32);
pub fn fetch_function_name_length() -> i32;
pub fn fetch_function_name(name_holder: *const u8);
pub fn fetch_args_length() -> i32;
pub fn fetch_args(name_holder: *const u8);
pub fn fetch_types_length() -> i32;
pub fn fetch_types(name_holder: *const u8);
pub fn write_eth_bridge(payload: *const u8, payload_len: u32, address: *const u8);
pub fn gas(amount: u32);
pub fn ret(payload: *const u8, payload_len: u32);
pub fn rand(payload: *const u8, payload_len: u32);
}
}
#[no_mangle]
pub fn print(msg: &str) -> i32 {
unsafe { external::eprint(msg.as_ptr(), msg.len() as u32); }
0
}
#[macro_export]
macro_rules! eprint {
( $($arg: tt)* ) => (
$crate::print( &eformat!( $($arg)* ) )
);
}
pub fn write<T>(key: &str, _value: T) where T: serde::Serialize {
let value = json!(_value);
let value_vec = serde_json::to_vec(&value).unwrap();
unsafe { external::write_state(key.as_ptr(), key.len() as u32, value_vec.as_ptr(), value_vec.len() as u32) }
}
pub fn read<T>(key: &str) -> Option<T> where for<'de> T: serde::Deserialize<'de> {
let val_len = unsafe { external::read_state_len(key.as_ptr(), key.len() as u32) };
let value_holder: Vec<u8> = iter::repeat(0).take(val_len as usize).collect();
unsafe { external::read_state(key.as_ptr(), key.len() as u32, value_holder.as_ptr()) };
let value: Value = serde_json::from_slice(&value_holder).map_err(|_| print("failed unwrapping from_slice in read_state")).expect("read_state failed");
if value.is_null() {
return None;
}
Some(serde_json::from_value(value.clone()).map_err(|_| print("failed unwrapping from_value in read_state")).expect("read_state failed"))
}
pub fn remove<T>(key: &str) -> Option<T> where for<'de> T: serde::Deserialize<'de> {
let value = read(key);
unsafe { external::remove_from_state(key.as_ptr(), key.len() as u32) }
value
}
pub fn write_ethereum_bridge(payload: &[u8], address: &Address){
unsafe {
external::write_eth_bridge(payload.as_ptr(), payload.len() as u32, address.as_ptr())
};
}
#[macro_export]
macro_rules! write_state {
( $($key: expr => $val: expr),+ ) => {
{
$(
$crate::write($key, $val);
)+
}
}
}
#[macro_export]
macro_rules! read_state {
( $key: expr ) => {
{
$crate::read($key)
}
}
}
#[macro_export]
macro_rules! remove_from_state {
( $key: expr ) => {
{
$crate::remove($key)
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn what() {
print("TEST!");
}
}