The first demo of TCT using metadata and Natspec.
-
Install solc compiler locally: https://docs.soliditylang.org/en/develop/installing-solidity.html
-
A tool to quickly switch between Solidity compiler versions: https://github.com/crytic/solc-select
-
use the command to get the NatSpec
solc --userdoc --devdoc re_victim.sol // under get-trace folder
natspec content for
re_victim.sol
======= re_victim.sol:Attack ======= Developer Documentation {"kind":"dev","methods":{},"version":1} User Documentation {"kind":"user","methods":{},"version":1} ======= re_victim.sol:EtherStore ======= Developer Documentation {"kind":"dev","methods":{"leaves()":{"custom:experimental":"invariant: (forall x:address :: 0 <= balances[x] && balances[x] <= totalSupply)"},"withdraw()":{"custom:experimental":"invariant: (forall x:address :: 0 <= balances[x] && balances[x] <= totalSupply) "}},"version":1} User Documentation {"kind":"user","methods":{},"version":1} ======= re_victim.sol:EtherStoreChild ======= Developer Documentation {"kind":"dev","methods":{"withdraw()":{"custom:experimental":"invariant: (forall x:address :: 0 <= balances[x] && balances[x] <= totalSupply) "}},"version":1} User Documentation {"kind":"user","methods":{},"version":1}
-
use the command
solc --metadata re_victim.sol --output-dir re_victim_metadata_json
to get the metedata in folderre_victim_metadata_json
. And we can extract from the key"devdoc"
(NatSpec). -
Rule to use tags:
- put the tag in front of interface, contract, function, event.
@inheritdoc
: when we want to make the thereom inherited.@custom:tct/experimental
: we could put the thereom here where it won't be inherited.
Get the evm execution trace using alchemy API trace-replaytransaction
: https://docs.alchemy.com/reference/trace-replaytransaction. But the vmtrace
is null. The vmTrace mode is one of the most enigmatic and rarely used, mainly because it was never really documented.
Here is what we get in a vmTrace
response:
VMTrace
represents a call and contains all subcallscode
EVM bytecode to be executedops
list of VMOperation to be executed
VMOperation
represents a step of the executionpc
program countercost
gas cost of the operationex
the result of the execution, could be null if the operation has revertedsub
list of VMTrace subcallsop
opcode nameidx
index in the call tree
VMExecutedOperation
represents side effects of executing the operationused
incorrectly named, shows the remaining gaspush
the items to be placed on the stackmem
the memory deltastore
the storage delta
MemoryDiff
represents a memory updateoff
memory offset where to write the datadata
the bytes to write starting at the offset
StorageDiff
represents a storage writekey
storage key to write toval
value to write
I build a vm_trace.py
to get execution trace.
Before you run, you have to make sure you run a Geth node on local machine.
- [1] Install Ethereum Client (Geth): https://geth.ethereum.org/docs/getting-started/installing-geth
- [2] Run a Local Ethereum Node: Once you have installed an Ethereum client, you need to run it to create a local blockchain. The specific command may vary depending on the client you are using. For example, if you are using Geth, you can run the following command to start a local node:
geth --syncmode "full" --http --http.api eth,web3,debug --http.addr "localhost" --http.port "8545" console debug.traceTransaction("0x241bf4e3ea3edf32eff7257486a774430e600d5aae6340e70ebf44a9e51ca2e0") erigon --http --http.api eth,web3,debug --http.addr "localhost" --http.port "8545" debug.trace_replayTransaction("0x241bf4e3ea3edf32eff7257486a774430e600d5aae6340e70ebf44a9e51ca2e0")
- [3] Connect to Localhost Provider by running
python3 web3_check.py
. It should return True. If False, return to check if you install Geth correctly.
Then, we could run vm_trace.py
python3 -m venv venv
source venv/bin/activate
pip3 install -r evm_trace_requirement.txt
ape --version # test if eth-ape is installed
python3 vm_trace.py --help # see how to use
python3 vm_trace.py trace <tx hash> # get tx hash
Dependency:
- ape: https://github.com/ApeWorX/ape
- eth-ape: https://docs.apeworx.io/ape/stable/userguides/quickstart.html
- ape-alchemy: https://github.com/ApeWorX/ape-alchemy
More details about vmtrace
in official doc: https://ethereum-tests.readthedocs.io/_/downloads/en/latest/pdf/.
Or we could use local remix plugin. There are two ways to run & deploy contracts using local remix: remixd (which connect web ethereum) and locally run via ganachi-cli
(https://trufflesuite.com/docs/ganache/quickstart/). Please refer to this link: https://medium.com/remix-ide/remix-in-vscode-compiling-debugging-metamask-remixd-42c4a61817e2.
For how to deploy and test the contract, follow this blog: https://blog.logrocket.com/develop-test-deploy-smart-contracts-ganache/.
after you successfully deploy a contract and issue an transaction, you could use this cmd to get trace of the transaction.
curl -H 'Content-Type: application/json' --data '{"jsonrpc":"2.0", "id": 1, "method": "debug_traceTransaction", "params": ["<transaction hash>",{} ] }' http://localhost:8545 -o trace.json
then you will get a json file trace.json
which contains the execution trace. And we process the raw json file to get the evm opcode trace. For example
python3 trace_process.py --trace_file trace.json --output trace1.txt
More details are here.