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
128
129
130
#![feature(
bind_by_move_pattern_guards,
linkage,
non_exhaustive,
proc_macro_hygiene,
specialization,
trait_alias,
drain_filter,
shrink_to,
try_reserve,
)]
#![cfg_attr(target_os = "wasi", feature(wasi_ext))]
extern crate oasis_macros;
pub mod backend;
pub mod collections;
pub mod exe;
pub mod abi {
pub extern crate oasis_borsh;
pub use oasis_borsh::{BorshDeserialize as Deserialize, BorshSerialize as Serialize};
#[macro_export]
macro_rules! abi_encode {
($( $arg:expr ),* $(,)?) => {
$crate::abi_encode!($($arg),* => Vec::new())
};
($( $arg:expr ),* $(,)? => $buf:expr) => {
Ok($buf)
$(
.and_then(|mut buf| {
#[allow(unused)] {
use $crate::abi::Serialize as _;
$arg.serialize(&mut buf)?;
}
Ok(buf)
})
)*
.map_err(|_: std::io::Error| $crate::RpcError::InvalidInput)
};
}
}
#[cfg(not(target_os = "wasi"))]
#[doc(hidden)]
pub mod reexports {
pub extern crate oasis_client;
pub extern crate oasis_test;
}
pub use oasis_macros::{default, Event, Service};
pub use oasis_types::{Address, Balance, RpcError};
pub use crate::exe::*;
#[macro_export]
macro_rules! service {
($svc:path) => {};
}
pub trait AddressExt {
fn call(&self, ctx: &Context, payload: &[u8]) -> Result<Vec<u8>, RpcError>;
fn transfer<B: Into<Balance>>(&self, value: B) -> Result<(), RpcError>;
fn balance(&self) -> Balance;
fn code(&self) -> Vec<u8>;
}
impl AddressExt for Address {
fn call(&self, ctx: &Context, payload: &[u8]) -> Result<Vec<u8>, RpcError> {
crate::backend::transact(self, ctx.value(), payload)
}
fn transfer<B: Into<Balance>>(&self, value: B) -> Result<(), RpcError> {
crate::backend::transact(self, value.into(), &[]).map(|_| ())
}
fn balance(&self) -> Balance {
crate::backend::balance(self).unwrap()
}
fn code(&self) -> Vec<u8> {
crate::backend::code(self).unwrap()
}
}
#[cfg(test)]
mod tests {
use super::*;
use abi::*;
extern crate oasis_test;
#[test]
fn test_invoke() {
type T = (Address, String, Vec<u8>);
let things = (Address::default(), "an arg", (1..100).collect::<Vec<_>>());
let encoded = abi_encode!(&things).unwrap();
let decoded = T::try_from_slice(&encoded).unwrap();
assert_eq!(decoded.0, things.0);
assert_eq!(decoded.1, things.1);
assert_eq!(decoded.2, things.2);
}
}