Skip to content
/ tracevm Public

Track the values and addresses of slots (storage variables in Solidity) inside the Ethereum contract, as well as tracking logs (Solidity events).

License

Notifications You must be signed in to change notification settings

ioterw/tracevm

Repository files navigation

TracEVM

This tool is used to track the values and addresses of slots (storage variables in Solidity) inside the Ethereum contract, as well as tracking logs (Solidity events).

  • Partial symbolic execution provides the complete data on how a specific variable or slot address was calculated
  • Suitable for learning about Solidity internals
  • Written in Go

Docker

The easiest way to start using the tool is to use Docker

docker pull ioterw/tracevm

It is needed to copy the sample config from here, and save it as conf.json

Run TracEVM

cat conf.json | docker run --rm -i -p 4334:4334 -p 8545:8545 ioterw/tracevm

Prerequesits

Project includes submodules, therefore it is needed to clone the project this way.

git clone https://github.com/ioterw/tracevm.git
cd tracevm
git submodule update --init

Also, make, git, go and python3 should be preinstalled.

Additionally, Geth prerequisites are required to compile Geth.

Building

It is possible to build TracEVM with such command.

./build.py geth

Running

To open webview on address 127.0.0.1:4334 run the following command.

cd build
./run.py conf.json

TracEVM will be running!

Connecting with Remix

It is expected to have Remix installed.

Choose External HTTP Provider

Connect by default address.

Usage example

Let's imagine we have such contract.

Let's deploy the contract and see the output.

We see that:

  • event type is final_slot, which means that this slot was written at the end of transaction (not reverted).
  • further we see slot offsets (constant - initial slot, mapping - solidity keccak mapping magic, offset - offset from last value)
  • short slot formula, which shows all cryptographic operations which were performed with slot

Also there is a full formula, which computes all needed data from initial initcode (or calldata).

Editing config

{
    "kv": {
        // Possible values for engine:
        // memory: data is stored in memory (root is ignored)
        // leveldb: data is stored in leveldb (root is path for leveldb folders)
        // riak: data is stored in riak (root is riak address)
        // amnesia: data is not stored (root is ignored, past_unknown is switched to true)
        "engine": "memory",
        "root": ""
    },
    "logger": {
        // _short postfix generally counts only cryptographic formulas (sha256, keccak etc.)
        // as significant, other formulas are folded 
        "opcodes_short": ["e0", "e1"],
        // outputs each occurence of TracEVM opcode
        // (probably it is a good idea to try ["e0", "e1"], which are sload and sstore)
        "opcodes": [],
        "final_slots_short": true,
        // outputs final slots which are set at the end of transaction
        "final_slots": true,
        "codes_short": false,
        // outputs code of contracts which is set at the end of transaction
        "codes": false,
        "return_data_short": false,
        // outputs return data at the end of transaction
        "return_data": true,
        "logs_short": false,
        // outputs logs (events)
        "logs": true,
        // outputs solidity view of final slots (final_slots should be enabled)
        "sol_view": true
    },
    // Possible values:
    // path to output file
    // if starts with "http://", starts http server on specified address
    // if empty, outputs to terminal
    "output": "http://127.0.0.1:4334",
    // special mode, if enabled TracEVM thinks that there are some slots or code which
    // existed before, therefore unknown, so it is marked as UNKNOWNSLOT or UNKNOWNCODE
    "past_unknown": false
}

List of TracEVM opcodes can be found here

Other conf examples can be found here

Foundry Docker

Still the easiest way to start foundry is to use Docker

docker pull ioterw/tracevm-cast

Run cast

docker run --rm -it -p 4334:4334 ioterw/tracevm-cast run 0xf717d3585675a6453e7b433692d3d951d24a41c7c0a7d04d1ce114f2db3e036d --flashbots --debug

or

docker run --rm -it ioterw/tracevm-cast run 0xf717d3585675a6453e7b433692d3d951d24a41c7c0a7d04d1ce114f2db3e036d --flashbots

Foundry prerequesites

make, git, go, python3, rust, gcc (clang on mac should be fine) should be preinstalled.

Building Foundry

It is possible to build TracEVM for Foundry with such command.

./build.py foundry

Running Foundry Cast

To open webview for specific transaction on address 127.0.0.1:4334 run the following command.

cd build
./tracevm-cast run 0xf717d3585675a6453e7b433692d3d951d24a41c7c0a7d04d1ce114f2db3e036d --flashbots --debug

Found a bug?

Please open an issue and supply solidity code that produced unexpected behaviour.

About

Track the values and addresses of slots (storage variables in Solidity) inside the Ethereum contract, as well as tracking logs (Solidity events).

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published