mrluit / evm Goto Github PK
View Code? Open in Web Editor NEWAn ethereum virtual machine (EVM) bytecode decompiler
Home Page: https://www.npmjs.com/package/evm
License: MIT License
An ethereum virtual machine (EVM) bytecode decompiler
Home Page: https://www.npmjs.com/package/evm
License: MIT License
I'm quite new to node; this failed for me:
git clone
npm install
npm run-script build
node example/DAI.js
which gives the error (with node version v10.11.0)
$ node examples/DAI.js
(node:27306) UnhandledPromiseRejectionWarning: TypeError: findOpcode is not a function
at EVM.getOpcodes (/home/zuuuhkrit/MrLuit/evm/lib/EVM.node.js:1711:27)
at EVM.parse (/home/zuuuhkrit/MrLuit/evm/lib/EVM.node.js:1771:28)
at EVM.decompile (/home/zuuuhkrit/MrLuit/evm/lib/EVM.node.js:1789:34)
at /home/zuuuhkrit/MrLuit/evm/examples/DAI.js:8:21
at process._tickCallback (internal/process/next_tick.js:68:7)
(node:27306) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 1)
(node:27306) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
What am I doing incorrectly?
From what I understand, the evm.getFunctions()
call only returns functions that appear in the functionHashes.json
lookup. If the hash is not mapped in this file, it won't be returned.
Assuming the code is able to distinguish and parse out function hashes contained in a contract's bytecode without using the mapping file, could we add a function to return all function hashes in a contract? Maybe something like getFunctionHashes(): which returns `{'functionHash': 'functionSignature'}? (functionSignature would be null if couldn't be mapped)
If the mapping lookup is necessary for extracting the functions, how about adding an optional parameter to evm.getFunctions()
for additional function hash -> signature mappings to check for in addition to the mapping file?
If install evm
globally everything works well. But if I have it in package.json and thus package-lock.json..then when I run the program I get:
TypeError: e.replace is not a function
node_modules/evm/lib/EVM.node.js:1:10271397
Any help is much appreciated!
CHAINID
opcode at 0x46
, which pops 0 stack arguments, and pushes the current chain ID onto the stack (256-bit value).SELFBALANCE
opcode at 0x47
, which pops 0 stack arguments, and pushes the balance of the current address onto the stack.(node:3067) UnhandledPromiseRejectionWarning: RangeError: Maximum BigInt size exceeded
at eval (eval at <anonymous> (/tmp/test/node_modules/evm/lib/EVM.node.js:1:12359), <anonymous>:1:9)
at NativeBigInt.pow (/tmp/test/node_modules/evm/lib/EVM.node.js:1:12653)
at Object.d.default [as EXP] (/tmp/test/node_modules/evm/lib/EVM.node.js:1:10281826)
at g.parse (/tmp/test/node_modules/evm/lib/EVM.node.js:1:10273112)
at Object.d.default [as JUMPI] (/tmp/test/node_modules/evm/lib/EVM.node.js:1:6408475)
at g.parse (/tmp/test/node_modules/evm/lib/EVM.node.js:1:10273112)
at Object.d.default [as JUMPI] (/tmp/test/node_modules/evm/lib/EVM.node.js:1:6408475)
at g.parse (/tmp/test/node_modules/evm/lib/EVM.node.js:1:10273112)
at Object.d.default [as JUMPI] (/tmp/test/node_modules/evm/lib/EVM.node.js:1:6408517)
at g.parse (/tmp/test/node_modules/evm/lib/EVM.node.js:1:10273112)
at Object.d.default [as JUMPI] (/tmp/test/node_modules/evm/lib/EVM.node.js:1:6408475)
at g.parse (/tmp/test/node_modules/evm/lib/EVM.node.js:1:10273112)
at g.decompile (/tmp/test/node_modules/evm/lib/EVM.node.js:1:10273172)
at web3.eth.getCode.then.code (/tmp/test/index.js:9:21)
at process._tickCallback (internal/process/next_tick.js:68:7)
To reproduce:
const { EVM } = require("evm");
const Web3 = require('web3');
const web3 = new Web3(new Web3.providers.HttpProvider("https://goerli.prylabs.net"));
web3.eth.getCode("0xB880162F8b188E9D7b075081f6E38fc3657ae10e").then(code => { /* ETH2 deposit contract */
const evm = new EVM(code);
console.log(evm.getFunctions()); /* Get functions */
console.log(evm.getEvents()); /* Get events */
console.log(evm.decompile()); /* Decompile bytecode */
});
I've been using your getOpcodes()
function to extract all the method hashes for a contrac's bytecode, and it seems like it's missing one of the methods. You can see the details in an issue I posted in another repo that is actually a fork of yours, but is using some different logic under the hood: acuarica/evm#49
At the end of each Solidity generated bytecode there is a 53 bytes metadata. This package should just strip it. Otherwise - it shows some invalid opcodes and jump destinations.
Getting an "1828116085 is too large for shifting" for certain contracts like https://etherscan.io/bytecode-decompiler?a=0xd43FF5612420c8bcc6316DCc15FEDfb4b791df32
I want to add functionality to this package and turn this into a plugin for hardhat, and the evm library works fine when imported, but I am unable to run "yarn install" due to some issues with scrypt in the outdated web3 package, and am unable to run "yarn build" after updating the web3 package due to some issues with typescript in webpack.
Is there any configuration (version of npm) for which building this works? Otherwise I plan to update every package and try to get the build working.
evm: v0.2.0
node: v11.14.0
There is a Transfer event defined on this contract but not return by the getEvents method of EVM
https://etherscan.io/address/0x5d00d312e171be5342067c09bae883f9bcb2003b#code
event Transfer(address indexed _from, address indexed _to, uint256 indexed _tokenId)
Reproduce:
const code = await web3.eth.getCode('0x5d00d312e171be5342067c09bae883f9bcb2003b');
const evm = new EVM(code);
const events = evm.getEvents();
console.log(events);
Expected:
[ 'Transfer(address,address,uint256)', 'Approval(address,address,uint256)', 'ApprovalForAll(address,address,bool)' ]
Actual:
[ 'Approval(address,address,uint256)', 'ApprovalForAll(address,address,bool)' ]
There is a bug in the way the mapping names are used. Given the following contract;
pragma solidity ^0.4.24;
contract Storage {
mapping (address => uint) public myFirstArray123;
mapping (address => uint) public mySecondArray;
}
Note that both functions refer to the same mapping.
This compiles to 60806040526004361060485763ffffffff7c010000000000000000000000000000000000000000000000000000000060003504166357092fea8114604d57806390f1f82d14608a575b600080fd5b348015605857600080fd5b50607873ffffffffffffffffffffffffffffffffffffffff6004351660b5565b60408051918252519081900360200190f35b348015609557600080fd5b50607873ffffffffffffffffffffffffffffffffffffffff6004351660c7565b60016020526000908152604090205481565b600060208190529081526040902054815600a165627a7a723058208d63c3e798dc9103a25dc8a216e21a6f924b5c584f8eb37ad4d0a8f5cd59bfd20029.
This will decompile as
mapping (unknown => unknown) mapping1;
mapping (unknown => unknown) mapping2;
function 57092fea() public view {
return(mapping1[_arg0]);
}
function 90f1f82d() public view {
return(mapping1[_arg0]);
}
The public getter functions refer now to the same mapping, although there are two mappings.
This happens becase the SLOAD
instruction will create a MappingLoad
using count = Object.keys(state.mappings).indexOf(mappingLocation.toString())
.
When 57092fea is decompiled, it will point to mySecondArray
, which is the only hence first mapping, so it has count=1
and will print (incorrectly) as mapping1
.
When 90f1f82d is decompiled, it will point to myFirstArray123
, which has a lower storage index, so it's the first mapping with count=1
and will print as mapping1
.
I fixed it locally by not using a count
variable but storing the mappingLocation
, and using that in the MappingLoad.toString()
function to construct a proper name. This seems to solve the issue. Are you open to a pull request?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.