#css-selectors #evm #arguments #bytecode #contracts #solidity #ethereum

evmole

从以太坊虚拟机 (EVM) 字节码中提取函数选择器和参数

7 个版本

新版本 0.3.8 2024 年 8 月 23 日
0.3.7 2024 年 7 月 26 日
0.3.6 2024 年 6 月 25 日
0.3.3 2024 年 2 月 26 日
0.3.1 2023 年 12 月 24 日

#13 in #evm

Download history 959/week @ 2024-05-03 1126/week @ 2024-05-10 1747/week @ 2024-05-17 1019/week @ 2024-05-24 1402/week @ 2024-05-31 1392/week @ 2024-06-07 1094/week @ 2024-06-14 1113/week @ 2024-06-21 1093/week @ 2024-06-28 1220/week @ 2024-07-05 994/week @ 2024-07-12 1037/week @ 2024-07-19 1880/week @ 2024-07-26 1916/week @ 2024-08-02 1873/week @ 2024-08-09 1140/week @ 2024-08-16

7,121 每月下载量

MIT 许可证

77KB
1.5K SLoC

EVMole

npm Crates.io PyPI license

这个库可以从以太坊虚拟机 (EVM) 字节码中提取 函数选择器 和参数,即使是未验证的合约。

在线尝试

使用方法

JavaScript

$ npm i evmole
import {functionArguments, functionSelectors} from 'evmole'
// Also supported: const e = require('evmole'); e.functionSelectors();

const code = '0x6080604052348015600e575f80fd5b50600436106030575f3560e01c80632125b65b146034578063b69ef8a8146044575b5f80fd5b6044603f3660046046565b505050565b005b5f805f606084860312156057575f80fd5b833563ffffffff811681146069575f80fd5b925060208401356001600160a01b03811681146083575f80fd5b915060408401356001600160e01b0381168114609d575f80fd5b80915050925092509256'
console.log( functionSelectors(code) )
// Output(list): [ '2125b65b', 'b69ef8a8' ]

console.log( functionArguments(code, '2125b65b') )
// Output(str): 'uint32,address,uint224'

Rust

文档可在 docs.rs 上找到

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

println!("{:x?}", evmole::function_selectors(&code, 0));
// Output(Vec<[u8;4]>): [[21, 25, b6, 5b], [b6, 9e, f8, a8]]

println!("{}", evmole::function_arguments(&code, &[0x21, 0x25, 0xb6, 0x5b], 0));
// Output(String): uint32,address,uint224

Python

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

code = '0x6080604052348015600e575f80fd5b50600436106030575f3560e01c80632125b65b146034578063b69ef8a8146044575b5f80fd5b6044603f3660046046565b505050565b005b5f805f606084860312156057575f80fd5b833563ffffffff811681146069575f80fd5b925060208401356001600160a01b03811681146083575f80fd5b915060408401356001600160e01b0381168114609d575f80fd5b80915050925092509256'
print( function_selectors(code) )
# Output(list): ['2125b65b', 'b69ef8a8']

print( function_arguments(code, '2125b65b') )
# Output(str): 'uint32,address,uint224'

Foundry

Foundry 的铸件 使用了 EVMole 的 Rust 实现


$ 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)
...

更多信息请见 示例

基准测试

函数选择器

FP/FN - 假阳性/假阴性 错误;越小越好

数据集 evmole rs · js · py whatsabi sevm evmhound heimdall smpl
largest1k
1000
合约

24427
函数
FP 合约 1 🥈 0 🥇 0 🥇 75 68 95
FN 合约 0 🥇 0 🥇 0 🥇 40 103 9
FP 函数 192 🥈 0 🥇 0 🥇 720 650 749
FN 函数 0 🥇 0 🥇 0 🥇 191 114 12
时间 0.6s · 1.6s · 2.1s 2.9s 34.8s(*) 0.7s 379.5s(*) 1.7s
random50k
50000
合约

1171102
函数
FP 合约 1 🥇 43 1 693 519 4136
FN 合约 9 🥇 11 85 2903 4669 77
FP 函数 3 🥇 51 3 10798 545 14652
FN 函数 10 🥇 12 1759 3538 4943 96
时间 9.8s · 20.2s · 39s 55.9s 1343s(*) 11.5s 9881.1s(*) 47.9s
vyper
780
合约

21244
函数
FP 合约 0 🥇 30 0 19 780 185
FN 合约 0 🥇 780 21 300 780 480
FP 函数 0 🥇 30 0 19 780 197
FN 函数 0 🥇 21244 336 8273 21244 12971
时间 0.4s · 0.8s · 1.2s 2.1s 55.1s(*) 0.4s 29.1s(*) 1.1s

函数参数

错误 - 当至少有一个参数错误时:(uint256,string) != (uint256,bytes)越小越好

数据集 evmole rs · js · py heimdall-rs 简单
largest1k
1000
合约

24427
函数
错误 14.0%,3417 🥇 31.1%, 7603 58.3%, 14242
时间 1.2s · 12.6s · 30.1s 385.6s(*) 0.6s
random50k
50000
合约

1171102
函数
错误 4.5%,52777 🥇 19.4%, 227078 54.9%, 643213
时间 33.7s · 337.7s · 1002.4s 9594.6s(*) 9.6s
vyper
780
合约

21244
函数
错误 49.6%,10544 🥇 100.0%, 21244 56.8%, 12077
时间 0.8s · 8.0s · 16.9s 29.6s(*) 0.5s

有关方法和重现这些结果的命令,请参阅 benchmark/README.md

版本:evmole v0.3.7; whatsabi v0.12.0; sevm v0.6.18; evm-hound-rs v0.1.4; heimdall-rs v0.8.3

(*)sevmheimdall-rs 是完整的反编译器,不仅限于提取函数选择器

工作原理

简而言之:使用自定义的 EVM 执行代码并跟踪 CALLDATA 使用情况。

详细说明:TODO

许可证

MIT

依赖项

~0.4–1.3MB
~26K SLoC