1use crate::{
6 types::{self, Selector, Uint8, H256, H512, I256, U128, U256, U64},
7 utils::id,
8};
9pub use ethabi::{self, Contract as Abi, *};
10
11mod tokens;
12pub use tokens::{Detokenize, InvalidOutputType, Tokenizable, TokenizableItem, Tokenize};
13
14pub mod struct_def;
15pub use struct_def::SolStruct;
16
17mod codec;
18pub use codec::{AbiDecode, AbiEncode};
19
20mod error;
21pub use error::{AbiError, ParseError};
22
23mod human_readable;
24pub use human_readable::{
25 lexer::HumanReadableParser, parse as parse_abi, parse_str as parse_abi_str, AbiParser,
26};
27
28mod raw;
29pub use raw::{AbiObject, Component, Item, JsonAbi, RawAbi};
30
31mod packed;
32pub use packed::{encode_packed, EncodePackedError};
33
34mod sealed {
35 use ethabi::{Event, Function};
36
37 pub trait Sealed {}
39 impl Sealed for Function {}
40 impl Sealed for Event {}
41 impl Sealed for ethabi::AbiError {}
42}
43
44pub trait FunctionExt: sealed::Sealed {
46 fn abi_signature(&self) -> String;
49
50 fn selector(&self) -> Selector;
52}
53
54impl FunctionExt for Function {
55 fn abi_signature(&self) -> String {
56 let mut full_signature = self.signature();
57 if let Some(colon) = full_signature.find(':') {
58 full_signature.truncate(colon);
59 }
60
61 full_signature
62 }
63
64 fn selector(&self) -> Selector {
65 id(self.abi_signature())
66 }
67}
68
69pub trait EventExt: sealed::Sealed {
71 fn abi_signature(&self) -> String;
75}
76
77impl EventExt for Event {
78 fn abi_signature(&self) -> String {
79 format!(
80 "{}({}){}",
81 self.name,
82 self.inputs.iter().map(|input| input.kind.to_string()).collect::<Vec<_>>().join(","),
83 if self.anonymous { " anonymous" } else { "" },
84 )
85 }
86}
87
88pub trait ErrorExt: sealed::Sealed {
90 fn abi_signature(&self) -> String;
92
93 fn selector(&self) -> Selector;
95}
96
97impl ErrorExt for ethabi::AbiError {
98 fn abi_signature(&self) -> String {
99 if self.inputs.is_empty() {
100 return format!("{}()", self.name)
101 }
102 let inputs = self.inputs.iter().map(|p| p.kind.to_string()).collect::<Vec<_>>().join(",");
103 format!("{}({inputs})", self.name)
104 }
105
106 fn selector(&self) -> Selector {
107 id(self.abi_signature())
108 }
109}
110
111pub trait AbiType {
113 fn param_type() -> ParamType;
115
116 fn minimum_size() -> usize {
118 minimum_size(&Self::param_type())
119 }
120}
121
122pub fn minimum_size(ty: &ParamType) -> usize {
124 match ty {
125 ParamType::Uint(_) |
127 ParamType::Int(_) |
128 ParamType::Bool |
129 ParamType::Address |
130 ParamType::FixedBytes(_) => 32,
131 ParamType::Bytes | ParamType::String | ParamType::Array(_) => 64,
133 ParamType::FixedArray(ty, len) => minimum_size(ty) * len,
135 ParamType::Tuple(tys) => tys.iter().map(minimum_size).sum(),
136 }
137}
138
139impl AbiType for u8 {
140 fn param_type() -> ParamType {
141 ParamType::Uint(8)
142 }
143}
144
145pub trait AbiArrayType: AbiType {}
149
150impl<T: AbiArrayType> AbiType for Vec<T> {
151 fn param_type() -> ParamType {
152 ParamType::Array(Box::new(T::param_type()))
153 }
154}
155impl<T: AbiArrayType> AbiArrayType for Vec<T> {}
156
157impl<T: AbiArrayType, const N: usize> AbiType for [T; N] {
158 fn param_type() -> ParamType {
159 ParamType::FixedArray(Box::new(T::param_type()), N)
160 }
161}
162
163impl<T: AbiArrayType, const N: usize> AbiArrayType for [T; N] {}
164
165impl<const N: usize> AbiType for [u8; N] {
166 fn param_type() -> ParamType {
167 ParamType::FixedBytes(N)
168 }
169}
170impl<const N: usize> AbiArrayType for [u8; N] {}
171
172macro_rules! impl_abi_type {
173 ($($name:ty => $var:ident $(($value:expr))? ),*) => {
174 $(
175 impl AbiType for $name {
176 fn param_type() -> ParamType {
177 ParamType::$var $( ($value) )?
178 }
179 }
180
181 impl AbiArrayType for $name {}
182 )*
183 };
184}
185
186impl_abi_type!(
187 types::Bytes => Bytes,
188 bytes::Bytes => Bytes,
189 Vec<u8> => Array(Box::new(ParamType::Uint(8))),
190 Address => Address,
191 bool => Bool,
192 String => String,
193 str => String,
194 H256 => FixedBytes(32),
195 H512 => FixedBytes(64),
196 Uint8 => Uint(8),
197 U64 => Uint(64),
198 U128 => Uint(128),
199 U256 => Uint(256),
200 u16 => Uint(16),
201 u32 => Uint(32),
202 u64 => Uint(64),
203 u128 => Uint(128),
204 i8 => Int(8),
205 i16 => Int(16),
206 i32 => Int(32),
207 i64 => Int(64),
208 i128 => Int(128),
209 I256 => Int(256)
210);
211
212impl<'a> AbiType for &'a str {
213 fn param_type() -> ParamType {
214 ParamType::String
215 }
216}
217
218impl<'a> AbiArrayType for &'a str {}
219
220macro_rules! impl_abi_type_tuple {
221 ($( $ty: ident),+) => {
222 impl<$($ty, )+> AbiType for ($($ty,)+) where
223 $(
224 $ty: AbiType,
225 )+
226 {
227 fn param_type() -> ParamType {
228 ParamType::Tuple(
229 ::std::vec![
230 $(
231 $ty::param_type(),
232 )+
233 ]
234 )
235 }
236 }
237
238 impl<$($ty, )+> AbiArrayType for ($($ty,)+) where
239 $(
240 $ty: AbiType,
241 )+ {}
242 }
243}
244
245impl_abi_type_tuple!(A);
246impl_abi_type_tuple!(A, B);
247impl_abi_type_tuple!(A, B, C);
248impl_abi_type_tuple!(A, B, C, D);
249impl_abi_type_tuple!(A, B, C, D, E);
250impl_abi_type_tuple!(A, B, C, D, E, F);
251impl_abi_type_tuple!(A, B, C, D, E, F, G);
252impl_abi_type_tuple!(A, B, C, D, E, F, G, H);
253impl_abi_type_tuple!(A, B, C, D, E, F, G, H, I);
254impl_abi_type_tuple!(A, B, C, D, E, F, G, H, I, J);
255impl_abi_type_tuple!(A, B, C, D, E, F, G, H, I, J, K);
256impl_abi_type_tuple!(A, B, C, D, E, F, G, H, I, J, K, L);
257impl_abi_type_tuple!(A, B, C, D, E, F, G, H, I, J, K, L, M);
258impl_abi_type_tuple!(A, B, C, D, E, F, G, H, I, J, K, L, M, N);
259impl_abi_type_tuple!(A, B, C, D, E, F, G, H, I, J, K, L, M, N, O);
260impl_abi_type_tuple!(A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P);
261impl_abi_type_tuple!(A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q);
262impl_abi_type_tuple!(A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R);
263impl_abi_type_tuple!(A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S);
264impl_abi_type_tuple!(A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T);
265impl_abi_type_tuple!(A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U);
266
267#[allow(clippy::extra_unused_type_parameters)]
268#[cfg(test)]
269mod tests {
270 use super::*;
271
272 #[test]
273 fn format_function_signature() {
274 for (f, expected) in &[
275 (
276 r#"{"name":"foo","inputs":[],"outputs":[], "stateMutability": "nonpayable"}"#,
277 "foo()",
278 ),
279 (
280 r#"{"name":"bar","inputs":[{"name":"a","type":"uint256"},{"name":"b","type":"bool"}],"outputs":[], "stateMutability": "nonpayable"}"#,
281 "bar(uint256,bool)",
282 ),
283 (
284 r#"{"name":"baz","inputs":[{"name":"a","type":"uint256"}],"outputs":[{"name":"b","type":"bool"}], "stateMutability": "nonpayable"}"#,
285 "baz(uint256)",
286 ),
287 (
288 r#"{"name":"bax","inputs":[],"outputs":[{"name":"a","type":"uint256"},{"name":"b","type":"bool"}], "stateMutability": "nonpayable"}"#,
289 "bax()",
290 ),
291 ] {
292 let function: Function = serde_json::from_str(f).expect("invalid function JSON");
293 let signature = function.abi_signature();
294 assert_eq!(signature, *expected);
295 }
296 }
297
298 #[test]
299 fn format_event_signature() {
300 for (e, expected) in &[
301 (r#"{"name":"foo","inputs":[],"anonymous":false}"#, "foo()"),
302 (
303 r#"{"name":"bar","inputs":[{"name":"a","type":"uint256"},{"name":"b","type":"bool"}],"anonymous":false}"#,
304 "bar(uint256,bool)",
305 ),
306 (
307 r#"{"name":"baz","inputs":[{"name":"a","type":"uint256"}],"anonymous":true}"#,
308 "baz(uint256) anonymous",
309 ),
310 (r#"{"name":"bax","inputs":[],"anonymous":true}"#, "bax() anonymous"),
311 ] {
312 let event: Event = serde_json::from_str(e).expect("invalid event JSON");
313 let signature = event.abi_signature();
314 assert_eq!(signature, *expected);
315 }
316 }
317
318 #[test]
319 fn abi_type_works() {
320 assert_eq!(ParamType::Bytes, types::Bytes::param_type());
321 assert_eq!(ParamType::Array(Box::new(ParamType::Uint(8))), Vec::<u8>::param_type());
322 assert_eq!(ParamType::Array(Box::new(ParamType::Bytes)), Vec::<types::Bytes>::param_type());
323 assert_eq!(
324 ParamType::Array(Box::new(ParamType::Array(Box::new(ParamType::Uint(8))))),
325 Vec::<Vec<u8>>::param_type()
326 );
327 assert_eq!(
328 ParamType::Array(Box::new(ParamType::Array(Box::new(ParamType::Array(Box::new(
329 ParamType::Uint(8)
330 )))))),
331 Vec::<Vec<Vec<u8>>>::param_type()
332 );
333
334 assert_eq!(ParamType::Array(Box::new(ParamType::Uint(16))), Vec::<u16>::param_type());
335
336 assert_eq!(
337 ParamType::Tuple(vec![ParamType::Bytes, ParamType::Address]),
338 <(types::Bytes, Address)>::param_type()
339 );
340
341 assert_eq!(ParamType::FixedBytes(32), <[u8; 32]>::param_type());
342 assert_eq!(
343 ParamType::Array(Box::new(ParamType::FixedBytes(32))),
344 Vec::<[u8; 32]>::param_type()
345 );
346
347 assert_eq!(
348 ParamType::FixedArray(Box::new(ParamType::Uint(16)), 32),
349 <[u16; 32]>::param_type()
350 );
351
352 assert_eq!(ParamType::String, str::param_type());
353 assert_eq!(ParamType::String, <&str>::param_type());
354 }
355
356 #[test]
357 fn abi_type_tuples_work() {
358 fn assert_abitype<T: AbiType>() {}
359 fn assert_abiarraytype<T: AbiArrayType>() {}
360
361 assert_abitype::<(u64, u64)>();
362 assert_abiarraytype::<(u64, u64)>();
363
364 assert_abitype::<(u8, u8)>();
365 assert_abiarraytype::<(u8, u8)>();
366
367 assert_abitype::<Vec<(u64, u64)>>();
368 assert_abiarraytype::<Vec<(u64, u64)>>();
369
370 assert_abitype::<Vec<(u8, u8)>>();
371 assert_abiarraytype::<Vec<(u8, u8)>>();
372 }
373}