Disassembling bytecode into opcodes across different EVM versions

207 views Asked by At

I need to disassemble bytecode into opcodes across different EVM versions, to make it agnostic to the EVM version used during compilation?

As the second best option - is there a disassembler, that allows you to specify the EVM version to use? I did plenty of research online but haven't found anything like this. I'm currently using evmdasm: https://github.com/ethereum/evmdasm

But it was not updated for a long time, so, as an example of the problem - with the release of Shanghai, and the introduction of PUSH0, for contracts, compiled with Shanghai EVM version I have opcode UNKNOWN_0x5f(basically unrecognized opcode 0x5f), while same operation in contract compiled using Paris version, will look like PUSH1 0x00.

Unification example:
Pushing 0, to stack in contract, compiled, using paris evm version, will look like PUSH1 0x00.
If you compile the same contract, using shanghai evm version, it'll look like PUSH0.
What I want is for the disassembler to make those opcodes look the same.
In this specific case it is easily achievable by doing, something like: decompiled_code.replace('PUSH0', 'PUSH1 0x00') to cast to paris implementation.

In other words:
decompile(x_shanghai_compiled) == decompile(x_paris_deployed) == decompile(x_other_evm_compiled)

2

There are 2 answers

0
Stas Buzuluk On BEST ANSWER

For anyone interested. I found an existing package, that allows you to select evm version to use during disassembling:
https://github.com/crytic/pyevmasm

This package also contains a nice changelog of EVM versions in their tests, which you can use to make unifications, in places it is possible :)

4
Aleksei Potapkin On

You can try the Dedaub disassembler; it's pretty good and well-maintained.

https://library.dedaub.com/decompile