Tracing
Tracing can give detailed insights into the execution of EVM contracts. w3vm.VM
supports tracing via go‑ethereum
’s tracing.Hooks
.
Usage
A tracing.Hooks
can be passed to VM.Apply
, VM.ApplyTx
, and VM.Call
. These methods can also be called with multiple hooks at the same time.
Example: Trace Calls and OpCodes of an Execution
w3vm
contains a powerful call an opcode tracer hooks.CallTracer
that can be used gain detailed insights into the execution of EVM contracts (Playground):
callTracer := hooks.NewCallTracer(os.Stdout, &hooks.CallTracerOptions{
ShowStaticcall: true,
DecodeABI: true,
})
vm.ApplyTx(tx, callTracer)
Example: Generate an Access List
Access list tracing using go-ethereum
’s logger.AccessListTracer
(Playground):
// setup access list tracer
signer := types.MakeSigner(params.MainnetChainConfig, header.Number, header.Time)
from, _ := signer.Sender(tx)
accessListTracer := logger.NewAccessListTracer(
nil,
from, *tx.To(),
gethVm.ActivePrecompiles(params.MainnetChainConfig.Rules(header.Number, header.Difficulty.Sign() == 0, header.Time)),
)
if _, err := vm.ApplyTx(tx, accessListTracer.Hooks()); err != nil {
// ...
}
fmt.Println("Access List:", accessListTracer.AccessList())
Example: Trace the Execution of all OpCodes in a Block
Trace the execution of all op’s in a block (Playground):
// setup block op's tracer
var opCount [256]uint64
tracer := &tracing.Hooks{
OnOpcode: func(pc uint64, op byte, gas, cost uint64, scope tracing.OpContext, rData []byte, depth int, err error) {
opCount[op]++
},
}
for _, tx := range block.Transactions() {
vm.ApplyTx(tx, tracer)
}