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
7,121 每月下载量
77KB
1.5K SLoC
EVMole
这个库可以从以太坊虚拟机 (EVM) 字节码中提取 函数选择器 和参数,即使是未验证的合约。
- JavaScript,Rust 和 Python 实现
- 无外部依赖的整洁代码(py & js)
- 比其他现有工具更快更准确
- 已在 Solidity 和 Vyper 编译合约上测试
使用方法
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
(*):sevm 和 heimdall-rs 是完整的反编译器,不仅限于提取函数选择器
工作原理
简而言之:使用自定义的 EVM 执行代码并跟踪 CALLDATA 使用情况。
详细说明:TODO
许可证
MIT
依赖项
~0.4–1.3MB
~26K SLoC