Extracts function selectors and arguments from EVM bytecode
Project description
EVMole
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
$ 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 (nonpayable
≠ view
). 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
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distributions
Hashes for evmole-0.5.1-cp312-none-win_amd64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | b61b40f5b9fd677ba50c9a22297137eab1833a563714583b7c798dd5a2bcd136 |
|
MD5 | d359cab47e57bcb4a83776dc2ae61606 |
|
BLAKE2b-256 | 5069b4133a466ec3f66de72f7a8f9311f7137a45ba9af980f6549a1b3bb14cd6 |
Hashes for evmole-0.5.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 4d2fb92c9883e73bd9b8c7dffa249214ab39dc556d6ff4fde3d7f76ed2ffee50 |
|
MD5 | 6d082a2e023bcefcf46635d152d61b11 |
|
BLAKE2b-256 | 17dc8a3f8802a3063e6fcef803d3876642f7dd39043e7a014e54e2ae5929cb5e |
Hashes for evmole-0.5.1-cp312-cp312-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 3b3834aa3f93754643522089b095331a97513074f5f303beda113d18e955d6c0 |
|
MD5 | be2bf5db9b55cc454a124d63811a7318 |
|
BLAKE2b-256 | 2fcfa44cd71e213ebb1393f6af8138f65e7a396323bd909540b7d5e82a277bfe |
Hashes for evmole-0.5.1-cp311-none-win_amd64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | f79d9fb739762c7fc6380af788ed09ace537e4a51f499f70a3bec9ba95b9c01e |
|
MD5 | d7bd6c75df06d7630f97b5e33fb890a4 |
|
BLAKE2b-256 | 6e6fdf9982fb331d04ea57f5a18b948b0c5dab55b59454d3c962d1e1c4b0ec16 |
Hashes for evmole-0.5.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | baf29d6fcc2e27a6d0f8aa3f042c3b7fbaca1c6599bc21551e468a2d1e0eaf90 |
|
MD5 | 3164f4c0a1d204d2f095e4486a17ee1d |
|
BLAKE2b-256 | f7c10d8ff398a3b0e5fbdd6b436c44ebc8f7fdd0fe5ad14ff93a9bf01f1e987b |
Hashes for evmole-0.5.1-cp311-cp311-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 7af0cbed311adb3048d4e1f4dbe3bdbf4bde85078a66d699f841c13519194562 |
|
MD5 | 2878a6736b11ebd82d6234403468c637 |
|
BLAKE2b-256 | 135ede737f1f3bc2beb2ec89abf9de8bac57376c686a702ed3ec2afce8c193a3 |
Hashes for evmole-0.5.1-cp310-none-win_amd64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | d6c59551c53f24cf6107e511c37f07e34637592d069555580df0151c20399cca |
|
MD5 | f96cceafd611b68a81de5ffd731b0fa3 |
|
BLAKE2b-256 | e314dd6ff479f4f8f5fd997e09c6f493c5c9cc92423ef3be60aeb4f50cb43f58 |
Hashes for evmole-0.5.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | d4f41f1d0bcd6b3479c4305cf78b60c2359a4f52abd91b654c2af93cebbb3393 |
|
MD5 | 35ee003af932d02c0a6d8a8dc75f0621 |
|
BLAKE2b-256 | 3f22414c127fe5ceeba829e0f0e84e1ed622d4b680df9e06cc3d08f418cd001a |
Hashes for evmole-0.5.1-cp310-cp310-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 2eb324d6b08ad0749b976e209d20820a5877494029e9f07086d905796f2e8b1b |
|
MD5 | 050afea2e76bee61d1fa70e0fbb05abc |
|
BLAKE2b-256 | d70fb3d55c5904672d9621ef5cfafad179972d14e5823f7b08a69c748126795d |
Hashes for evmole-0.5.1-cp39-none-win_amd64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 4f351d79ce4ad0639ee3a0c82f97c599625ee079010e1fc33cafe84656f2cce0 |
|
MD5 | f47cacc7e8db008eaccb36907b0034ad |
|
BLAKE2b-256 | 42c886677d79360c8d2aed1496f03051bac6f157e483ae7de1035914f98905ba |
Hashes for evmole-0.5.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 0842174ee8e76bd36a8a041130fab26df636dff5158a33a236ba0407e3f36b7c |
|
MD5 | 151a36e0c82776d96f1ee2da64055300 |
|
BLAKE2b-256 | de4d6242cda7acde278327513a44d1cd13d2a4532a9906b508744af95ac92252 |
Hashes for evmole-0.5.1-cp39-cp39-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | ed04470352f771c7c8fda0cdbf1e5557fd47d04485e071b8d8f0e008917d3c5f |
|
MD5 | 1909f4a35e2cf5cd8bbae64312e1826f |
|
BLAKE2b-256 | 1673d134b10592958dc2999ce2a52faafea489952914ce26073fb660b09b9530 |