evm_coder/abi/
impls.rs

1use primitive_types::{H160, U256};
2
3use super::{
4	AbiDecode, AbiDecodeZero, AbiDecoder, AbiEncode, AbiEncodeZero, AbiEncoder, ABI_WORD_SIZE,
5};
6use crate::{
7	abi::{traits::AbiType, Error, Result},
8	custom_signature::SignatureUnit,
9	make_signature,
10	types::*,
11};
12
13impl<T: AbiType> AbiType for Vec<T> {
14	const SIGNATURE: SignatureUnit = make_signature!(new nameof(T::SIGNATURE) fixed("[]"));
15	const HEAD_WORDS: u32 = 1;
16	const IS_DYNAMIC: bool = true;
17}
18impl<T: AbiEncode> AbiEncode for Vec<T> {
19	fn enc(&self, out: &mut AbiEncoder) {
20		(self.len() as u32).enc(out);
21		if T::IS_DYNAMIC {
22			out.reserve_head(self.len() as u32);
23			for v in self {
24				(self.len() as u32 * ABI_WORD_SIZE + out.tail_size()).enc(out);
25				out.encode_tail(v);
26			}
27		} else {
28			for v in self {
29				out.encode_tail(v);
30			}
31		}
32	}
33}
34impl<T: AbiDecode> AbiDecode for Vec<T> {
35	fn dec(input: &mut AbiDecoder<'_>) -> Result<Self> {
36		let len = u32::dec(input)?;
37		// Not using with_capacity, len may be too big
38		let mut out = Vec::new();
39		let mut input = input.start_frame();
40		if T::IS_DYNAMIC {
41			for _ in 0..len {
42				let offset = u32::dec(&mut input)?;
43				out.push(T::dec(&mut input.dynamic_at(offset)?)?)
44			}
45		} else {
46			for _ in 0..len {
47				out.push(T::dec(&mut input)?)
48			}
49		}
50		Ok(out)
51	}
52}
53
54impl<T: AbiType, const S: usize> AbiType for [T; S] {
55	const SIGNATURE: SignatureUnit =
56		make_signature!(new nameof(T::SIGNATURE) fixed("[") numof(S) fixed("]"));
57	const HEAD_WORDS: u32 = if T::IS_DYNAMIC {
58		S as u32
59	} else {
60		T::HEAD_WORDS * S as u32
61	};
62	const IS_DYNAMIC: bool = T::IS_DYNAMIC;
63}
64impl<T: AbiEncode, const S: usize> AbiEncode for [T; S] {
65	fn enc(&self, out: &mut AbiEncoder) {
66		if T::IS_DYNAMIC {
67			for v in self {
68				(Self::HEAD_WORDS * self.len() as u32 + out.tail_size()).enc(out);
69				out.encode_tail(v);
70			}
71		} else {
72			for v in self {
73				v.enc(out)
74			}
75		}
76	}
77}
78impl<T: AbiDecode, const S: usize> AbiDecode for [T; S] {
79	fn dec(input: &mut AbiDecoder<'_>) -> Result<Self> {
80		let mut out = Vec::with_capacity(S);
81		if T::IS_DYNAMIC {
82			for _ in 0..S {
83				let offset = u32::dec(input)?;
84				let mut data = input.dynamic_at(offset)?;
85				out.push(T::dec(&mut data)?);
86			}
87		} else {
88			for _ in 0..S {
89				out.push(T::dec(input)?);
90			}
91		}
92		out.try_into().map_err(|_| Error::InvalidRange)
93	}
94}
95
96impl AbiType for &str {
97	const SIGNATURE: SignatureUnit = make_signature!(new fixed("string"));
98	const HEAD_WORDS: u32 = 1;
99	const IS_DYNAMIC: bool = true;
100}
101impl AbiEncode for &str {
102	fn enc(&self, out: &mut AbiEncoder) {
103		(self.len() as u32).enc(out);
104		for ele in self.as_bytes().chunks(32) {
105			let mut word = [0; ABI_WORD_SIZE as usize];
106			word[0..ele.len()].copy_from_slice(ele);
107			out.append_tail(word);
108		}
109	}
110}
111
112impl AbiType for String {
113	const SIGNATURE: SignatureUnit = <&str>::SIGNATURE;
114	const HEAD_WORDS: u32 = <&str>::HEAD_WORDS;
115	const IS_DYNAMIC: bool = <&str>::IS_DYNAMIC;
116}
117impl AbiEncode for String {
118	fn enc(&self, out: &mut AbiEncoder) {
119		self.as_str().enc(out)
120	}
121}
122impl AbiDecode for String {
123	fn dec(input: &mut AbiDecoder<'_>) -> Result<Self> {
124		let bytes = Bytes::dec(input)?;
125		String::from_utf8(bytes.0).map_err(|_| Error::InvalidRange)
126	}
127}
128
129impl AbiType for Bytes {
130	const SIGNATURE: SignatureUnit = make_signature!(new fixed("bytes"));
131	const HEAD_WORDS: u32 = 1;
132	const IS_DYNAMIC: bool = true;
133}
134impl AbiEncode for Bytes {
135	fn enc(&self, out: &mut AbiEncoder) {
136		(self.len() as u32).enc(out);
137		for ele in self.0.chunks(32) {
138			let mut word = [0; ABI_WORD_SIZE as usize];
139			word[0..ele.len()].copy_from_slice(ele);
140			out.append_tail(word);
141		}
142	}
143}
144impl AbiDecode for Bytes {
145	fn dec(input: &mut AbiDecoder<'_>) -> Result<Self> {
146		let len = u32::dec(input)?;
147		// Not using with_capacity: len might be bad
148		let mut out = Vec::new();
149		// Next multiple of 32
150		let full_words = len / 32;
151		for _ in 0..full_words {
152			let word = input.get_head()?;
153			out.extend_from_slice(&word);
154		}
155		let leftovers = len % 32;
156		if leftovers != 0 {
157			let word = input.get_head()?;
158			out.extend_from_slice(&word[..leftovers as usize]);
159			for i in leftovers..32 {
160				if word[i as usize] != 0 {
161					return Err(Error::InvalidRange);
162				}
163			}
164		}
165		Ok(Self(out))
166	}
167}
168
169impl<const S: usize> AbiType for BytesFixed<S> {
170	const SIGNATURE: SignatureUnit = make_signature!(new fixed("bytes") numof(S));
171	// Next multiple of 32
172	const HEAD_WORDS: u32 = (S as u32 + 31) & !31;
173	const IS_DYNAMIC: bool = false;
174}
175impl<const S: usize> AbiEncode for BytesFixed<S> {
176	fn enc(&self, out: &mut AbiEncoder) {
177		for ele in self.0.chunks(32) {
178			let mut word = [0; ABI_WORD_SIZE as usize];
179			word[0..ele.len()].copy_from_slice(ele);
180			out.append_tail(word);
181		}
182	}
183}
184impl<const S: usize> AbiDecode for BytesFixed<S> {
185	fn dec(input: &mut AbiDecoder<'_>) -> Result<Self> {
186		// Not using with_capacity: len might be bad
187		let mut out = Vec::new();
188		// Next multiple of 32
189		let full_words = S / 32;
190		for _ in 0..full_words {
191			let word = input.get_head()?;
192			out.extend_from_slice(&word);
193		}
194		let leftovers = S % 32;
195		if leftovers != 0 {
196			let word = input.get_head()?;
197			out.extend_from_slice(&word[..leftovers]);
198			if word[leftovers..ABI_WORD_SIZE as usize]
199				.iter()
200				.any(|&v| v != 0)
201			{
202				return Err(Error::InvalidRange);
203			}
204		}
205		out.try_into().map(Self).map_err(|_| Error::InvalidRange)
206	}
207}
208
209impl AbiType for () {
210	const SIGNATURE: SignatureUnit = make_signature!(new fixed("()"));
211	const HEAD_WORDS: u32 = 0;
212	const IS_DYNAMIC: bool = false;
213}
214impl AbiEncode for () {
215	fn enc(&self, _out: &mut AbiEncoder) {}
216}
217impl AbiDecode for () {
218	fn dec(_input: &mut AbiDecoder<'_>) -> Result<Self> {
219		Ok(())
220	}
221}
222
223const fn tuple_comp_head_words<T: AbiType>() -> u32 {
224	if T::IS_DYNAMIC {
225		1
226	} else {
227		T::HEAD_WORDS
228	}
229}
230fn encode_tuple_comp<T: AbiEncode>(comp: &T, total_head: u32, out: &mut AbiEncoder) {
231	if T::IS_DYNAMIC {
232		let head = total_head * ABI_WORD_SIZE + out.tail_size();
233		head.enc(out);
234		out.encode_tail(comp);
235	} else {
236		comp.enc(out);
237	}
238}
239fn decode_tuple_comp<T: AbiDecode>(input: &mut AbiDecoder) -> Result<T> {
240	if T::IS_DYNAMIC {
241		let head = u32::dec(input)?;
242		let mut dynamic = input.dynamic_at(head)?;
243		T::dec(&mut dynamic)
244	} else {
245		T::dec(input)
246	}
247}
248macro_rules! impl_tuples {
249	($($gen:ident)+) => {
250		impl<$($gen: AbiType,)*> AbiType for ($($gen,)*)
251		where $(
252			$gen: AbiType,
253		)*
254		{
255			const SIGNATURE: SignatureUnit = make_signature!(
256				new fixed("(")
257					$(nameof(<$gen>::SIGNATURE) fixed(","))+
258					shift_left(1)
259					fixed(")")
260				);
261			const HEAD_WORDS: u32 = 0 $(+ tuple_comp_head_words::<$gen>())*;
262			const IS_DYNAMIC: bool = false $(|| $gen::IS_DYNAMIC)*;
263		}
264
265		#[allow(non_snake_case)]
266		impl<$($gen: AbiEncode,)*> AbiEncode for ($($gen,)*) {
267			#[allow(unused_variables)]
268			fn enc(&self, out: &mut AbiEncoder) {
269				#[allow(non_snake_case)]
270				let ($($gen,)*) = self;
271				$(encode_tuple_comp($gen, Self::HEAD_WORDS, out);)*
272			}
273		}
274
275		#[allow(non_snake_case)]
276		impl<$($gen: AbiDecode,)*> AbiDecode for ($($gen,)*) {
277			fn dec(input: &mut AbiDecoder) -> Result<($($gen,)*)> {
278				Ok((
279					$({
280						#[allow(unused_variables)]
281						let $gen = 0;
282						decode_tuple_comp::<$gen>(input)?
283					},)*
284				))
285			}
286		}
287	};
288	($($cur:ident)* @ $c:ident $($rest:ident)*) => {
289		impl_tuples!($($cur)*);
290		impl_tuples!($($cur)* $c @ $($rest)*);
291	};
292	($($cur:ident)* @) => {
293		impl_tuples!($($cur)*);
294	};
295}
296impl_tuples!(A @ B C D E F G H I J K L M N O P);
297
298//----- impls for Option -----
299impl<T: AbiType> AbiType for Option<T> {
300	const SIGNATURE: SignatureUnit = <(bool, T)>::SIGNATURE;
301	const HEAD_WORDS: u32 = <(bool, T)>::HEAD_WORDS;
302	const IS_DYNAMIC: bool = <(bool, T)>::IS_DYNAMIC;
303}
304impl<T: AbiEncode + AbiEncodeZero> AbiEncode for Option<T> {
305	fn enc(&self, out: &mut AbiEncoder) {
306		match self {
307			Some(v) => (true, v).enc(out),
308			None => (false, <Zero<T>>::new()).enc(out),
309		}
310	}
311}
312impl<T: AbiDecode + AbiDecodeZero> AbiDecode for Option<T> {
313	fn dec(input: &mut AbiDecoder<'_>) -> Result<Self> {
314		let has_value = bool::dec(input)?;
315		if T::IS_DYNAMIC {
316			let off = u32::dec(input)?;
317			let mut input = input.dynamic_at(off)?;
318			if has_value {
319				Some(T::dec(&mut input)).transpose()
320			} else {
321				<Zero<T>>::dec(&mut input)?;
322				Ok(None)
323			}
324		} else if has_value {
325			Some(T::dec(input)).transpose()
326		} else {
327			<Zero<T>>::dec(input)?;
328			Ok(None)
329		}
330	}
331}
332
333impl<T: AbiType> AbiType for Zero<T> {
334	const SIGNATURE: SignatureUnit = T::SIGNATURE;
335	const HEAD_WORDS: u32 = T::HEAD_WORDS;
336	const IS_DYNAMIC: bool = T::IS_DYNAMIC;
337}
338impl<T: AbiEncodeZero> AbiEncode for Zero<T> {
339	fn enc(&self, out: &mut AbiEncoder) {
340		T::enc_zero(out)
341	}
342}
343impl<T: AbiDecodeZero> AbiDecode for Zero<T> {
344	fn dec(input: &mut AbiDecoder<'_>) -> Result<Self> {
345		T::dec_zero(input)?;
346		Ok(Self::new())
347	}
348}
349
350macro_rules! impl_num_abicode {
351	($pref:literal $($t:ty)*) => {$(
352		impl AbiType for $t {
353			const SIGNATURE: SignatureUnit = make_signature!(new fixed($pref) numof(<$t>::BITS));
354			const IS_DYNAMIC: bool = false;
355			const HEAD_WORDS: u32 = 1;
356		}
357		impl AbiEncode for $t {
358			// const HEAD_WORDS: u32 = 1;
359			// const IS_DYNAMIC: bool = false;
360			fn enc(&self, out: &mut AbiEncoder) {
361				let bytes = self.to_be_bytes();
362				let mut word = [0; ABI_WORD_SIZE as usize];
363				word[ABI_WORD_SIZE as usize - bytes.len()..ABI_WORD_SIZE as usize].copy_from_slice(&bytes);
364				out.append_head(word);
365			}
366		}
367		impl AbiDecode for $t {
368			fn dec(input: &mut AbiDecoder) -> Result<$t> {
369				let head = input.get_head()?;
370				let mut bytes = [0; <$t>::BITS as usize / 8];
371				let offset = 32-(<$t>::BITS as usize / 8);
372				for i in 0..offset {
373					if head[i] != 0 {
374						return Err(Error::InvalidRange);
375					}
376				}
377				bytes.copy_from_slice(&head[offset..32]);
378				Ok(<$t>::from_be_bytes(bytes))
379			}
380		}
381	)*};
382}
383impl_num_abicode!("uint" u8 u16 u32 u64 u128);
384impl_num_abicode!("int" i8 i16 i32 i64 i128);
385
386impl AbiType for bool {
387	const SIGNATURE: SignatureUnit = make_signature!(new fixed("bool"));
388	const IS_DYNAMIC: bool = false;
389	const HEAD_WORDS: u32 = 1;
390}
391impl AbiEncode for bool {
392	fn enc(&self, out: &mut AbiEncoder) {
393		(*self as u32).enc(out)
394	}
395}
396impl AbiDecode for bool {
397	fn dec(input: &mut AbiDecoder<'_>) -> Result<Self> {
398		let v = u32::dec(input)?;
399		Ok(match v {
400			0 => false,
401			1 => true,
402			_ => return Err(Error::InvalidRange),
403		})
404	}
405}
406impl AbiType for H160 {
407	const SIGNATURE: SignatureUnit = make_signature!(new fixed("address"));
408	const HEAD_WORDS: u32 = 1;
409	const IS_DYNAMIC: bool = false;
410}
411impl AbiEncode for H160 {
412	fn enc(&self, out: &mut AbiEncoder) {
413		let mut word = [0; ABI_WORD_SIZE as usize];
414		word[12..].copy_from_slice(&self.0);
415		out.append_head(word)
416	}
417}
418impl AbiDecode for H160 {
419	fn dec(input: &mut AbiDecoder<'_>) -> Result<Self> {
420		let data = input.get_head()?;
421		let mut out = [0; 20];
422		out.copy_from_slice(&data[12..]);
423		if data[0..12].iter().any(|&b| b != 0) {
424			return Err(Error::InvalidRange);
425		}
426		Ok(H160(out))
427	}
428}
429
430impl AbiType for U256 {
431	const SIGNATURE: SignatureUnit = make_signature!(new fixed("uint256"));
432	const HEAD_WORDS: u32 = 1;
433	const IS_DYNAMIC: bool = false;
434}
435impl AbiEncode for U256 {
436	fn enc(&self, out: &mut AbiEncoder) {
437		let mut word = [0; ABI_WORD_SIZE as usize];
438		self.to_big_endian(&mut word);
439		out.append_head(word)
440	}
441}
442impl AbiDecode for U256 {
443	fn dec(input: &mut AbiDecoder<'_>) -> Result<Self> {
444		let word = input.get_head()?;
445		Ok(U256::from_big_endian(&word))
446	}
447}