MCPcopy Index your code
hub / github.com/cdump/evmole

github.com/cdump/evmole @0.8.5

Chat with this repo
repository ↗ · DeepWiki ↗ · release 0.8.5 ↗ · + Follow
426 symbols 1,017 edges 65 files 77 documented · 18%
What it actually does AI analysis from the code graph — generated when you open this
loading…
README

EVMole

try it online npm Crates.io PyPI Go

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

Key Features

  • Multi-language support: Available as JavaScript, Rust, Python, and Go libraries.
  • High accuracy 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.
  • CBOR metadata: Extracts string-keyed values from a terminal, length-suffixed CBOR map without assuming a particular compiler.

Usage

JavaScript

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

$ npm i evmole
import { contractInfo } from 'evmole'

const code = '0x6080604052348015600e575f80fd5b50600436106030575f3560e01c80632125b65b146034578063b69ef8a8146044575b5f80fd5b6044603f3660046046565b505050565b005b5f805f606084860312156057575f80fd5b833563ffffffff811681146069575f80fd5b925060208401356001600160a01b03811681146083575f80fd5b915060408401356001600160e01b0381168114609d575f80fd5b80915050925092509256'

console.log( contractInfo(code, {selectors:true, arguments:true, stateMutability:true}) )
// {
//   functions: [
//     {
//       selector: '2125b65b',
//       bytecodeOffset: 52,
//       arguments: 'uint32,address,uint224',
//       stateMutability: 'pure'
//     },
//     ...

Rust

Documentation is available on docs.rs

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

println!("{:?}", evmole::contract_info(
    evmole::ContractInfoArgs::new(&code)
        .with_selectors()
        .with_arguments()
        .with_state_mutability()
    )
);
// Contract {
//     functions: Some([
//         Function {
//             selector: [33, 37, 182, 91],
//             bytecode_offset: 52,
//             arguments: Some([Uint(32), Address, Uint(224)]),
//             state_mutability: Some(Pure)
//         },
//         ...

Python

API documentation

$ pip install evmole --upgrade
from evmole import contract_info

code = '0x6080604052348015600e575f80fd5b50600436106030575f3560e01c80632125b65b146034578063b69ef8a8146044575b5f80fd5b6044603f3660046046565b505050565b005b5f805f606084860312156057575f80fd5b833563ffffffff811681146069575f80fd5b925060208401356001600160a01b03811681146083575f80fd5b915060408401356001600160e01b0381168114609d575f80fd5b80915050925092509256'

print( contract_info(code, selectors=True, arguments=True, state_mutability=True) )
# Contract(
#     functions=[
#     Function(
#             selector=2125b65b,
#             bytecode_offset=52,
#             arguments=uint32,address,uint224,
#             state_mutability=pure),
#     ...

Go

API documentation

$ go get github.com/cdump/evmole/go
package main

import (
    "context"
    "encoding/hex"
    "fmt"

    "github.com/cdump/evmole/go"
)

func main() {
    code, _ := hex.DecodeString("6080604052348015600e575f80fd5b50600436106030575f3560e01c80632125b65b146034578063b69ef8a8146044575b5f80fd5b6044603f3660046046565b505050565b005b5f805f606084860312156057575f80fd5b833563ffffffff811681146069575f80fd5b925060208401356001600160a01b03811681146083575f80fd5b915060408401356001600160e01b0381168114609d575f80fd5b80915050925092509256")

    info, _ := evmole.ContractInfo(context.Background(), code, evmole.Options{
        Selectors:       true,
        Arguments:       true,
        StateMutability: true,
    })

    for _, fn := range info.Functions {
        fmt.Printf("%s: %s @ %d\n", fn.Selector, *fn.Arguments, fn.BytecodeOffset)
    }
    // 2125b65b: uint32,address,uint224 @ 52
    // b69ef8a8:  @ 68
}

Foundry

Foundry's cast uses the Rust implementation of EVMole


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

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

Benchmark

function selectors

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

Dataset evmole rs · js · py · go whatsabi sevm evmhound heimdall
largest1k 1000 addresses 24427 functions FP addrs 1 🥈 0 🥇 0 🥇 75 18
FN addrs 0 🥇 0 🥇 0 🥇 40 103
FP funcs 192 🥈 0 🥇 0 🥇 720 600
FN funcs 0 🥇 0 🥇 0 🥇 191 114
Time 18ms · 0.2s · 22ms · 69ms 2.3s 30s(*) 56ms 371s(*)
random50k 50000 addresses 1171102 functions FP addrs 1 🥇 43 1 693 3
FN addrs 9 🥇 11 10 2903 4669
FP funcs 3 🥇 51 3 10798 29
FN funcs 10 🥇 12 11 3538 4943
Time 0.5s · 3.1s · 0.6s · 3.1s 30s 440s(*) 1.6s 8684s(*)
vyper 780 addresses 21244 functions FP addrs 0 🥇 30 0 19 0
FN addrs 0 🥇 780 0 300 780
FP funcs 0 🥇 30 0 19 0
FN funcs 0 🥇 21244 0 8273 21244
Time 9ms · 99ms · 11ms · 42ms 2.0s 34s(*) 26ms 28s(*)

function arguments

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

Dataset evmole rs · js · py · go heimdall
largest1k 24427 functions Errors 14.0% 🥇 3410 31.1% 7603
Time 0.6s · 1.3s · 0.7s · 1.8s 370s(*)
random50k 1171102 functions Errors 4.5% 🥇 52664 19.4% 227077
Time 16s · 31s · 20s · 48s 8579s(*)
vyper 21244 functions Errors 46.7% 🥇 9914 100.0% 21244
Time 0.5s · 1.1s · 0.6s · 1.8s 29s(*)

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 · go whatsabi sevm heimdall
largest1k 24427 functions Errors 0.0% 🥇 0 68.1% 16623 2.1% 501 25.7% 6268
Errors strict 18.6% 🥇 4549 79.4% 19393 59.0% 14417 54.8% 13386
Time 10s · 9.7s · 9.7s · 25s 2.5s 27s(*) 371s(*)
random50k 1160861 functions Errors 0.0% 🥇 44 30.2% 351060 0.3% 3370 11.5% 133471
Errors strict 6.8% 🥇 78359 58.2% 675111 55.7% 646831 27.6% 320264
Time 201s · 184s · 200s · 427s 51s 2261s(*) 8334s(*)
vyper 21166 functions Errors 0.5% 🥇 110 100.0% 21166 76.3% 16150 100.0% 21166
Errors strict 4.0% 🥇 850 100.0% 21166 90.2% 19092 100.0% 21166
Time 11s · 8.7s · 10s · 22s 1.8s 35s(*) 29s(*)

Control Flow Graph

False Negatives - Valid blocks possibly incorrectly marked unreachable by CFG analysis. Lower count usually indicates better precision.

evmole rs · js · py · go ethersolve evm-cfg sevm heimdall-rs evm

Extension points exported contracts — how you extend this code

CallData (Interface)
(no doc) [5 implementers]
src/evm/calldata.rs
CallDataLabel (Interface)
(no doc) [2 implementers]
src/evm/calldata.rs

Core symbols most depended-on inside this repo

push
called by 65
src/evm/stack.rs
pop
called by 65
src/evm/stack.rs
get
called by 58
src/storage/mod.rs
len
called by 48
src/evm/vm.rs
peek_mut
called by 45
src/evm/stack.rs
store
called by 25
src/evm/memory.rs
bop
called by 21
src/evm/vm.rs
load
called by 17
src/evm/memory.rs

Shape

Function 187
Method 134
Class 62
Struct 23
Enum 17
Interface 2
TypeAlias 1

Languages

Rust73%
Go13%
Python8%
Java4%
TypeScript2%

Modules by API surface

src/storage/mod.rs37 symbols
go/types.go33 symbols
benchmark/compare.py24 symbols
src/evm/memory.rs22 symbols
src/evm/calldata.rs20 symbols
src/interface_js.rs17 symbols
src/evm/vm.rs17 symbols
src/metadata.rs16 symbols
src/interface_py.rs15 symbols
src/arguments/mod.rs15 symbols
src/control_flow_graph/resolver.rs14 symbols
src/evm/stack.rs13 symbols

For agents

$ claude mcp add evmole \
  -- python -m otcore.mcp_server <graph>

⬇ download graph artifact