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)
}