1use crate::result::{Error, Result};
4
5pub trait AbiEncode {
7 fn abi_encode(&self) -> Vec<u8>;
9}
10
11pub trait AbiDecode: Sized {
13 fn abi_decode(data: &[u8]) -> std::result::Result<Self, DecodeError>;
15}
16
17#[derive(Debug)]
19pub enum DecodeError {
20 InvalidData,
21 UnsupportedType,
22}
23
24impl From<DecodeError> for Error {
25 fn from(_e: DecodeError) -> Self {
26 Error::Postcard(postcard::Error::SerializeBufferFull)
27 }
28}
29
30impl AbiEncode for bool {
31 fn abi_encode(&self) -> Vec<u8> {
32 let mut result = vec![0u8; 32];
33 if *self {
34 result[31] = 1;
35 }
36 result
37 }
38}
39
40impl AbiDecode for bool {
41 fn abi_decode(data: &[u8]) -> std::result::Result<Self, DecodeError> {
42 if data.len() < 32 {
43 return Err(DecodeError::InvalidData);
44 }
45 Ok(data[31] != 0)
46 }
47}
48
49impl AbiEncode for u8 {
50 fn abi_encode(&self) -> Vec<u8> {
51 let mut result = vec![0u8; 32];
52 result[31] = *self;
53 result
54 }
55}
56
57impl AbiDecode for u8 {
58 fn abi_decode(data: &[u8]) -> std::result::Result<Self, DecodeError> {
59 if data.len() < 32 {
60 return Err(DecodeError::InvalidData);
61 }
62 Ok(data[31])
63 }
64}
65
66impl AbiEncode for u16 {
67 fn abi_encode(&self) -> Vec<u8> {
68 let mut result = vec![0u8; 32];
69 result[30..32].copy_from_slice(&self.to_be_bytes());
70 result
71 }
72}
73
74impl AbiDecode for u16 {
75 fn abi_decode(data: &[u8]) -> std::result::Result<Self, DecodeError> {
76 if data.len() < 32 {
77 return Err(DecodeError::InvalidData);
78 }
79 let mut bytes = [0u8; 2];
80 bytes.copy_from_slice(&data[30..32]);
81 Ok(u16::from_be_bytes(bytes))
82 }
83}
84
85impl AbiEncode for u32 {
86 fn abi_encode(&self) -> Vec<u8> {
87 let mut result = vec![0u8; 32];
88 result[28..32].copy_from_slice(&self.to_be_bytes());
89 result
90 }
91}
92
93impl AbiDecode for u32 {
94 fn abi_decode(data: &[u8]) -> std::result::Result<Self, DecodeError> {
95 if data.len() < 32 {
96 return Err(DecodeError::InvalidData);
97 }
98 let mut bytes = [0u8; 4];
99 bytes.copy_from_slice(&data[28..32]);
100 Ok(u32::from_be_bytes(bytes))
101 }
102}
103
104impl AbiEncode for u64 {
105 fn abi_encode(&self) -> Vec<u8> {
106 let mut result = vec![0u8; 32];
107 result[24..32].copy_from_slice(&self.to_be_bytes());
108 result
109 }
110}
111
112impl AbiDecode for u64 {
113 fn abi_decode(data: &[u8]) -> std::result::Result<Self, DecodeError> {
114 if data.len() < 32 {
115 return Err(DecodeError::InvalidData);
116 }
117 let mut bytes = [0u8; 8];
118 bytes.copy_from_slice(&data[24..32]);
119 Ok(u64::from_be_bytes(bytes))
120 }
121}
122
123impl AbiEncode for u128 {
124 fn abi_encode(&self) -> Vec<u8> {
125 let mut result = vec![0u8; 32];
126 result[16..32].copy_from_slice(&self.to_be_bytes());
127 result
128 }
129}
130
131impl AbiDecode for u128 {
132 fn abi_decode(data: &[u8]) -> std::result::Result<Self, DecodeError> {
133 if data.len() < 32 {
134 return Err(DecodeError::InvalidData);
135 }
136 let mut bytes = [0u8; 16];
137 bytes.copy_from_slice(&data[16..32]);
138 Ok(u128::from_be_bytes(bytes))
139 }
140}
141
142#[allow(dead_code)]
146pub fn encode_address(addr: &[u8; 20]) -> Vec<u8> {
147 let mut result = vec![0u8; 32];
148 result[12..32].copy_from_slice(addr);
149 result
150}
151
152#[allow(dead_code)]
154pub fn decode_address(data: &[u8]) -> std::result::Result<[u8; 20], DecodeError> {
155 if data.len() < 32 {
156 return Err(DecodeError::InvalidData);
157 }
158 let mut bytes = [0u8; 20];
159 bytes.copy_from_slice(&data[12..32]);
160 Ok(bytes)
161}
162
163#[allow(dead_code)]
165pub fn encode_u256(value: &[u8; 32]) -> Vec<u8> {
166 value.to_vec()
167}
168
169#[allow(dead_code)]
171pub fn decode_u256(data: &[u8]) -> std::result::Result<[u8; 32], DecodeError> {
172 if data.len() < 32 {
173 return Err(DecodeError::InvalidData);
174 }
175 let mut bytes = [0u8; 32];
176 bytes.copy_from_slice(&data[0..32]);
177 Ok(bytes)
178}
179
180impl AbiEncode for String {
181 fn abi_encode(&self) -> Vec<u8> {
182 let bytes = self.as_bytes();
183 let length = bytes.len();
184
185 let mut result = vec![0u8; 32];
186 result[28..32].copy_from_slice(&(32u32).to_be_bytes()); let mut length_bytes = vec![0u8; 32];
189 length_bytes[28..32].copy_from_slice(&(length as u32).to_be_bytes());
190 result.extend_from_slice(&length_bytes);
191
192 result.extend_from_slice(bytes);
193 let padding_needed = (32 - (bytes.len() % 32)) % 32;
194 result.extend(vec![0u8; padding_needed]);
195
196 result
197 }
198}
199
200impl AbiDecode for String {
201 fn abi_decode(data: &[u8]) -> std::result::Result<Self, DecodeError> {
202 if data.len() < 64 {
203 return Err(DecodeError::InvalidData);
204 }
205
206 let mut offset_bytes = [0u8; 4];
207 offset_bytes.copy_from_slice(&data[28..32]);
208 let offset = u32::from_be_bytes(offset_bytes) as usize;
209
210 if data.len() < offset + 32 {
211 return Err(DecodeError::InvalidData);
212 }
213
214 let mut length_bytes = [0u8; 4];
215 length_bytes.copy_from_slice(&data[offset + 28..offset + 32]);
216 let length = u32::from_be_bytes(length_bytes) as usize;
217
218 if data.len() < offset + 32 + length {
219 return Err(DecodeError::InvalidData);
220 }
221
222 let string_data = &data[offset + 32..offset + 32 + length];
223 String::from_utf8(string_data.to_vec()).map_err(|_| DecodeError::InvalidData)
224 }
225}
226
227impl<T: AbiEncode> AbiEncode for Vec<T> {
228 fn abi_encode(&self) -> Vec<u8> {
229 let length = self.len();
230
231 let mut result = vec![0u8; 32];
232 result[28..32].copy_from_slice(&(32u32).to_be_bytes()); let mut length_bytes = vec![0u8; 32];
235 length_bytes[28..32].copy_from_slice(&(length as u32).to_be_bytes());
236 result.extend_from_slice(&length_bytes);
237
238 for element in self {
239 result.extend_from_slice(&element.abi_encode());
240 }
241
242 result
243 }
244}
245
246impl<T: AbiDecode> AbiDecode for Vec<T> {
247 fn abi_decode(data: &[u8]) -> std::result::Result<Self, DecodeError> {
248 if data.len() < 64 {
249 return Err(DecodeError::InvalidData);
250 }
251
252 let mut offset_bytes = [0u8; 4];
253 offset_bytes.copy_from_slice(&data[28..32]);
254 let offset = u32::from_be_bytes(offset_bytes) as usize;
255
256 if data.len() < offset + 32 {
257 return Err(DecodeError::InvalidData);
258 }
259
260 let mut length_bytes = [0u8; 4];
261 length_bytes.copy_from_slice(&data[offset + 28..offset + 32]);
262 let length = u32::from_be_bytes(length_bytes) as usize;
263
264 let mut result = Vec::with_capacity(length);
265 let mut pos = offset + 32;
266
267 for _ in 0..length {
268 if data.len() < pos + 32 {
269 return Err(DecodeError::InvalidData);
270 }
271
272 let element = T::abi_decode(&data[pos..pos + 32])?;
273 result.push(element);
274 pos += 32;
275 }
276
277 Ok(result)
278 }
279}
280
281pub fn encode<T: AbiEncode>(value: &T) -> Vec<u8> {
282 value.abi_encode()
283}
284
285pub fn decode<T: AbiDecode>(data: &[u8]) -> Result<T> {
286 T::abi_decode(data).map_err(Into::into)
287}
288
289pub fn is_dynamic_type(solidity_type: &str) -> bool {
290 solidity_type == "string" || solidity_type == "bytes" || solidity_type.ends_with("[]")
291}