Skip to main content

Extracts function selectors and arguments from EVM bytecode

Project description

EVMole

try it online npm Crates.io PyPI

EVMole is a powerful library that extracts information from Ethereum Virtual Machine (EVM) bytecode, including function selectors, arguments, and state mutability, even for unverified contracts.

Key Features

  • Multi-language support: Available as JavaScript, Rust, and Python libraries.
  • High accurancy and performance: Outperforms existing tools.
  • Broad compatibility: Tested with both Solidity and Vyper compiled contracts.
  • Lightweight: Clean codebase with minimal external dependencies.
  • Unverified contract analysis: Extracts information even from unverified bytecode.

Usage

JavaScript

API documentation and usage examples (node, vite, webpack, parcel, esbuild)

$ npm i evmole
import { functionSelectors, functionArguments, functionStateMutability } from 'evmole'

const code = '0x6080604052348015600e575f80fd5b50600436106030575f3560e01c80632125b65b146034578063b69ef8a8146044575b5f80fd5b6044603f3660046046565b505050565b005b5f805f606084860312156057575f80fd5b833563ffffffff811681146069575f80fd5b925060208401356001600160a01b03811681146083575f80fd5b915060408401356001600160e01b0381168114609d575f80fd5b80915050925092509256'

console.log(functionSelectors(code));                   // [ '2125b65b', 'b69ef8a8' ]
console.log(functionArguments(code, '2125b65b'));       // 'uint32,address,uint224'
console.log(functionStateMutability(code, '2125b65b')); // 'pure'

Rust

Documentation is available on docs.rs

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

println!("{:x?} | {} | {:?}",
    evmole::function_selectors(&code, 0),
    evmole::function_arguments(&code, &[0x21, 0x25, 0xb6, 0x5b], 0),
    evmole::function_state_mutability(&code, &[0x21, 0x25, 0xb6, 0x5b], 0),
);
// [[21, 25, b6, 5b], [b6, 9e, f8, a8]] | uint32,address,uint224 | Pure

Python

API documentation

$ pip install evmole --upgrade
from evmole import function_selectors, function_arguments, function_state_mutability

code = '0x6080604052348015600e575f80fd5b50600436106030575f3560e01c80632125b65b146034578063b69ef8a8146044575b5f80fd5b6044603f3660046046565b505050565b005b5f805f606084860312156057575f80fd5b833563ffffffff811681146069575f80fd5b925060208401356001600160a01b03811681146083575f80fd5b915060408401356001600160e01b0381168114609d575f80fd5b80915050925092509256'

print(function_selectors(code))                    # ['2125b65b', 'b69ef8a8']
print(function_arguments(code, '2125b65b'))        # uint32,address,uint224
print(function_state_mutability(code, '2125b65b')) # pure

Foundry

Foundy's cast uses the Rust implementation of EVMole

$ cast selectors $(cast code 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2)
0x06fdde03	
0x095ea7b3	address,uint256
0x18160ddd	
0x23b872dd	address,address,uint256
...

$ cast selectors --resolve $(cast code 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2)
0x06fdde03	                       	name()
0x095ea7b3	address,uint256        	approve(address,uint256)
0x18160ddd	                       	totalSupply()
0x23b872dd	address,address,uint256	transferFrom(address,address,uint256)
...

Benchmark

function selectors

FP/FN - False Positive/False Negative errors; smaller is better

Dataset evmole rs · js · py whatsabi sevm evmhound heimdall smpl
largest1k
1000
addresses

24427
functions
FP addrs 1 🥈 0 🥇 0 🥇 75 18 95
FN addrs 0 🥇 0 🥇 0 🥇 40 111 9
FP funcs 192 🥈 0 🥇 0 🥇 720 600 749
FN funcs 0 🥇 0 🥇 0 🥇 191 147 12
Time 0.5s · 0.7s · 0.6s 3.2s 44s(*) 0.5s 341s(*) 1.8s
random50k
50000
addresses

1171102
functions
FP addrs 1 🥇 43 1 693 3 4136
FN addrs 9 🥇 11 10 2903 4708 77
FP funcs 3 🥇 51 3 10798 29 14652
FN funcs 10 🥇 12 11 3538 6098 96
Time 4.5s · 8.5s · 7.8s 54s 2458s(*) 6.1s 8576s(*) 46s
vyper
780
addresses

21244
functions
FP addrs 0 🥇 30 0 19 0 185
FN addrs 0 🥇 780 21 300 780 480
FP funcs 0 🥇 30 0 19 0 197
FN funcs 0 🥇 21244 336 8273 21244 12971
Time 0.4s · 0.6s · 0.4s 2.4s 43s(*) 0.4s 27s(*) 1.1s

function arguments

Errors - when at least 1 argument is incorrect: (uint256,string)(uint256,bytes)

Dataset evmole rs · js · py heimdall smpl
largest1k
24427
functions
Errors 14.0% 🥇
3410
31.1%
7593
58.3%
14242
Time 1.1s · 4.8s · 1.4s 342s(*) 0.7s
random50k
1171102
functions
Errors 4.5% 🥇
52662
19.4%
227612
54.9%
643213
Time 25s · 127 · 32 8544s(*) 9.5s
vyper
21244
functions
Errors 48.5% 🥇
10300
100.0%
21244
56.8%
12077
Time 0.8s · 3.0s · 1.0s 28s(*) 0.6s

function state mutability

Errors - Results are not equal (treating view and pure as equivalent to nonpayable)

Errors strict - Results are strictly unequal (nonpayableview). Some ABIs mark pure/view functions as nonpayable, so not all strict errors indicate real issues.

Dataset evmole rs · js · py whatsabi sevm heimdall smpl
largest1k
24427
functions
Errors 0.0% 🥇
0
68.1%
16623
2.1%
501
25.4%
6201
2.6%
643
Errors strict 18.7% 🥇
4558
79.3%
19370
59.0%
14417
54.9%
13403
60.9%
14864
Time 9.5s · 19s · 9.4s 3.8s 46s(*) 339s(*) 0.7s
random50k
1160861
functions
Errors 0.0% 🥇
35
30.2%
351060
0.3%
3370
11.6%
134195
2.2%
24961
Errors strict 6.7% 🥇
77945
58.1%
674922
55.7%
646831
27.7%
321494
57.7%
670318
Time 214s · 471s · 240s 85s 2331s(*) 8151s(*) 9.4s
vyper
21166
functions
Errors 0.5% 🥇
110
100.0%
21166
77.8%
16462
100.0%
21166
1.8%
390
Errors strict 4.2% 🥇
888
100.0%
21166
91.0%
19253
100.0%
21166
59.6%
12610
Time 10s · 15s · 10s 2.4s 41s(*) 28s(*) 0.6s

See benchmark/README.md for the methodology and commands to reproduce these results

versions: evmole v0.5.1; whatsabi v0.14.1; sevm v0.7.2; evm-hound-rs v0.1.4; heimdall-rs v0.8.4

(*): sevm and heimdall-rs are full decompilers, not limited to extracting function selectors

How it works

Short: Executes code with a custom EVM and traces CALLDATA usage.

Long: TODO

License

MIT

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

evmole-0.5.1.tar.gz (38.6 kB view hashes)

Uploaded Source

Built Distributions

evmole-0.5.1-cp312-none-win_amd64.whl (176.1 kB view hashes)

Uploaded CPython 3.12 Windows x86-64

evmole-0.5.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (315.5 kB view hashes)

Uploaded CPython 3.12 manylinux: glibc 2.17+ x86-64

evmole-0.5.1-cp312-cp312-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl (542.3 kB view hashes)

Uploaded CPython 3.12 macOS 10.12+ universal2 (ARM64, x86-64) macOS 10.12+ x86-64 macOS 11.0+ ARM64

evmole-0.5.1-cp311-none-win_amd64.whl (176.3 kB view hashes)

Uploaded CPython 3.11 Windows x86-64

evmole-0.5.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (315.6 kB view hashes)

Uploaded CPython 3.11 manylinux: glibc 2.17+ x86-64

evmole-0.5.1-cp311-cp311-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl (542.7 kB view hashes)

Uploaded CPython 3.11 macOS 10.12+ universal2 (ARM64, x86-64) macOS 10.12+ x86-64 macOS 11.0+ ARM64

evmole-0.5.1-cp310-none-win_amd64.whl (176.3 kB view hashes)

Uploaded CPython 3.10 Windows x86-64

evmole-0.5.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (315.8 kB view hashes)

Uploaded CPython 3.10 manylinux: glibc 2.17+ x86-64

evmole-0.5.1-cp310-cp310-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl (543.0 kB view hashes)

Uploaded CPython 3.10 macOS 10.12+ universal2 (ARM64, x86-64) macOS 10.12+ x86-64 macOS 11.0+ ARM64

evmole-0.5.1-cp39-none-win_amd64.whl (176.4 kB view hashes)

Uploaded CPython 3.9 Windows x86-64

evmole-0.5.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (316.3 kB view hashes)

Uploaded CPython 3.9 manylinux: glibc 2.17+ x86-64

evmole-0.5.1-cp39-cp39-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl (544.0 kB view hashes)

Uploaded CPython 3.9 macOS 10.12+ universal2 (ARM64, x86-64) macOS 10.12+ x86-64 macOS 11.0+ ARM64

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page