This directory contains API documentation and various examples (web page, nodejs, vite, webpack, parcel, esbuild) demonstrating how to use the EVMole library with its JavaScript (WASM) build in different environments and with various build tools.
The library is built with wasm-pack. To simplify usage, we provide a default entry point with await init(), which should work in all modern browsers and bundlers.
You can load evmole directly in a web page using a script module. Here's how to do it:
<div id="info"></div>
<script type="module">
import { contractInfo } from 'https://cdn.jsdelivr.net/npm/evmole@0.7.0/dist/evmole.mjs';
const bytecode = '0x6080...'; // Replace with actual bytecode
document.getElementById('info').textContent = contractInfo(bytecode, {selectors: true, arguments: true, stateMutability: true});
</script>You can use EVMole with both import and require syntax:
Set target: esnext in vite.config.js to support Top Level Await, required for default EVMole import:
build: {
target: 'esnext'
}After that, import and use EVMole as usual.
If you can't use esnext, see the No Top Level Await section.
Set asyncWebAssembly: true in webpack.config.js:
experiments: {
asyncWebAssembly: true,
}After that, import and use EVMole as usual.
Parcel can't work with Top Level Await, so you need to manually call init after import. See examples with:
- default parcel installation
- example with
"packageExports": trueset in package.json
You can read more about this in parcel resolver documentation
Pass --format=esm and --loader:.wasm=file to esbuild.
Find the full command in package.json
After that, import and use EVMole as usual.
If you can't use Top Level Await, you can import EVMole as:
import init, { contractInfo } from 'evmole/no_tla`
// or: from 'evmole/dist/evmole.js' (supported, but not recommended)After that, you can use it as:
const bytecode = '0x6080...'; // Replace with actual bytecode
async function main() {
await init();
console.log(contractInfo(bytecode, {selectors: true}));
}
main()or
const bytecode = '0x6080...'; // Replace with actual bytecode
init().then() => {
console.log(contractInfo(bytecode, {selectors: true}));
}See full example without Top Level Await in Parcel example
contractInfo(code, args) ⇒ Contract
Analyzes contract bytecode and returns contract information based on specified options.
Kind: global function
Returns: Contract - Analyzed contract information
| Param | Type | Description |
|---|---|---|
| code | string |
Runtime bytecode as a hex string |
| args | Object |
Configuration options for the analysis |
| [args.selectors] | boolean |
When true, includes function selectors in the output |
| [args.arguments] | boolean |
When true, includes function arguments information |
| [args.stateMutability] | boolean |
When true, includes state mutability information for functions |
| [args.storage] | boolean |
When true, includes contract storage layout information |
| [args.disassemble] | boolean |
When true, includes disassembled bytecode |
| [args.basicBlocks] | boolean |
When true, includes basic block analysis |
| [args.controlFlowGraph] | boolean |
When true, includes control flow graph analysis |
Contains the analysis results of a contract
Kind: global typedef
Properties
| Name | Type | Description |
|---|---|---|
| [functions] | Array.<ContractFunction> |
Array of functions found in the contract. Not present if no functions were extracted |
| [storage] | Array.<StorageRecord> |
Array of storage records found in the contract. Not present if storage layout was not extracted |
| [disassembled] | Array.<Array.<(number|string)>> |
Array of bytecode instructions, where each element is [offset, instruction] |
| [basicBlocks] | Array.<Array.<number>> |
Array of basic blocks found in the contract. Not present if basic blocks were not analyzed. |
| [controlFlowGraph] | ControlFlowGraph |
Control flow graph representation. Not present if CFG was not generated. |
Represents a function found in the contract bytecode
Kind: global typedef
Properties
| Name | Type | Description |
|---|---|---|
| selector | string |
Function selector as a 4-byte hex string without '0x' prefix (e.g., 'aabbccdd') |
| bytecodeOffset | number |
Starting byte offset within the EVM bytecode for the function body |
| [arguments] | string |
Function argument types in canonical format (e.g., 'uint256,address[]'). Not present if arguments were not extracted |
| [stateMutability] | string |
Function's state mutability ("pure", "view", "payable", or "nonpayable"). Not present if state mutability were not extracted |
Represents a storage record found in the contract
Kind: global typedef
Properties
| Name | Type | Description |
|---|---|---|
| slot | string |
Storage slot number as a hex string (e.g., '0', '1b') |
| offset | number |
Byte offset within the storage slot (0-31) |
| type | string |
Variable type (e.g., 'uint256', 'mapping(address => uint256)', 'bytes32') |
| reads | Array.<string> |
Array of function selectors that read from this storage location |
| writes | Array.<string> |
Array of function selectors that write to this storage location |
Represents the control flow graph of the contract bytecode
Kind: global typedef
Properties
| Name | Type | Description |
|---|---|---|
| blocks | Array.<Block> |
List of basic blocks in the control flow graph |
Represents a basic block in the control flow graph
Kind: global typedef Properties
| Name | Type | Description |
|---|---|---|
| id | number |
Unique block identifier (CFG key) |
| start | number |
Byte offset where the block's first opcode begins |
| end | number |
Byte offset where the block's last opcode begins |
| type | 'Terminate' | 'Jump' | 'Jumpi' | 'DynamicJump' | 'DynamicJumpi' |
Block type |
| data | DataTerminate | DataJump | DataJumpi | DataDynamicJump | DataDynamicJumpi |
Type Type-specific block data |
Kind: global typedef
Properties
| Name | Type | Description |
|---|---|---|
| success | boolean |
true for normal termination (STOP/RETURN), false for REVERT/INVALID |
Kind: global typedef Properties
| Name | Type | Description |
|---|---|---|
| to | number |
Destination block ID; use Block.start to get the bytecode offset |
Kind: global typedef Properties
| Name | Type | Description |
|---|---|---|
| true_to | number |
Destination block ID if condition is true; use Block.start to get the bytecode offset |
| false_to | number |
Destination block ID if condition is false; use Block.start to get the bytecode offset |
Kind: global typedef Properties
| Name | Type | Description |
|---|---|---|
| to | DynamicJump |
Possible computed jump destinations |
Kind: global typedef Properties
| Name | Type | Description |
|---|---|---|
| true_to | DynamicJump |
Possible computed jump destinations if true |
| false_to | number |
Destination block ID if condition is false; use Block.start to get the bytecode offset |
Represents a dynamic jump destination in the control flow
Kind: global typedef Properties
| Name | Type | Description |
|---|---|---|
| path | Array.<number> |
Path of block IDs leading to this jump |
| [to] | number |
Destination block ID if known; use Block.start to get the bytecode offset. Optional |