ink_env/engine/off_chain/call_data.rs
1// Copyright (C) Use Ink (UK) Ltd.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15use crate::call::Selector;
16use ink_prelude::{
17 vec,
18 vec::Vec,
19};
20
21/// The raw ABI respecting input data to a call.
22///
23/// # Note
24///
25/// The first four bytes are the function selector and the rest are SCALE encoded inputs.
26#[derive(Debug, Clone, PartialEq, Eq)]
27pub struct CallData {
28 /// Already encoded function selector and inputs.
29 ///
30 /// # Note
31 ///
32 /// Has the invariant of always holding at least 4 bytes (the selector).
33 bytes: Vec<u8>,
34}
35
36impl CallData {
37 /// Creates new call ABI data for the given selector.
38 pub fn new(selector: Selector) -> Self {
39 let bytes = selector.to_bytes();
40 Self {
41 bytes: vec![bytes[0], bytes[1], bytes[2], bytes[3]],
42 }
43 }
44
45 /// Pushes the given argument onto the call ABI data in encoded form.
46 pub fn push_arg<A>(&mut self, arg: &A)
47 where
48 A: scale::Encode,
49 {
50 arg.encode_to(&mut self.bytes)
51 }
52
53 /// Returns the selector of `self`.
54 pub fn selector(&self) -> Selector {
55 debug_assert!(self.bytes.len() >= 4);
56 let bytes = [self.bytes[0], self.bytes[1], self.bytes[2], self.bytes[3]];
57 bytes.into()
58 }
59
60 /// Returns the underlying bytes of the encoded input parameters.
61 pub fn params(&self) -> &[u8] {
62 debug_assert!(self.bytes.len() >= 4);
63 &self.bytes[4..]
64 }
65
66 /// Returns the underlying byte representation.
67 pub fn to_bytes(&self) -> &[u8] {
68 &self.bytes
69 }
70}
71
72impl scale::Encode for CallData {
73 fn size_hint(&self) -> usize {
74 self.bytes.len()
75 }
76
77 fn encode_to<T: scale::Output + ?Sized>(&self, dest: &mut T) {
78 dest.write(self.bytes.as_slice());
79 }
80}
81
82impl scale::Decode for CallData {
83 fn decode<I: scale::Input>(
84 input: &mut I,
85 ) -> core::result::Result<Self, scale::Error> {
86 let remaining_len = input.remaining_len().unwrap_or(None).unwrap_or(0);
87 let mut bytes = Vec::with_capacity(remaining_len);
88 while let Ok(byte) = input.read_byte() {
89 bytes.push(byte);
90 }
91 if bytes.len() < 4 {
92 return Err(scale::Error::from(
93 "require at least 4 bytes for input data",
94 ))
95 }
96 Ok(Self { bytes })
97 }
98}