1use ethabi::AbiError;
2use std::collections::{BTreeMap, HashMap, VecDeque};
3
4use crate::abi::{
5 error::{bail, format_err, ParseError, Result},
6 struct_def::{FieldType, StructFieldType},
7 Abi, Constructor, Event, EventParam, Function, HumanReadableParser, Param, ParamType,
8 SolStruct, StateMutability,
9};
10pub mod lexer;
11
12pub struct AbiParser {
14 pub structs: HashMap<String, SolStruct>,
16 pub struct_tuples: HashMap<String, Vec<ParamType>>,
18 pub function_params: HashMap<(String, String), String>,
21 pub event_params: HashMap<(String, usize), String>,
26 pub outputs: HashMap<String, Vec<String>>,
28}
29
30impl AbiParser {
31 pub fn parse_str(&mut self, s: &str) -> Result<Abi> {
44 self.parse(
45 &s.trim().trim_start_matches('[').trim_end_matches(']').lines().collect::<Vec<_>>(),
46 )
47 }
48
49 pub fn parse(&mut self, input: &[&str]) -> Result<Abi> {
60 let mut abi = Abi {
62 constructor: None,
63 functions: BTreeMap::new(),
64 events: BTreeMap::new(),
65 errors: BTreeMap::new(),
66 receive: false,
67 fallback: false,
68 };
69
70 let (structs, types): (Vec<_>, Vec<_>) = input
71 .iter()
72 .map(|s| escape_quotes(s))
73 .map(str::trim)
74 .filter(|s| !s.is_empty())
75 .partition(|s| s.starts_with("struct"));
76
77 for sol in structs {
78 let s = SolStruct::parse(sol)?;
79 if self.structs.contains_key(s.name()) {
80 bail!("Duplicate struct declaration for struct `{}`", s.name())
81 }
82 self.structs.insert(s.name().to_string(), s);
83 }
84 self.substitute_structs()?;
85
86 for mut line in types {
87 line = line.trim_start();
88 if line.starts_with("event") {
89 let event = self.parse_event(line)?;
90 abi.events.entry(event.name.clone()).or_default().push(event);
91 } else if let Some(err) = line.strip_prefix("error") {
92 let function = match self.parse_function(err) {
94 Ok(function) => function,
95 Err(_) => bail!("Illegal abi `{}`, expected error", line),
96 };
97 if !function.outputs.is_empty() {
98 bail!("Illegal abi `{}`, expected error", line);
99 }
100 let error = AbiError { name: function.name, inputs: function.inputs };
101 abi.errors.entry(error.name.clone()).or_default().push(error);
102 } else if line.starts_with("constructor") {
103 let inputs = self
104 .constructor_inputs(line)?
105 .into_iter()
106 .map(|(input, struct_name)| {
107 if let Some(struct_name) = struct_name {
108 self.function_params.insert(
110 ("constructor".to_string(), input.name.clone()),
111 struct_name,
112 );
113 }
114 input
115 })
116 .collect();
117
118 abi.constructor = Some(Constructor { inputs });
119 } else {
120 let function = match self.parse_function(line) {
122 Ok(function) => function,
123 Err(_) => bail!("Illegal abi `{}`, expected function", line),
124 };
125 abi.functions.entry(function.name.clone()).or_default().push(function);
126 }
127 }
128 Ok(abi)
129 }
130
131 fn substitute_structs(&mut self) -> Result<()> {
133 let mut unresolved = self.structs.keys().collect::<VecDeque<_>>();
134 let mut sequential_retries = 0;
135 while let Some(name) = unresolved.pop_front() {
136 let mut unresolved_field = None;
137 let sol = &self.structs[name];
138 let mut tuple = Vec::with_capacity(sol.fields().len());
139 for field in sol.fields() {
140 match field.r#type() {
141 FieldType::Elementary(param) => tuple.push(param.clone()),
142 FieldType::Struct(ty) => {
143 if let Some(param) = self.struct_tuples.get(ty.name()) {
144 tuple.push(ty.as_param(ParamType::Tuple(param.clone())))
145 } else {
146 unresolved_field = Some(field);
147 break
148 }
149 }
150 FieldType::Mapping(_) => {
151 bail!(
152 "mappings are not allowed as params in public functions of struct `{}`",
153 sol.name()
154 )
155 }
156 }
157 }
158 if let Some(f) = unresolved_field {
159 sequential_retries += 1;
160 if sequential_retries > unresolved.len() {
161 bail!("Could not resolve field of struct '{name}': `{}: {:?}`", f.name, f.ty)
162 }
163 unresolved.push_back(name);
164 } else {
165 sequential_retries = 0;
166 self.struct_tuples.insert(sol.name().to_string(), tuple);
167 }
168 }
169 Ok(())
170 }
171
172 pub fn with_structs(structs: Vec<SolStruct>) -> Self {
174 Self {
175 structs: structs.into_iter().map(|s| (s.name().to_string(), s)).collect(),
176 struct_tuples: HashMap::new(),
177 function_params: Default::default(),
178 event_params: Default::default(),
179 outputs: Default::default(),
180 }
181 }
182
183 pub fn parse_event(&mut self, s: &str) -> Result<Event> {
185 let mut event = s.trim();
186 if !event.starts_with("event ") {
187 bail!("Not an event `{}`", s)
188 }
189 event = &event[5..];
190
191 let name = parse_identifier(&mut event)?;
192
193 let mut chars = event.chars();
194
195 loop {
196 match chars.next() {
197 None => bail!("Expected event"),
198 Some('(') => {
199 event = chars.as_str().trim();
200 let mut anonymous = false;
201 if event.ends_with("anonymous") {
202 anonymous = true;
203 event = event[..event.len() - 9].trim_end();
204 }
205 event = event
206 .trim()
207 .strip_suffix(')')
208 .ok_or_else(|| format_err!("Expected closing `)` in `{}`", s))?;
209
210 let inputs = if event.is_empty() {
211 Vec::new()
212 } else {
213 event
214 .split(',')
215 .map(|e| self.parse_event_arg(e))
216 .collect::<Result<Vec<_>, _>>()?
217 .into_iter()
218 .enumerate()
219 .map(|(idx, (input, struct_name))| {
220 if let Some(struct_name) = struct_name {
221 self.event_params.insert((name.clone(), idx), struct_name);
223 }
224 input
225 })
226 .collect()
227 };
228
229 let event = Event { name, inputs, anonymous };
230 return Ok(event)
231 }
232 Some(' ') | Some('\t') => continue,
233 Some(c) => {
234 bail!("Illegal char `{}` at `{}`", c, s)
235 }
236 }
237 }
238 }
239
240 fn parse_event_arg(&self, input: &str) -> Result<(EventParam, Option<String>)> {
244 let mut iter = input.trim().rsplitn(3, is_whitespace);
245 let mut indexed = false;
246 let mut name =
247 iter.next().ok_or_else(|| format_err!("Empty event param at `{}`", input))?;
248
249 let type_str;
250 if let Some(mid) = iter.next() {
251 if let Some(ty) = iter.next() {
252 if mid != "indexed" {
253 bail!("Expected indexed keyword at `{}`", input)
254 }
255 indexed = true;
256 type_str = ty;
257 } else {
258 if name == "indexed" {
259 indexed = true;
260 name = "";
261 }
262 type_str = mid;
263 }
264 } else {
265 type_str = name;
266 name = "";
267 }
268
269 let (kind, user_ty) = self.parse_type(type_str)?;
270 Ok((EventParam { name: name.to_string(), indexed, kind }, user_ty))
271 }
272
273 pub fn parse_function(&mut self, s: &str) -> Result<Function> {
283 let mut input = s.trim();
284 let shorthand = !input.starts_with("function ");
285
286 if !shorthand {
287 input = &input[8..];
288 }
289
290 let name = parse_identifier(&mut input)?;
291 input = input
292 .strip_prefix('(')
293 .ok_or_else(|| format_err!("Expected input args parentheses at `{}`", s))?;
294
295 let (input_args_modifiers, output_args) = match input.rsplit_once('(') {
296 Some((first, second)) => (first, Some(second)),
297 None => (input, None),
298 };
299
300 let mut input_args_modifiers_iter = input_args_modifiers
301 .trim_end()
302 .strip_suffix(" returns")
303 .unwrap_or(input_args_modifiers)
304 .splitn(2, ')');
305
306 let input_args = match input_args_modifiers_iter
307 .next()
308 .ok_or_else(|| format_err!("Expected input args parentheses at `{}`", s))?
309 {
310 "" => None,
311 input_params_args => Some(input_params_args),
312 };
313 let modifiers = match input_args_modifiers_iter
314 .next()
315 .ok_or_else(|| format_err!("Expected input args parentheses at `{}`", s))?
316 {
317 "" => None,
318 modifiers => Some(modifiers),
319 };
320
321 let inputs = if let Some(params) = input_args {
322 self.parse_params(params)?
323 .into_iter()
324 .map(|(input, struct_name)| {
325 if let Some(struct_name) = struct_name {
326 self.function_params
328 .insert((name.clone(), input.name.clone()), struct_name);
329 }
330 input
331 })
332 .collect()
333 } else {
334 Vec::new()
335 };
336
337 let outputs = if let Some(params) = output_args {
338 let params = params
339 .trim()
340 .strip_suffix(')')
341 .ok_or_else(|| format_err!("Expected output args parentheses at `{}`", s))?;
342 let output_params = self.parse_params(params)?;
343 let mut outputs = Vec::with_capacity(output_params.len());
344 let mut output_types = Vec::new();
345
346 for (output, struct_name) in output_params {
347 if let Some(struct_name) = struct_name {
348 output_types.push(struct_name);
350 }
351 outputs.push(output);
352 }
353 self.outputs.insert(name.clone(), output_types);
354 outputs
355 } else {
356 Vec::new()
357 };
358
359 let state_mutability = modifiers.map(detect_state_mutability).unwrap_or_default();
360
361 Ok(
362 #[allow(deprecated)]
363 Function { name, inputs, outputs, state_mutability, constant: None },
364 )
365 }
366
367 fn parse_params(&self, s: &str) -> Result<Vec<(Param, Option<String>)>> {
368 s.split(',')
369 .filter(|s| !s.is_empty())
370 .map(|s| self.parse_param(s))
371 .collect::<Result<Vec<_>, _>>()
372 }
373
374 fn parse_type(&self, type_str: &str) -> Result<(ParamType, Option<String>)> {
408 if let Ok(kind) = HumanReadableParser::parse_type(type_str) {
409 Ok((kind, None))
410 } else {
411 self.parse_struct_type(type_str)
413 }
414 }
415
416 fn parse_struct_type(&self, type_str: &str) -> Result<(ParamType, Option<String>)> {
419 if let Ok(field) = StructFieldType::parse(type_str) {
420 let struct_ty = field
421 .as_struct()
422 .ok_or_else(|| format_err!("Expected struct type `{}`", type_str))?;
423 let name = struct_ty.name();
424 let tuple = self
425 .struct_tuples
426 .get(name)
427 .cloned()
428 .map(ParamType::Tuple)
429 .ok_or_else(|| format_err!("Unknown struct `{}`", struct_ty.name()))?;
430
431 if let Some(field) = field.as_struct() {
432 Ok((field.as_param(tuple), Some(name.to_string())))
433 } else {
434 bail!("Expected struct type")
435 }
436 } else {
437 bail!("Failed determine event type `{}`", type_str)
438 }
439 }
440
441 pub fn parse_constructor(&self, s: &str) -> Result<Constructor> {
442 let inputs = self.constructor_inputs(s)?.into_iter().map(|s| s.0).collect();
443 Ok(Constructor { inputs })
444 }
445
446 fn constructor_inputs(&self, s: &str) -> Result<Vec<(Param, Option<String>)>> {
447 let mut input = s.trim();
448 if !input.starts_with("constructor") {
449 bail!("Not a constructor `{}`", input)
450 }
451 input = input[11..]
452 .trim_start()
453 .strip_prefix('(')
454 .ok_or_else(|| format_err!("Expected leading `(` in `{}`", s))?;
455
456 let params = input
457 .rsplitn(2, ')')
458 .last()
459 .ok_or_else(|| format_err!("Expected closing `)` in `{}`", s))?;
460
461 self.parse_params(params)
462 }
463
464 fn parse_param(&self, param: &str) -> Result<(Param, Option<String>)> {
465 let mut iter = param.trim().rsplitn(3, is_whitespace);
466
467 let mut name =
468 iter.next().ok_or_else(|| ParseError::ParseError(super::Error::InvalidData))?;
469
470 let type_str;
471 if let Some(ty) = iter.last() {
472 if name == "memory" || name == "calldata" {
473 name = "";
474 }
475 type_str = ty;
476 } else {
477 type_str = name;
478 name = "";
479 }
480 let (kind, user_struct) = self.parse_type(type_str)?;
481 Ok((Param { name: name.to_string(), kind, internal_type: None }, user_struct))
482 }
483}
484
485impl Default for AbiParser {
486 fn default() -> Self {
487 Self::with_structs(Vec::new())
488 }
489}
490
491pub fn parse(input: &[&str]) -> Result<Abi> {
501 AbiParser::default().parse(input)
502}
503
504pub fn parse_str(input: &str) -> Result<Abi> {
508 AbiParser::default().parse_str(input)
509}
510
511pub(crate) fn parse_identifier(input: &mut &str) -> Result<String> {
513 let mut chars = input.trim_start().chars();
514 let mut name = String::new();
515 let c = chars.next().ok_or_else(|| format_err!("Empty identifier in `{}`", input))?;
516 if is_first_ident_char(c) {
517 name.push(c);
518 loop {
519 match chars.clone().next() {
520 Some(c) if is_ident_char(c) => {
521 chars.next();
522 name.push(c);
523 }
524 _ => break,
525 }
526 }
527 }
528 if name.is_empty() {
529 return Err(ParseError::ParseError(super::Error::InvalidName(input.to_string())))
530 }
531 *input = chars.as_str();
532 Ok(name)
533}
534
535fn detect_state_mutability(s: &str) -> StateMutability {
536 if s.contains("pure") {
537 StateMutability::Pure
538 } else if s.contains("view") {
539 StateMutability::View
540 } else if s.contains("payable") {
541 StateMutability::Payable
542 } else {
543 StateMutability::NonPayable
544 }
545}
546
547pub(crate) fn is_first_ident_char(c: char) -> bool {
548 matches!(c, 'a'..='z' | 'A'..='Z' | '_')
549}
550
551pub(crate) fn is_ident_char(c: char) -> bool {
552 matches!(c, 'a'..='z' | 'A'..='Z' | '0'..='9' | '_')
553}
554
555pub(crate) fn is_whitespace(c: char) -> bool {
556 matches!(c, ' ' | '\t')
557}
558
559fn escape_quotes(input: &str) -> &str {
560 input.trim_matches(is_whitespace).trim_matches('\"')
561}
562
563#[cfg(test)]
564mod tests {
565 use super::*;
566
567 #[test]
568 fn parses_approve() {
569 let fn_str = "function approve(address _spender, uint256 value) external returns(bool)";
570 let parsed = AbiParser::default().parse_function(fn_str).unwrap();
571 assert_eq!(parsed.name, "approve");
572 assert_eq!(parsed.inputs[0].name, "_spender");
573 assert_eq!(parsed.inputs[0].kind, ParamType::Address,);
574 assert_eq!(parsed.inputs[1].name, "value");
575 assert_eq!(parsed.inputs[1].kind, ParamType::Uint(256),);
576 assert_eq!(parsed.outputs[0].name, "");
577 assert_eq!(parsed.outputs[0].kind, ParamType::Bool);
578 }
579
580 #[test]
581 fn parses_function_arguments_return() {
582 let fn_str = "function foo(uint32[] memory x) external view returns (address)";
583 let parsed = AbiParser::default().parse_function(fn_str).unwrap();
584 assert_eq!(parsed.name, "foo");
585 assert_eq!(parsed.inputs[0].name, "x");
586 assert_eq!(parsed.inputs[0].kind, ParamType::Array(Box::new(ParamType::Uint(32))));
587 assert_eq!(parsed.outputs[0].name, "");
588 assert_eq!(parsed.outputs[0].kind, ParamType::Address);
589 }
590
591 #[test]
592 fn parses_function_empty() {
593 let fn_str = "function foo()";
594 let parsed = AbiParser::default().parse_function(fn_str).unwrap();
595 assert_eq!(parsed.name, "foo");
596 assert!(parsed.inputs.is_empty());
597 assert!(parsed.outputs.is_empty());
598 }
599
600 #[test]
601 fn parses_function_payable() {
602 let fn_str = "function foo() public payable";
603 let parsed = AbiParser::default().parse_function(fn_str).unwrap();
604 assert_eq!(parsed.state_mutability, StateMutability::Payable);
605 }
606
607 #[test]
608 fn parses_function_view() {
609 let fn_str = "function foo() external view";
610 let parsed = AbiParser::default().parse_function(fn_str).unwrap();
611 assert_eq!(parsed.state_mutability, StateMutability::View);
612 }
613
614 #[test]
615 fn parses_function_pure() {
616 let fn_str = "function foo() pure";
617 let parsed = AbiParser::default().parse_function(fn_str).unwrap();
618 assert_eq!(parsed.state_mutability, StateMutability::Pure);
619 }
620
621 #[test]
622 fn parses_event() {
623 assert_eq!(
624 AbiParser::default()
625 .parse_event("event Foo (address indexed x, uint y, bytes32[] z)")
626 .unwrap(),
627 Event {
628 anonymous: false,
629 name: "Foo".to_string(),
630 inputs: vec![
631 EventParam { name: "x".to_string(), kind: ParamType::Address, indexed: true },
632 EventParam {
633 name: "y".to_string(),
634 kind: ParamType::Uint(256),
635 indexed: false,
636 },
637 EventParam {
638 name: "z".to_string(),
639 kind: ParamType::Array(Box::new(ParamType::FixedBytes(32))),
640 indexed: false,
641 },
642 ],
643 }
644 );
645 }
646
647 #[test]
648 fn parses_anonymous_event() {
649 assert_eq!(
650 AbiParser::default().parse_event("event Foo() anonymous").unwrap(),
651 Event { anonymous: true, name: "Foo".to_string(), inputs: vec![] }
652 );
653 }
654
655 #[test]
656 fn parses_unnamed_event() {
657 assert_eq!(
658 AbiParser::default().parse_event("event Foo(address)").unwrap(),
659 Event {
660 anonymous: false,
661 name: "Foo".to_string(),
662 inputs: vec![EventParam {
663 name: "".to_string(),
664 kind: ParamType::Address,
665 indexed: false,
666 }],
667 }
668 );
669 }
670
671 #[test]
672 fn parses_unnamed_indexed_event() {
673 assert_eq!(
674 AbiParser::default().parse_event("event Foo(address indexed)").unwrap(),
675 Event {
676 anonymous: false,
677 name: "Foo".to_string(),
678 inputs: vec![EventParam {
679 name: "".to_string(),
680 kind: ParamType::Address,
681 indexed: true,
682 }],
683 }
684 );
685 }
686
687 #[test]
688 fn parse_event_input() {
689 assert_eq!(
690 AbiParser::default().parse_event_arg("address indexed x").unwrap().0,
691 EventParam { name: "x".to_string(), kind: ParamType::Address, indexed: true }
692 );
693
694 assert_eq!(
695 AbiParser::default().parse_event_arg("address x").unwrap().0,
696 EventParam { name: "x".to_string(), kind: ParamType::Address, indexed: false }
697 );
698 }
699
700 #[test]
701 fn can_parse_functions() {
702 [
703 "function foo(uint256[] memory x) external view returns (address)",
704 "function bar(uint256[] memory x) returns(address)",
705 "function bar(uint256[] memory x, uint32 y) returns (address, uint256)",
706 "function foo(address[] memory, bytes memory) returns (bytes memory)",
707 "function bar(uint256[] memory x)",
708 "function bar()",
709 "bar(uint256[] memory x)(address)",
710 "bar(uint256[] memory x, uint32 y)(address, uint256)",
711 "foo(address[] memory, bytes memory)(bytes memory)",
712 "bar(uint256[] memory x)()",
713 "bar()()",
714 "bar(uint256)",
715 "bar()",
716 ]
717 .iter()
718 .for_each(|x| {
719 AbiParser::default().parse_function(x).unwrap();
720 });
721 }
722
723 #[test]
724 fn can_parse_structs_and_functions() {
725 let abi = &[
726 "struct Demo {bytes x; address payable d;}",
727 "struct Voter { uint weight; bool voted; address delegate; uint vote; }",
728 "event FireEvent(Voter v, NestedVoter2 n)",
729 "function foo(uint256[] memory x) external view returns (address)",
730 "function call(Voter memory voter) returns (address, uint256)",
731 "foo(uint256[] memory x)()",
732 "call(Voter memory voter)(address, uint256)",
733 "struct NestedVoter { Voter voter; bool voted; address delegate; uint vote; }",
734 "struct NestedVoter2 { NestedVoter[] voter; Voter[10] votes; address delegate; uint vote; }",
735 ];
736 parse(abi).unwrap();
737 }
738
739 #[test]
740 fn can_parse_params() {
741 [
742 "address x",
743 "address",
744 "bytes memory y",
745 "bytes memory",
746 "bytes32[] memory",
747 "bytes32[] memory z",
748 ]
749 .iter()
750 .for_each(|x| {
751 AbiParser::default().parse_param(x).unwrap();
752 });
753 }
754
755 #[test]
756 fn can_read_backslashes() {
757 parse(&[
758 "\"function setValue(string)\"",
759 "\"function getValue() external view returns(string)\"",
760 ])
761 .unwrap();
762 }
763
764 #[test]
765 fn can_substitute_structs() {
766 let abi = parse(&[
767 "struct MyStruct {int y; address _addr;}",
768 "event FireEvent(MyStruct m, address indexed newOwner)",
769 ])
770 .unwrap();
771 assert_eq!(
772 abi.events["FireEvent"][0].inputs.clone(),
773 vec![
774 EventParam {
775 name: "m".to_string(),
776 kind: ParamType::Tuple(vec![ParamType::Int(256), ParamType::Address]),
777 indexed: false
778 },
779 EventParam {
780 name: "newOwner".to_string(),
781 kind: ParamType::Address,
782 indexed: true
783 },
784 ]
785 );
786 }
787
788 #[test]
789 fn can_substitute_array_structs() {
790 let abi = parse(&[
791 "struct MyStruct {int y; address _addr;}",
792 "event FireEvent(MyStruct[] m, MyStruct[10] m2)",
793 ])
794 .unwrap();
795
796 assert_eq!(
797 abi.events["FireEvent"][0].inputs.clone(),
798 vec![
799 EventParam {
800 name: "m".to_string(),
801 kind: ParamType::Array(Box::new(ParamType::Tuple(vec![
802 ParamType::Int(256),
803 ParamType::Address
804 ]))),
805 indexed: false
806 },
807 EventParam {
808 name: "m2".to_string(),
809 kind: ParamType::FixedArray(
810 Box::new(ParamType::Tuple(vec![ParamType::Int(256), ParamType::Address])),
811 10
812 ),
813 indexed: false
814 },
815 ]
816 );
817 }
818
819 #[test]
820 fn can_substitute_nested_array_structs() {
821 let abi = parse(&[
822 "struct MyStruct {int y; address _addr;}",
823 "event FireEvent(MyStruct[] m, MyStructWrapper w)",
824 "struct MyStructWrapper {MyStruct y; int y; address _addr;}",
825 ])
826 .unwrap();
827
828 assert_eq!(
829 abi.events["FireEvent"][0].inputs.clone(),
830 vec![
831 EventParam {
832 name: "m".to_string(),
833 kind: ParamType::Array(Box::new(ParamType::Tuple(vec![
834 ParamType::Int(256),
835 ParamType::Address
836 ]))),
837 indexed: false
838 },
839 EventParam {
840 name: "w".to_string(),
841 kind: ParamType::Tuple(vec![
842 ParamType::Tuple(vec![ParamType::Int(256), ParamType::Address]),
843 ParamType::Int(256),
844 ParamType::Address
845 ]),
846 indexed: false
847 },
848 ]
849 );
850 }
851}