alloy-rs / core

High-performance, well-tested & documented core libraries for Ethereum, in Rust
https://alloy.rs
Apache License 2.0
795 stars 156 forks source link

AbiItem parsing from human readable ABI does not allow for state mutibility keywords #681

Closed 0xfourzerofour closed 5 months ago

0xfourzerofour commented 5 months ago

Component

dyn-abi, json-abi

What version of Alloy are you on?

0.1.0

Operating System

macOS (Apple Silicon)

Describe the bug

I am trying to parse the following human readable ABI into an AbitItem (AbitItem::Function to be specific) however when I pass it into the parse function I get the following error.

function balanceOf(address owner) view returns (uint256 balance)
Error: parser error:
balanceOf(address owner) view returns (uint256 balance)

When I remove the state mutability keyword "view" it will not give me the error

0xfourzerofour commented 5 months ago

I have tried using both the following setups but end up with the same result

        let item: AbiItem = data.function_signature.parse()?;
        println!("item {:?}", item);
        let function: Function = data.function_signature.parse()?;
        println!("function {:?}", function);
0xfourzerofour commented 5 months ago

Looking at the implementation of the parser this may be a little harder to do than I thought to make it work for ParseSigTuple<Param>

/// Returns `(name, inputs, outputs, anonymous)`.
#[doc(hidden)]
pub fn parse_signature<'a, const OUT: bool, F: Fn(ParameterSpecifier<'a>) -> T, T>(
    s: &'a str,
    f: F,
) -> Result<(String, Vec<T>, Vec<T>, bool)> {
    trace(
        "signature",
        (
            RootType::parser.map(|x| x.span().into()),
            preceded(space0, tuple_parser(ParameterSpecifier::parser.map(&f))),
            |i: &mut _| {
                if OUT {
                    preceded(
                        (space0, opt(":"), opt("returns"), space0),
                        opt(tuple_parser(ParameterSpecifier::parser.map(&f))),
                    )
                    .parse_next(i)
                    .map(Option::unwrap_or_default)
                } else {
                    Ok(vec![])
                }
            },
            preceded(space0, opt("anonymous").map(|x| x.is_some())),
        ),
    )
    .parse(s)
    .map_err(Error::parser)
}