evm-selector-extractor 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +156 -0
- package/dist/cjs/index.js +127 -0
- package/dist/esm/index.js +123 -0
- package/dist/types/index.d.ts +54 -0
- package/package.json +58 -0
package/README.md
ADDED
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
# evm-selector-extractor
|
|
2
|
+
|
|
3
|
+
[](https://www.npmjs.com/package/evm-selector-extractor)
|
|
4
|
+
[](https://www.npmjs.com/package/evm-selector-extractor)
|
|
5
|
+
[](https://github.com/snipe-dev/evm-selector-extractor)
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
Lightweight Ethereum Virtual Machine (EVM) bytecode selector extractor.
|
|
9
|
+
|
|
10
|
+
- Zero dependencies
|
|
11
|
+
- Works in Node.js and Browser
|
|
12
|
+
- ESM + CommonJS compatible
|
|
13
|
+
- Extracts `PUSH4` function selectors directly from raw bytecode
|
|
14
|
+
|
|
15
|
+
------------------------------------------------------------------------
|
|
16
|
+
|
|
17
|
+
## Installation
|
|
18
|
+
|
|
19
|
+
``` bash
|
|
20
|
+
npm install evm-selector-extractor
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
------------------------------------------------------------------------
|
|
24
|
+
|
|
25
|
+
## Usage (Node.js + ethers v6)
|
|
26
|
+
|
|
27
|
+
This example:
|
|
28
|
+
|
|
29
|
+
- Creates a provider
|
|
30
|
+
- Fetches bytecode of PEPE (ERC-20)
|
|
31
|
+
- Extracts function selectors
|
|
32
|
+
- Prints them to console
|
|
33
|
+
|
|
34
|
+
``` ts
|
|
35
|
+
import { JsonRpcProvider } from "ethers";
|
|
36
|
+
import { EVM } from "evm-selector-extractor";
|
|
37
|
+
|
|
38
|
+
const provider = new JsonRpcProvider("https://ethereum-rpc.publicnode.com");
|
|
39
|
+
|
|
40
|
+
const address = "0x6982508145454ce325ddbe47a25d4ec3d2311933"; // PEPE ERC-20
|
|
41
|
+
|
|
42
|
+
async function main() {
|
|
43
|
+
const bytecode = await provider.getCode(address);
|
|
44
|
+
|
|
45
|
+
const evm = new EVM(bytecode);
|
|
46
|
+
const selectors = evm.getSelectors();
|
|
47
|
+
|
|
48
|
+
console.log("Extracted selectors:");
|
|
49
|
+
console.log(selectors);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
main();
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
------------------------------------------------------------------------
|
|
56
|
+
|
|
57
|
+
## Usage (CommonJS)
|
|
58
|
+
|
|
59
|
+
``` js
|
|
60
|
+
const { JsonRpcProvider } = require("ethers");
|
|
61
|
+
const { EVM } = require("evm-selector-extractor");
|
|
62
|
+
|
|
63
|
+
const provider = new JsonRpcProvider("https://ethereum-rpc.publicnode.com");
|
|
64
|
+
|
|
65
|
+
async function main() {
|
|
66
|
+
const bytecode = await provider.getCode(
|
|
67
|
+
"0x6982508145454ce325ddbe47a25d4ec3d2311933"
|
|
68
|
+
);
|
|
69
|
+
|
|
70
|
+
const evm = new EVM(bytecode);
|
|
71
|
+
console.log(evm.getSelectors());
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
main();
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
------------------------------------------------------------------------
|
|
78
|
+
|
|
79
|
+
## Browser Example
|
|
80
|
+
|
|
81
|
+
``` ts
|
|
82
|
+
import { EVM } from "evm-selector-extractor";
|
|
83
|
+
|
|
84
|
+
const bytecode = "0x63a9059cbb...";
|
|
85
|
+
const evm = new EVM(bytecode);
|
|
86
|
+
|
|
87
|
+
console.log(evm.getSelectors());
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
No Node.js APIs are used internally. The library relies only on
|
|
91
|
+
`Uint8Array`.
|
|
92
|
+
|
|
93
|
+
------------------------------------------------------------------------
|
|
94
|
+
|
|
95
|
+
## API
|
|
96
|
+
|
|
97
|
+
### new EVM(bytecode: string)
|
|
98
|
+
|
|
99
|
+
Creates an EVM bytecode parser instance.
|
|
100
|
+
|
|
101
|
+
- Accepts hex string with or without `0x`
|
|
102
|
+
- Throws if invalid hex
|
|
103
|
+
|
|
104
|
+
------------------------------------------------------------------------
|
|
105
|
+
|
|
106
|
+
### getOpcodes(): EvmOpcode\[\]
|
|
107
|
+
|
|
108
|
+
Returns parsed opcode list.
|
|
109
|
+
|
|
110
|
+
``` ts
|
|
111
|
+
interface EvmOpcode {
|
|
112
|
+
name: string;
|
|
113
|
+
opcode: number;
|
|
114
|
+
pc: number;
|
|
115
|
+
pushData?: Uint8Array;
|
|
116
|
+
}
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
------------------------------------------------------------------------
|
|
120
|
+
|
|
121
|
+
### getSelectors(): string\[\]
|
|
122
|
+
|
|
123
|
+
Extracts unique `PUSH4` selectors.
|
|
124
|
+
|
|
125
|
+
Returns:
|
|
126
|
+
|
|
127
|
+
``` ts
|
|
128
|
+
string[] // e.g. ["0xa9059cbb", "0x095ea7b3"]
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
Hidden internal selectors are automatically filtered.
|
|
132
|
+
|
|
133
|
+
------------------------------------------------------------------------
|
|
134
|
+
|
|
135
|
+
## Why not use ethereum.js / ethers ABI parsing?
|
|
136
|
+
|
|
137
|
+
This library:
|
|
138
|
+
|
|
139
|
+
- Does not require ABI
|
|
140
|
+
- Does not depend on heavy EVM stacks
|
|
141
|
+
- Works directly on raw bytecode
|
|
142
|
+
- Designed for lightweight analysis tools and browser environments
|
|
143
|
+
|
|
144
|
+
------------------------------------------------------------------------
|
|
145
|
+
|
|
146
|
+
## Build
|
|
147
|
+
|
|
148
|
+
``` bash
|
|
149
|
+
npm run build
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
------------------------------------------------------------------------
|
|
153
|
+
|
|
154
|
+
## Repository
|
|
155
|
+
|
|
156
|
+
https://github.com/snipe-dev/evm-selector-extractor
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.EVM = void 0;
|
|
4
|
+
/**
|
|
5
|
+
* Lightweight EVM bytecode parser for extracting opcodes and function selectors.
|
|
6
|
+
*
|
|
7
|
+
* Zero dependencies.
|
|
8
|
+
* Works in both Node.js and browser environments.
|
|
9
|
+
*/
|
|
10
|
+
class EVM {
|
|
11
|
+
/**
|
|
12
|
+
* Creates an EVM bytecode parser instance.
|
|
13
|
+
*
|
|
14
|
+
* @param bytecode - Raw EVM bytecode as a hex string (with or without '0x' prefix)
|
|
15
|
+
* @throws {Error} If bytecode is not a valid hex string
|
|
16
|
+
*/
|
|
17
|
+
constructor(bytecode) {
|
|
18
|
+
this.opcodes = [];
|
|
19
|
+
const hexCode = bytecode.startsWith("0x")
|
|
20
|
+
? bytecode.slice(2)
|
|
21
|
+
: bytecode;
|
|
22
|
+
if (!EVM.isValidHex(hexCode)) {
|
|
23
|
+
throw new Error("Invalid hex string provided as bytecode");
|
|
24
|
+
}
|
|
25
|
+
this.code = EVM.hexToBytes(hexCode);
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Parses and returns all opcodes from the bytecode.
|
|
29
|
+
*
|
|
30
|
+
* @returns Array of parsed opcode objects with their metadata
|
|
31
|
+
*/
|
|
32
|
+
getOpcodes() {
|
|
33
|
+
if (this.opcodes.length > 0) {
|
|
34
|
+
return this.opcodes;
|
|
35
|
+
}
|
|
36
|
+
for (let pc = 0; pc < this.code.length; pc++) {
|
|
37
|
+
const opcodeByte = this.code[pc];
|
|
38
|
+
const opcodeInfo = this.getOpcodeInfo(opcodeByte);
|
|
39
|
+
const currentOp = {
|
|
40
|
+
name: opcodeInfo.name,
|
|
41
|
+
opcode: opcodeByte,
|
|
42
|
+
pc: pc
|
|
43
|
+
};
|
|
44
|
+
if (opcodeInfo.name.startsWith("PUSH")) {
|
|
45
|
+
const pushSize = parseInt(opcodeInfo.name.replace("PUSH", ""), 10);
|
|
46
|
+
if (pc + pushSize < this.code.length) {
|
|
47
|
+
currentOp.pushData = this.code.slice(pc + 1, pc + pushSize + 1);
|
|
48
|
+
pc += pushSize;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
this.opcodes.push(currentOp);
|
|
52
|
+
}
|
|
53
|
+
return this.opcodes;
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Extracts unique 4-byte function selectors (PUSH4) from EVM bytecode.
|
|
57
|
+
*
|
|
58
|
+
* @returns Array of unique function selectors as hex strings with `0x` prefix
|
|
59
|
+
*/
|
|
60
|
+
getSelectors() {
|
|
61
|
+
const hidden = new Set([
|
|
62
|
+
"0xffffffff",
|
|
63
|
+
"0x00000000",
|
|
64
|
+
"0x4e487b71",
|
|
65
|
+
"0xad5c4648"
|
|
66
|
+
]);
|
|
67
|
+
const opcodes = this.getOpcodes();
|
|
68
|
+
const push4codes = opcodes
|
|
69
|
+
.filter(op => op.name === "PUSH4" && op.pushData)
|
|
70
|
+
.map(op => EVM.bytesToHex(op.pushData));
|
|
71
|
+
return Array.from(new Set(push4codes))
|
|
72
|
+
.sort()
|
|
73
|
+
.map(hex => "0x" + hex)
|
|
74
|
+
.filter(selector => !hidden.has(selector));
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Maps opcode byte values to their human-readable names.
|
|
78
|
+
*/
|
|
79
|
+
getOpcodeInfo(opcode) {
|
|
80
|
+
const opcodeMap = {
|
|
81
|
+
0x60: "PUSH1", 0x61: "PUSH2", 0x62: "PUSH3", 0x63: "PUSH4",
|
|
82
|
+
0x64: "PUSH5", 0x65: "PUSH6", 0x66: "PUSH7", 0x67: "PUSH8",
|
|
83
|
+
0x68: "PUSH9", 0x69: "PUSH10", 0x6A: "PUSH11", 0x6B: "PUSH12",
|
|
84
|
+
0x6C: "PUSH13", 0x6D: "PUSH14", 0x6E: "PUSH15", 0x6F: "PUSH16",
|
|
85
|
+
0x70: "PUSH17", 0x71: "PUSH18", 0x72: "PUSH19", 0x73: "PUSH20",
|
|
86
|
+
0x74: "PUSH21", 0x75: "PUSH22", 0x76: "PUSH23", 0x77: "PUSH24",
|
|
87
|
+
0x78: "PUSH25", 0x79: "PUSH26", 0x7A: "PUSH27", 0x7B: "PUSH28",
|
|
88
|
+
0x7C: "PUSH29", 0x7D: "PUSH30", 0x7E: "PUSH31", 0x7F: "PUSH32",
|
|
89
|
+
0x00: "STOP", 0x01: "ADD", 0x02: "MUL", 0x03: "SUB",
|
|
90
|
+
0x50: "POP", 0x51: "MLOAD", 0x52: "MSTORE", 0x53: "MSTORE8",
|
|
91
|
+
0x54: "SLOAD", 0x55: "SSTORE", 0x56: "JUMP", 0x57: "JUMPI",
|
|
92
|
+
0x58: "PC", 0x59: "MSIZE", 0x5A: "GAS", 0x5B: "JUMPDEST",
|
|
93
|
+
0xF0: "CREATE", 0xF1: "CALL", 0xF2: "CALLCODE", 0xF3: "RETURN",
|
|
94
|
+
0xF4: "DELEGATECALL", 0xFA: "STATICCALL",
|
|
95
|
+
0xFD: "REVERT", 0xFF: "SELFDESTRUCT"
|
|
96
|
+
};
|
|
97
|
+
return {
|
|
98
|
+
name: opcodeMap[opcode] ||
|
|
99
|
+
`0x${opcode.toString(16).toUpperCase().padStart(2, "0")}`
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Validates hex string.
|
|
104
|
+
*/
|
|
105
|
+
static isValidHex(hex) {
|
|
106
|
+
return hex.length % 2 === 0 && /^[0-9a-fA-F]*$/.test(hex);
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Converts hex string to Uint8Array.
|
|
110
|
+
*/
|
|
111
|
+
static hexToBytes(hex) {
|
|
112
|
+
const bytes = new Uint8Array(hex.length / 2);
|
|
113
|
+
for (let i = 0; i < bytes.length; i++) {
|
|
114
|
+
bytes[i] = parseInt(hex.substring(i * 2, i * 2 + 2), 16);
|
|
115
|
+
}
|
|
116
|
+
return bytes;
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* Converts Uint8Array to hex string (without 0x prefix).
|
|
120
|
+
*/
|
|
121
|
+
static bytesToHex(bytes) {
|
|
122
|
+
return Array.from(bytes)
|
|
123
|
+
.map(b => b.toString(16).padStart(2, "0"))
|
|
124
|
+
.join("");
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
exports.EVM = EVM;
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Lightweight EVM bytecode parser for extracting opcodes and function selectors.
|
|
3
|
+
*
|
|
4
|
+
* Zero dependencies.
|
|
5
|
+
* Works in both Node.js and browser environments.
|
|
6
|
+
*/
|
|
7
|
+
export class EVM {
|
|
8
|
+
/**
|
|
9
|
+
* Creates an EVM bytecode parser instance.
|
|
10
|
+
*
|
|
11
|
+
* @param bytecode - Raw EVM bytecode as a hex string (with or without '0x' prefix)
|
|
12
|
+
* @throws {Error} If bytecode is not a valid hex string
|
|
13
|
+
*/
|
|
14
|
+
constructor(bytecode) {
|
|
15
|
+
this.opcodes = [];
|
|
16
|
+
const hexCode = bytecode.startsWith("0x")
|
|
17
|
+
? bytecode.slice(2)
|
|
18
|
+
: bytecode;
|
|
19
|
+
if (!EVM.isValidHex(hexCode)) {
|
|
20
|
+
throw new Error("Invalid hex string provided as bytecode");
|
|
21
|
+
}
|
|
22
|
+
this.code = EVM.hexToBytes(hexCode);
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Parses and returns all opcodes from the bytecode.
|
|
26
|
+
*
|
|
27
|
+
* @returns Array of parsed opcode objects with their metadata
|
|
28
|
+
*/
|
|
29
|
+
getOpcodes() {
|
|
30
|
+
if (this.opcodes.length > 0) {
|
|
31
|
+
return this.opcodes;
|
|
32
|
+
}
|
|
33
|
+
for (let pc = 0; pc < this.code.length; pc++) {
|
|
34
|
+
const opcodeByte = this.code[pc];
|
|
35
|
+
const opcodeInfo = this.getOpcodeInfo(opcodeByte);
|
|
36
|
+
const currentOp = {
|
|
37
|
+
name: opcodeInfo.name,
|
|
38
|
+
opcode: opcodeByte,
|
|
39
|
+
pc: pc
|
|
40
|
+
};
|
|
41
|
+
if (opcodeInfo.name.startsWith("PUSH")) {
|
|
42
|
+
const pushSize = parseInt(opcodeInfo.name.replace("PUSH", ""), 10);
|
|
43
|
+
if (pc + pushSize < this.code.length) {
|
|
44
|
+
currentOp.pushData = this.code.slice(pc + 1, pc + pushSize + 1);
|
|
45
|
+
pc += pushSize;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
this.opcodes.push(currentOp);
|
|
49
|
+
}
|
|
50
|
+
return this.opcodes;
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Extracts unique 4-byte function selectors (PUSH4) from EVM bytecode.
|
|
54
|
+
*
|
|
55
|
+
* @returns Array of unique function selectors as hex strings with `0x` prefix
|
|
56
|
+
*/
|
|
57
|
+
getSelectors() {
|
|
58
|
+
const hidden = new Set([
|
|
59
|
+
"0xffffffff",
|
|
60
|
+
"0x00000000",
|
|
61
|
+
"0x4e487b71",
|
|
62
|
+
"0xad5c4648"
|
|
63
|
+
]);
|
|
64
|
+
const opcodes = this.getOpcodes();
|
|
65
|
+
const push4codes = opcodes
|
|
66
|
+
.filter(op => op.name === "PUSH4" && op.pushData)
|
|
67
|
+
.map(op => EVM.bytesToHex(op.pushData));
|
|
68
|
+
return Array.from(new Set(push4codes))
|
|
69
|
+
.sort()
|
|
70
|
+
.map(hex => "0x" + hex)
|
|
71
|
+
.filter(selector => !hidden.has(selector));
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Maps opcode byte values to their human-readable names.
|
|
75
|
+
*/
|
|
76
|
+
getOpcodeInfo(opcode) {
|
|
77
|
+
const opcodeMap = {
|
|
78
|
+
0x60: "PUSH1", 0x61: "PUSH2", 0x62: "PUSH3", 0x63: "PUSH4",
|
|
79
|
+
0x64: "PUSH5", 0x65: "PUSH6", 0x66: "PUSH7", 0x67: "PUSH8",
|
|
80
|
+
0x68: "PUSH9", 0x69: "PUSH10", 0x6A: "PUSH11", 0x6B: "PUSH12",
|
|
81
|
+
0x6C: "PUSH13", 0x6D: "PUSH14", 0x6E: "PUSH15", 0x6F: "PUSH16",
|
|
82
|
+
0x70: "PUSH17", 0x71: "PUSH18", 0x72: "PUSH19", 0x73: "PUSH20",
|
|
83
|
+
0x74: "PUSH21", 0x75: "PUSH22", 0x76: "PUSH23", 0x77: "PUSH24",
|
|
84
|
+
0x78: "PUSH25", 0x79: "PUSH26", 0x7A: "PUSH27", 0x7B: "PUSH28",
|
|
85
|
+
0x7C: "PUSH29", 0x7D: "PUSH30", 0x7E: "PUSH31", 0x7F: "PUSH32",
|
|
86
|
+
0x00: "STOP", 0x01: "ADD", 0x02: "MUL", 0x03: "SUB",
|
|
87
|
+
0x50: "POP", 0x51: "MLOAD", 0x52: "MSTORE", 0x53: "MSTORE8",
|
|
88
|
+
0x54: "SLOAD", 0x55: "SSTORE", 0x56: "JUMP", 0x57: "JUMPI",
|
|
89
|
+
0x58: "PC", 0x59: "MSIZE", 0x5A: "GAS", 0x5B: "JUMPDEST",
|
|
90
|
+
0xF0: "CREATE", 0xF1: "CALL", 0xF2: "CALLCODE", 0xF3: "RETURN",
|
|
91
|
+
0xF4: "DELEGATECALL", 0xFA: "STATICCALL",
|
|
92
|
+
0xFD: "REVERT", 0xFF: "SELFDESTRUCT"
|
|
93
|
+
};
|
|
94
|
+
return {
|
|
95
|
+
name: opcodeMap[opcode] ||
|
|
96
|
+
`0x${opcode.toString(16).toUpperCase().padStart(2, "0")}`
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Validates hex string.
|
|
101
|
+
*/
|
|
102
|
+
static isValidHex(hex) {
|
|
103
|
+
return hex.length % 2 === 0 && /^[0-9a-fA-F]*$/.test(hex);
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* Converts hex string to Uint8Array.
|
|
107
|
+
*/
|
|
108
|
+
static hexToBytes(hex) {
|
|
109
|
+
const bytes = new Uint8Array(hex.length / 2);
|
|
110
|
+
for (let i = 0; i < bytes.length; i++) {
|
|
111
|
+
bytes[i] = parseInt(hex.substring(i * 2, i * 2 + 2), 16);
|
|
112
|
+
}
|
|
113
|
+
return bytes;
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* Converts Uint8Array to hex string (without 0x prefix).
|
|
117
|
+
*/
|
|
118
|
+
static bytesToHex(bytes) {
|
|
119
|
+
return Array.from(bytes)
|
|
120
|
+
.map(b => b.toString(16).padStart(2, "0"))
|
|
121
|
+
.join("");
|
|
122
|
+
}
|
|
123
|
+
}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Interface representing an EVM opcode with its metadata
|
|
3
|
+
*/
|
|
4
|
+
export interface EvmOpcode {
|
|
5
|
+
name: string;
|
|
6
|
+
opcode: number;
|
|
7
|
+
pc: number;
|
|
8
|
+
pushData?: Uint8Array;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Lightweight EVM bytecode parser for extracting opcodes and function selectors.
|
|
12
|
+
*
|
|
13
|
+
* Zero dependencies.
|
|
14
|
+
* Works in both Node.js and browser environments.
|
|
15
|
+
*/
|
|
16
|
+
export declare class EVM {
|
|
17
|
+
private readonly code;
|
|
18
|
+
private opcodes;
|
|
19
|
+
/**
|
|
20
|
+
* Creates an EVM bytecode parser instance.
|
|
21
|
+
*
|
|
22
|
+
* @param bytecode - Raw EVM bytecode as a hex string (with or without '0x' prefix)
|
|
23
|
+
* @throws {Error} If bytecode is not a valid hex string
|
|
24
|
+
*/
|
|
25
|
+
constructor(bytecode: string);
|
|
26
|
+
/**
|
|
27
|
+
* Parses and returns all opcodes from the bytecode.
|
|
28
|
+
*
|
|
29
|
+
* @returns Array of parsed opcode objects with their metadata
|
|
30
|
+
*/
|
|
31
|
+
getOpcodes(): EvmOpcode[];
|
|
32
|
+
/**
|
|
33
|
+
* Extracts unique 4-byte function selectors (PUSH4) from EVM bytecode.
|
|
34
|
+
*
|
|
35
|
+
* @returns Array of unique function selectors as hex strings with `0x` prefix
|
|
36
|
+
*/
|
|
37
|
+
getSelectors(): string[];
|
|
38
|
+
/**
|
|
39
|
+
* Maps opcode byte values to their human-readable names.
|
|
40
|
+
*/
|
|
41
|
+
private getOpcodeInfo;
|
|
42
|
+
/**
|
|
43
|
+
* Validates hex string.
|
|
44
|
+
*/
|
|
45
|
+
private static isValidHex;
|
|
46
|
+
/**
|
|
47
|
+
* Converts hex string to Uint8Array.
|
|
48
|
+
*/
|
|
49
|
+
private static hexToBytes;
|
|
50
|
+
/**
|
|
51
|
+
* Converts Uint8Array to hex string (without 0x prefix).
|
|
52
|
+
*/
|
|
53
|
+
private static bytesToHex;
|
|
54
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "evm-selector-extractor",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Lightweight Ethereum Virtual Machine (EVM) bytecode selector extractor (Node + Browser, zero dependencies)",
|
|
5
|
+
"author": "snipe-dev",
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
|
|
8
|
+
"repository": {
|
|
9
|
+
"type": "git",
|
|
10
|
+
"url": "https://github.com/snipe-dev/evm-selector-extractor.git"
|
|
11
|
+
},
|
|
12
|
+
"homepage": "https://github.com/snipe-dev/evm-selector-extractor#readme",
|
|
13
|
+
"bugs": {
|
|
14
|
+
"url": "https://github.com/snipe-dev/evm-selector-extractor/issues"
|
|
15
|
+
},
|
|
16
|
+
|
|
17
|
+
"main": "./dist/cjs/index.js",
|
|
18
|
+
"module": "./dist/esm/index.js",
|
|
19
|
+
"types": "./dist/types/index.d.ts",
|
|
20
|
+
|
|
21
|
+
"exports": {
|
|
22
|
+
".": {
|
|
23
|
+
"import": "./dist/esm/index.js",
|
|
24
|
+
"require": "./dist/cjs/index.js",
|
|
25
|
+
"types": "./dist/types/index.d.ts"
|
|
26
|
+
}
|
|
27
|
+
},
|
|
28
|
+
|
|
29
|
+
"files": [
|
|
30
|
+
"dist"
|
|
31
|
+
],
|
|
32
|
+
|
|
33
|
+
"scripts": {
|
|
34
|
+
"build:esm": "tsc -p tsconfig.esm.json",
|
|
35
|
+
"build:cjs": "tsc -p tsconfig.cjs.json",
|
|
36
|
+
"build": "npm run build:esm && npm run build:cjs",
|
|
37
|
+
"prepublishOnly": "npm run build"
|
|
38
|
+
},
|
|
39
|
+
|
|
40
|
+
"keywords": [
|
|
41
|
+
"ethereum",
|
|
42
|
+
"evm",
|
|
43
|
+
"bytecode",
|
|
44
|
+
"selector",
|
|
45
|
+
"solidity",
|
|
46
|
+
"push4",
|
|
47
|
+
"typescript",
|
|
48
|
+
"decompiler"
|
|
49
|
+
],
|
|
50
|
+
|
|
51
|
+
"engines": {
|
|
52
|
+
"node": ">=16"
|
|
53
|
+
},
|
|
54
|
+
|
|
55
|
+
"devDependencies": {
|
|
56
|
+
"typescript": "^5.0.0"
|
|
57
|
+
}
|
|
58
|
+
}
|