evmole icon indicating copy to clipboard operation
evmole copied to clipboard

Add function_arguments_typed to return alloy Vec<DynSolType>

Open wtdcode opened this issue 1 year ago • 1 comments

As title, this adds a new function function_arguments_typed to return Vec<DynSolType>, which makes it much easier to use because parsing string returned by function_arguments is really a pain.

I ran the benchmark locally, and I didn't notice obvious performance regression. I compared the new implementation against evmole-py and no errors are found.

dataset largest1k (1000 contracts, 24427 functions), evmole-rs:
  time: 1.5s
  bad:  0 functions 0.00%
  good: 24427 functions (100.00%)
  errors:
dataset random50k (50000 contracts, 1171102 functions), evmole-rs:
  time: 51.7s
  bad:  0 functions 0.00%
  good: 1171102 functions (100.00%)
  errors:
dataset vyper (780 contracts, 21244 functions), evmole-rs:
  time: 1.2s
  bad:  0 functions 0.00%
  good: 21244 functions (100.00%)
  errors:

Note the comparison is based on string so this even doesn't break compatibility.

This PR also includes a few fixes.

wtdcode avatar Jul 04 '24 16:07 wtdcode

Thanks for PR, I like the idea and will take a look after the EthCC week (after 15 July)

cdump avatar Jul 06 '24 20:07 cdump

parsing string returned by function_arguments is really a pain

Wrapping the result in () and extracting Vec<DynSolType> from results looks not so ugly:


use  alloy_dyn_abi::DynSolType;

fn main() {
    let code = hex::decode("6080604052348015600e575f80fd5b50600436106030575f3560e01c80632125b65b146034578063b69ef8a8146044575b5f80fd5b6044603f3660046046565b505050565b005b5f805f606084860312156057575f80fd5b833563ffffffff811681146069575f80fd5b925060208401356001600160a01b03811681146083575f80fd5b915060408401356001600160e01b0381168114609d575f80fd5b80915050925092509256").unwrap();

    let a = evmole::function_arguments(&code, &[0x21, 0x25, 0xb6, 0x5b], 0);
    println!("{}", a);

    if let Ok(DynSolType::Tuple(v)) = DynSolType::parse(&format!("({})", &a)) {
        println!("{:?}", v); // type = Vec<DynSolType>
    }
}
uint32,address,uint224
[Uint(32), Address, Uint(224)]

cdump avatar Aug 24 '24 05:08 cdump

parsing string returned by function_arguments is really a pain

Wrapping the result in () and extracting Vec<DynSolType> from results looks not so ugly:

use  alloy_dyn_abi::DynSolType;

fn main() {
    let code = hex::decode("6080604052348015600e575f80fd5b50600436106030575f3560e01c80632125b65b146034578063b69ef8a8146044575b5f80fd5b6044603f3660046046565b505050565b005b5f805f606084860312156057575f80fd5b833563ffffffff811681146069575f80fd5b925060208401356001600160a01b03811681146083575f80fd5b915060408401356001600160e01b0381168114609d575f80fd5b80915050925092509256").unwrap();

    let a = evmole::function_arguments(&code, &[0x21, 0x25, 0xb6, 0x5b], 0);
    println!("{}", a);

    if let Ok(DynSolType::Tuple(v)) = DynSolType::parse(&format!("({})", &a)) {
        println!("{:?}", v); // type = Vec<DynSolType>
    }
}
uint32,address,uint224
[Uint(32), Address, Uint(224)]

This doesn’t work for certain types string returned by evmole.

wtdcode avatar Aug 24 '24 05:08 wtdcode

Do you have any examples? This is probably a bug inside evmole that I need to fix independently of this PR

cdump avatar Aug 24 '24 05:08 cdump

Do you have any examples? This is probably a bug inside evmole that I need to fix independently of this PR

This is generally related to the nested types, where the string returned by evmole is not accepted by alloy, though the abi is correct by my manual checking. I don't have exact example for that because this happens pretty frequently when I decoded more than 50M onchain contracts across various evm-compatible chains.

wtdcode avatar Aug 24 '24 05:08 wtdcode

I have resolved the conflicts and updated according to reviews. I just forgot this PR =).

wtdcode avatar Aug 24 '24 06:08 wtdcode

Also add a testcase for previous crashing bytecode.

wtdcode avatar Aug 24 '24 06:08 wtdcode

the string returned by evmole is not accepted by alloy

I've tested it on all mainnet contracts and didn't find any errors; that's strange.

cdump avatar Aug 24 '24 08:08 cdump

Merged to master with reverting some code-format changes: https://github.com/cdump/evmole/commit/2ee8495e2ca9a4e5f783379b85f48efc1a7f9245

cdump avatar Aug 24 '24 08:08 cdump

the string returned by evmole is not accepted by alloy

I've tested it on all mainnet contracts and didn't find any errors; that's strange.

I would assume it's due to some updates, either alloy or emvole? I notice this breakage after one cargo update. But anyway, thanks for merging this =).

wtdcode avatar Aug 24 '24 08:08 wtdcode

Merged to master with reverting some code-format changes: 2ee8495

You may want a custom rustfmt style? I just run cargo fmt automatically.

wtdcode avatar Aug 24 '24 08:08 wtdcode

due to some updates, either alloy or emvole

maybe, but anyway function returning Vec<DynSolType> is better

want a custom rustfmt style

I just don't like rustfmt's style for match cases; I find the current version more readable. For other parts, rustfmt is okay. Contributors should use it by default, and I will either roll back the match-case style, find another way to configure it, or convince myself that rustfmt's style is also acceptable.

Thanks for PR :)

cdump avatar Aug 24 '24 08:08 cdump