Skip to content

Commit 8a4685e

Browse files
committed
import ext_call to trait and add function to generate input_data of ext_call
remove #[allow(unused)] from ext_call() implment call_invoke and call_evaluate fix format
1 parent 9525f2f commit 8a4685e

File tree

6 files changed

+214
-4
lines changed

6 files changed

+214
-4
lines changed

core/src/env/srml/srml_only/impls.rs

Lines changed: 52 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,10 @@ use crate::{
2525
storage::Key,
2626
};
2727
use core::marker::PhantomData;
28-
use scale::Decode;
28+
use scale::{
29+
Decode,
30+
Encode,
31+
};
2932

3033
/// Load the contents of the scratch buffer
3134
fn read_scratch_buffer() -> Vec<u8> {
@@ -107,6 +110,7 @@ impl<T> Env for SrmlEnv<T>
107110
where
108111
T: EnvTypes,
109112
{
113+
110114
fn input() -> Vec<u8> {
111115
read_scratch_buffer()
112116
}
@@ -153,4 +157,51 @@ where
153157
fn dispatch_raw_call(data: &[u8]) {
154158
unsafe { sys::ext_dispatch_call(data.as_ptr() as u32, data.len() as u32) }
155159
}
160+
161+
fn call_invoke(
162+
callee: <Self as EnvTypes>::AccountId,
163+
gas: u64,
164+
value: <Self as EnvTypes>::Balance,
165+
input_data: &[u8],
166+
) {
167+
let callee = callee.encode();
168+
let value = value.encode();
169+
unsafe {
170+
sys::ext_call(
171+
callee.as_ptr() as u32,
172+
callee.len() as u32,
173+
gas,
174+
value.as_ptr() as u32,
175+
value.len() as u32,
176+
input_data.as_ptr() as u32,
177+
input_data.len() as u32
178+
);
179+
}
180+
}
181+
182+
fn call_evaluate<U: Decode>(
183+
callee: <Self as EnvTypes>::AccountId,
184+
gas: u64,
185+
value: <Self as EnvTypes>::Balance,
186+
input_data: &[u8],
187+
) -> Option<U> {
188+
let callee = callee.encode();
189+
let value = value.encode();
190+
unsafe {
191+
let success = sys::ext_call(
192+
callee.as_ptr() as u32,
193+
callee.len() as u32,
194+
gas,
195+
value.as_ptr() as u32,
196+
value.len() as u32,
197+
input_data.as_ptr() as u32,
198+
input_data.len() as u32
199+
);
200+
if success == 0 {
201+
Some(U::decode(&mut &read_scratch_buffer()[..]).unwrap())
202+
} else {
203+
None
204+
}
205+
}
206+
}
156207
}

core/src/env/srml/srml_only/sys.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,6 @@ extern "C" {
3232
) -> u32;
3333

3434
/// Calls a remote smart contract.
35-
#[allow(unused)]
3635
pub fn ext_call(
3736
callee_ptr: u32,
3837
callee_len: u32,

core/src/env/test_env.rs

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -414,8 +414,20 @@ impl TestEnvData {
414414
self.add_event(topics, data);
415415
}
416416

417+
<<<<<<< HEAD
417418
pub fn dispatch_call(&mut self, call: &[u8]) {
418419
self.add_dispatched_call(call);
420+
=======
421+
#[allow(unused_variables)]
422+
pub fn call<T: Decode>(
423+
&mut self,
424+
callee: &[u8],
425+
gas: u64,
426+
value: &[u8],
427+
input_data: &[u8],
428+
) -> Option<T> {
429+
unimplemented!();
430+
>>>>>>> import ext_call to trait and add function to generate input_data of ext_call
419431
}
420432
}
421433

@@ -564,8 +576,33 @@ where
564576
})
565577
}
566578

579+
<<<<<<< HEAD
567580
fn dispatch_raw_call(data: &[u8]) {
568581
TEST_ENV_DATA.with(|test_env| test_env.borrow_mut().dispatch_call(data))
582+
=======
583+
fn call_invoke(
584+
callee: T::AccountId,
585+
gas: u64,
586+
value: T::Balance,
587+
input_data: &[u8],
588+
) {
589+
let callee = &(callee.encode())[..];
590+
let value = &(value.encode())[..];
591+
TEST_ENV_DATA
592+
.with(|test_env| test_env.borrow_mut().call(callee, gas, value, input_data));
593+
}
594+
595+
fn call_evaluate<U : Decode>(
596+
callee: T::AccountId,
597+
gas: u64,
598+
value: T::Balance,
599+
input_data: &[u8],
600+
) -> Option<U> {
601+
let callee = &(callee.encode())[..];
602+
let value = &(value.encode())[..];
603+
TEST_ENV_DATA
604+
.with(|test_env| test_env.borrow_mut().call(callee, gas, value, input_data))
605+
>>>>>>> import ext_call to trait and add function to generate input_data of ext_call
569606
}
570607
}
571608

core/src/env/traits.rs

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,10 @@ use crate::{
1818
memory::vec::Vec,
1919
storage::Key,
2020
};
21-
use scale::Codec;
21+
use scale::{
22+
Codec,
23+
Decode,
24+
};
2225

2326
#[cfg(not(feature = "test-env"))]
2427
/// The environmental types usable by contracts defined with ink!.
@@ -136,4 +139,21 @@ pub trait Env: EnvTypes {
136139

137140
/// Dispatches a call into the Runtime.
138141
fn dispatch_raw_call(data: &[u8]);
142+
143+
/// Calls a remote smart contract and return access to scratch buffer without return data
144+
fn call_invoke(
145+
callee: <Self as EnvTypes>::AccountId,
146+
gas: u64,
147+
value: <Self as EnvTypes>::Balance,
148+
input_data: &[u8]
149+
);
150+
151+
/// Calls a remote smart contract and return access to scratch buffer with return data
152+
#[must_use]
153+
fn call_evaluate<T: Decode>(
154+
callee: <Self as EnvTypes>::AccountId,
155+
gas: u64,
156+
value: <Self as EnvTypes>::Balance,
157+
input_data: &[u8],
158+
) -> Option<T>;
139159
}

lang/src/encode_input_data.rs

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
use ink_core::memory::vec::Vec;
2+
use ink_utils;
3+
use parity_codec::Encode;
4+
5+
pub trait EncodeSafe{
6+
fn encode_safe(&self) -> Vec<u8>;
7+
}
8+
9+
macro_rules! impl_encode_safe {
10+
($( $one:ty ),*) => { $(
11+
impl EncodeSafe for $one {
12+
fn encode_safe(&self) -> Vec<u8> {
13+
parity_codec::Encode::encode(&self)
14+
}
15+
}
16+
)* }
17+
}
18+
19+
impl_encode_safe!(bool,u16,u32,u64,u128,i8,i16,i32,i64,i128,Vec<u8>);
20+
21+
/// make selector from method name
22+
#[allow(unused)]
23+
fn raw_message_selector(name: &str) -> u32 {
24+
let keccak = ink_utils::hash::keccak256(name.as_bytes());
25+
u32::from_le_bytes([keccak[0], keccak[1], keccak[2], keccak[3]])
26+
}
27+
28+
/// encode to input_data from Box wrapped params
29+
#[allow(unused)]
30+
pub fn gen_input_data(method: &str, params: &[Box<EncodeSafe>]) -> Vec<u8>
31+
where
32+
{
33+
let selector = raw_message_selector(method);
34+
let mut input_data = selector.encode();
35+
for param in params.iter() {
36+
let mut encoded_param = param.encode_safe();
37+
input_data.append(&mut encoded_param);
38+
}
39+
return input_data.encode()
40+
}
41+
42+
#[cfg(test)]
43+
mod tests {
44+
use super::*;
45+
46+
#[test]
47+
fn message_selectors() {
48+
assert_eq!(raw_message_selector("inc"), 257544423);
49+
assert_eq!(raw_message_selector("get"), 4266279973);
50+
assert_eq!(raw_message_selector("compare"), 363906316);
51+
}
52+
53+
#[test]
54+
fn encode(){
55+
let var:bool = false;
56+
assert_eq!(var.encode(), vec![0]);
57+
58+
let var:bool = true;
59+
assert_eq!(var.encode(), vec![1]);
60+
61+
let var :u32 = 22;
62+
assert_eq!(var.encode(), vec![22,0,0,0]);
63+
64+
let var :u32 = 257544423;
65+
assert_eq!(var.encode(), vec![231, 208, 89, 15]);
66+
67+
let mut vec1 : Vec<u8> = Vec::new(); vec1.push(11);
68+
assert_eq!(vec1.encode(), vec![4,11]);
69+
}
70+
71+
#[test]
72+
fn input_data_works(){
73+
let mut params : Vec<Box<EncodeSafe>> = Vec::new();
74+
params.push(Box::new(true));
75+
params.push(Box::new(12u64));
76+
assert_eq!(gen_input_data("inc",&params),vec![52, 231, 208, 89, 15, 1, 12, 0, 0, 0, 0, 0, 0, 0]);
77+
}
78+
}

model/src/exec_env.rs

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,10 @@ use ink_core::{
2828
Initialize,
2929
},
3030
};
31-
use scale::Encode as _;
31+
use scale::{
32+
Encode as _,
33+
Decode,
34+
};
3235

3336
/// Provides a safe interface to an environment given a contract state.
3437
pub struct ExecutionEnv<State, Env> {
@@ -190,4 +193,26 @@ impl<T: Env> EnvHandler<T> {
190193
{
191194
T::dispatch_raw_call(call.into().encode().as_slice())
192195
}
196+
197+
/// Calls a remote smart contract
198+
pub fn call_invoke(
199+
&self,
200+
callee: T::AccountId,
201+
gas: u64,
202+
value: T::Balance,
203+
input_data: &[u8],
204+
) {
205+
T::call_invoke(callee, gas, value, input_data);
206+
}
207+
208+
/// Calls a remote smart contract and return access to scratch buffer
209+
pub fn call_evaluate<U:Decode>(
210+
&self,
211+
callee: T::AccountId,
212+
gas: u64,
213+
value: T::Balance,
214+
input_data: &[u8],
215+
) -> Option<U> {
216+
T::call_evaluate(callee, gas, value, input_data)
217+
}
193218
}

0 commit comments

Comments
 (0)