Skip to content
/ evm2 Public

e=vm² (pronounced evm-squared; the = is silent) is an evm that runs inside evm.

Notifications You must be signed in to change notification settings

hananbeer/evm2

Folders and files

NameName
Last commit message
Last commit date

Latest commit

78dc724 · Sep 28, 2022

History

8 Commits
Sep 28, 2022
Sep 28, 2022
Sep 28, 2022
Sep 28, 2022
Sep 28, 2022
Sep 28, 2022
Sep 28, 2022
Sep 28, 2022
Sep 28, 2022

Repository files navigation

e=vm²

e=vm² (pronounced evm-squared; the = is silent), also spelled evm2, is an evm that runs inside evm.

Yo dawg I heard you like building

Huff - use this!

Added huff implementation:

run_huff.sh and test_huff.sh

Compiling (old method)

evm is a tool that comes with go-ethereum.

evm compile evm.easm

Running (old method)

Use evm run or the provided helper script:

./run.sh 0x<bytecode>

Debugging (old method)

./disas.sh will compile evm2 and then show disassembly so, you can like, do things that help stuff.

Testing

(NOTE: code without a return statement will return evm2's memory)

return 0x33 * 2:

./test_huff.sh 60336002025952
"0000000000000000000000000000000000000000000000000000000000000066"

return [0x00, 0x20, 0x40]:

./test_huff.sh 595952595952595952
"000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000040"

mstore8 & mstore:

./test_huff.sh 6040595360205952
"40000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020"

emit LOG0(abi.encode(uint256(-1), uint256(0))):

(to see logs need to run evm --debug)

# classic evm:
evm --debug --json --code 600019595260406000a0 run

# and for evm2:
evm --debug --json --code `huffc evm.huff --bin-runtime` --input 600019595260406000a0 run

#### LOGS ####
LOG0: 0000000000000000000000007265636569766572 bn=0 txi=0
00000000  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|
00000010  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|
00000020  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
00000030  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|

untested

untested but presumably works:

  • CALL, STATICCALL, DELEGATECALL, CALLCODE
  • CREATE, CREATE2
  • CODESIZE (simply replaced to CALLDATASIZE)
  • CODECOPY (simply replaced to CALLDATACOPY)

TODO

Not yet implemented:

  • SELFDESTRUCT - currently implemented as STOP... (probably should not be implemented at all)

Implemented without virtualization: (will shift all data 32 bytes)

  • GAS (note: can implement HOSTGAS opcode in addition to virtualized GAS but is it useful?)
  • CALLDATASIZE (this would be CODESIZE of the input code)
  • CALLDATACOPY (this would be CODECOPY of the input code)
  • RETURNDATASIZE (supposedly ok)
  • RETURNDATACOPY (supposedly ok)

NOTE: CODESIZE & CODECOPY are simply translated to CALLDATASIZE & CALLDATACOPY.

Fun fact

I used evm to write pure bytecode, I couldn't even use labels for jumps I had to calculate offsets! I wanted to do it in pure solidity or yul; I just couldn't get it to run properly. Solidity has breaking changes every other day especially when it comes to inline assembly. So I just ended up implementing from scratch.

Thanks to The Optimizor by 0x_Beans, by the end of which I was building mental models in pure assembly while typing bytecodes from memory.

About

e=vm² (pronounced evm-squared; the = is silent) is an evm that runs inside evm.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages