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}