Skip to content

Commit

Permalink
0.2.0 (#1)
Browse files Browse the repository at this point in the history
* Remove experimental feature from README

* Implement mappings

* Fix small issues

* Temporarily disable opcode tests

* Add structs

* Improve variables/events

* Add new example

* 0.2.0

* Add tests

* Small bugfixes
  • Loading branch information
MrLuit authored Jan 14, 2019
1 parent 70f3a87 commit 2f64a4c
Show file tree
Hide file tree
Showing 99 changed files with 1,562 additions and 860 deletions.
1 change: 0 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ An [Ethereum Virtual Machine (EVM)](https://medium.com/@jeff.ethereum/optimising
- **Converting bytecode to opcodes**
- **Reading information like events or functions from either bytecode or tx data**
- **Extracting the [swarm hash](https://github.com/ethereum/wiki/wiki/Swarm-Hash) (if any) from bytecode**
- **Generating ABI from bytecode (EXPERIMENTAL)**

## API

Expand Down
36 changes: 36 additions & 0 deletions examples/tokenTransfer.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
const Web3 = require('web3');
import { Transaction } from '../src/index';
const web3 = new Web3(new Web3.providers.HttpProvider('https://api.mycryptoapi.com/eth'));

(async () => {
const txHashes = [
'0xea0b0b749b9c291f1c933c2dc883b3c9ac30b570f2b0899b18472be5512ee0b8',
'0xfdc2e71e2cd961b04f56d8929fc9fb26692a5b41821d2178eda9e35c2eb2af0b',
'0xf2fda91498ef6f661230646bef977f51b779b3454c64f993e580901ae3d5089f',
'0xbdc3c392fce18c706512ba21a9d00444d349e77d3d48f3259e828aec3ebdb3b7',
'0x9e1d3403efa72f68ffd262e29b1e5662b75dda8ae5faaaa0d1f35dcdf2158b7d',
'0x1e7b2f5ae04b1337b32b9975da098967f06a9487c8907b1aae8de0bedcdbe1c9',
'0x4d8ced3c95407155224fbe1d975d65232f4237bf1ed26a648664c8be25a4138e',
'0xdedff4b8ad80cafe7350f54b73fe764a3366415e4cf38364d419df0ea83f010f',
'0xf153f63dd6b8e08c918c984307d9f68f04fed89118f8610e52cd9adfbd1b6645',
'0xa54656081baa8e76a74d891782e5e523045bd76cb2fd88ad8dafb865636ae56c',
'0xc80682000c727462ac07b64b3de4da43a3635922aa3dd26174fd59f8e8120278'
];

const txs = await Promise.all(
txHashes.map(async (tx: string) => {
const data = await web3.eth.getTransaction(tx);
return data;
})
);

const txData = txs.map((tx: any) => {
const transaction = new Transaction();
transaction.setInput(tx.input);
const functionName = transaction.getFunctionName();
const functionArguments = transaction.getArguments();
return functionName + '(' + functionArguments.join(',') + ')';
});

console.log(txData.join('\n\n'));
})();
34 changes: 32 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

9 changes: 5 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "evm",
"version": "0.1.1",
"version": "0.2.0",
"description": "An ethereum virtual machine (EVM) bytecode decompiler",
"main": "lib/EVM.node.js",
"module": "lib/EVM.js",
Expand Down Expand Up @@ -35,19 +35,19 @@
"bytecode",
"solidity"
],
"dependencies": {
"big-integer": "1.6.40"
},
"dependencies": {},
"devDependencies": {
"@babel/core": "7.2.2",
"@babel/preset-env": "7.2.3",
"@types/chai": "4.1.7",
"@types/ethereumjs-abi": "0.6.1",
"@types/mocha": "5.2.5",
"@types/node": "10.12.18",
"@types/webpack": "4.4.22",
"@types/webpack-merge": "4.1.3",
"@types/webpack-node-externals": "1.6.3",
"awesome-typescript-loader": "5.2.1",
"big-integer": "1.6.40",
"chai": "4.2.0",
"cross-env": "5.2.0",
"ethereumjs-vm": "2.5.0",
Expand All @@ -61,6 +61,7 @@
"tslint": "5.12.0",
"tslint-config-prettier": "1.17.0",
"tslint-microsoft-contrib": "6.0.0",
"tslint-no-unused-expression-chai": "0.1.4",
"typescript": "3.2.2",
"web3": "1.0.0-beta.37",
"webpack": "4.28.3",
Expand Down
43 changes: 29 additions & 14 deletions src/classes/evm.class.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
const findOpcode = require('../../node_modules/ethereumjs-vm/dist/opcodes.js');
import * as functionHashes from '../../data/functionHashes.json';
import * as eventHashes from '../../data/eventHashes.json';
import allOpcodes from '../utils/opcodes';
import stringifyInstructions from '../utils/stringifyInstructions';
import opcodeFunctions from '../utils/opcodes';
import stringifyEvents from '../utils/stringifyEvents';
import stringifyStructs from '../utils/stringifyStructs';
import stringifyMappings from '../utils/stringifyMappings';
import stringifyVariables from '../utils/stringifyVariables';
import stringifyFunctions from '../utils/stringifyFunctions';
import parseEvents from '../utils/parseEvents';
import parseVariables from '../utils/parseVariables';
import Instruction from './instruction.class';
import stringifyInstructions from '../utils/stringifyInstructions';
import Opcode from '../interfaces/opcode.interface';
import Stack from './stack.class';
import Memory from '../interfaces/memory.interface';
import Storage from '../interfaces/storage.interface';
import Mappings from '../interfaces/mappings.interface';
import Jumps from '../interfaces/jumps.interface';

class EVM {
Expand All @@ -23,10 +23,13 @@ class EVM {
storage: Storage;
jumps: Jumps;
code: Buffer;
mappings: Mappings;
mappings: any;
layer: number;
halted: boolean;
functions: any;
variables: any;
events: any;
gasUsed: number;

constructor(code: string | Buffer) {
this.pc = 0;
Expand All @@ -40,6 +43,9 @@ class EVM {
this.layer = 0;
this.halted = false;
this.functions = {};
this.variables = {};
this.events = {};
this.gasUsed = 0;
if (code instanceof Buffer) {
this.code = code;
} else {
Expand All @@ -53,12 +59,14 @@ class EVM {
clone.opcodes = this.opcodes;
clone.stack = this.stack.clone();
clone.memory = { ...this.memory };
//clone.storage = { ...this.storage };
clone.storage = this.storage;
clone.jumps = { ...this.jumps };
clone.mappings = this.mappings;
clone.layer = this.layer + 1;
clone.functions = this.functions;
clone.variables = this.variables;
clone.events = this.events;
clone.gasUsed = this.gasUsed;
return clone;
}

Expand Down Expand Up @@ -138,17 +146,22 @@ class EVM {
this.storage = {};
this.jumps = {};
this.mappings = {};
this.functions = {};
this.variables = {};
this.events = {};
this.gasUsed = 0;
}

parse(): Instruction[] {
parse(): any[] {
if (this.instructions.length === 0) {
const opcodes = this.getOpcodes();
for (this.pc; this.pc < opcodes.length && !this.halted; this.pc++) {
const opcode = opcodes[this.pc];
if (!(opcode.name in allOpcodes)) {
this.gasUsed += opcode.fee;
if (!(opcode.name in opcodeFunctions)) {
throw new Error('Unknown OPCODE: ' + opcode.name);
} else {
(allOpcodes as any)[opcode.name](opcode, this);
(opcodeFunctions as any)[opcode.name](opcode, this);
}
}
}
Expand All @@ -157,15 +170,17 @@ class EVM {

decompile(): string {
const instructionTree = this.parse();
const events = parseEvents(this.getEvents());
const variables = parseVariables(this.storage, this.functions, instructionTree);
const events = stringifyEvents(this.events, this.getEvents());
const structs = stringifyStructs(this.mappings);
const mappings = stringifyMappings(this.mappings);
const variables = stringifyVariables(this.variables);
const functions = Object.keys(this.functions)
.map((functionName: string) =>
stringifyFunctions(functionName, this.functions[functionName])
)
.join('');
const code = stringifyInstructions(instructionTree);
return events + variables + functions + code;
return events + structs + mappings + variables + functions + code;
}
}

Expand Down
38 changes: 0 additions & 38 deletions src/classes/instruction.class.ts

This file was deleted.

2 changes: 1 addition & 1 deletion src/classes/stack.class.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ export default class Stack {
}

swap(secondPosition: number): void {
if (secondPosition < 0 || secondPosition > 15) {
if (secondPosition < 1 || secondPosition > 16) {
throw new Error('Unsupported position for swap operation');
} else if (!(secondPosition in this.elements)) {
throw new Error("Invalid swap operation, provided position wasn't found in stack");
Expand Down
Loading

0 comments on commit 2f64a4c

Please sign in to comment.