move tracer doc, md formatting

This commit is contained in:
Joe 2022-08-17 09:24:32 +01:00
parent 008150095d
commit 18ae820f7a
4 changed files with 60 additions and 190 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 142 KiB

View file

@ -1,12 +1,10 @@
--- ---
title: Built-in tracers title: Built-in tracers
sort_key: C description: Explanation of the tracers that come bundled in Geth as part of the tracing API.
--- ---
Geth comes bundled with a choice of tracers ready for usage through the [tracing API](/docs/rpc/ns-debug). Some of them are implemented natively in Go, and others in JS. In this page a summary of each of these will be outlined. They have to be specified by name when sending a request. The only exception is the opcode logger (otherwise known as struct logger) which is the default tracer for all the methods and cannot be specified by name. Geth comes bundled with a choice of tracers ready for usage through the [tracing API](/docs/rpc/ns-debug). Some of them are implemented natively in Go, and others in JS. In this page a summary of each of these will be outlined. They have to be specified by name when sending a request. The only exception is the opcode logger (otherwise known as struct logger) which is the default tracer for all the methods and cannot be specified by name.
* TOC
{:toc}
## Struct logger ## Struct logger

View file

@ -1,30 +1,17 @@
--- ---
title: Go API title: Go API
sort_key: C description: Introduction to the Go packages that allow Geth to be used in Go native applications.
--- ---
Ethereum was originally conceptualized to be the base layer for [Web3][web3-link], providing Ethereum was originally conceptualized to be the base layer for [Web3](https://ethereum.org/en/web3/), providing the backbone for a new generation of decentralized, permissionless and censorship resistant applications called [dapps](https://ethereum.org/en/glossary/#dapp). The first step towards this vision was the development of clients providing an RPC interface into the peer-to-peer protocols. This allowed users to transact between accounts and interact with smart contracts using command line tools. Geth was one of the original clients to provide this type of gateway to the Ethereum network.
the backbone for a new generation of decentralized, permissionless and censorship resistant
applications called [dapps][dapp-link]. The first step towards this vision was the development
of clients providing an RPC interface into the peer-to-peer protocols. This allowed users to
transact between accounts and interact with smart contracts using command line tools.
Geth was one of the original clients to provide this type of gateway to the Ethereum network.
Before long, web-browser-like graphical interfaces (e.g. Mist) were created to extend clients, and Before long, web-browser-like graphical interfaces (e.g. Mist) were created to extend clients, and client functions were built into websites built using the time-tested HTML/CSS/JS stack. However, to support the most diverse, complex dapps, developers require programmatic access to client functions through an API. This opens up client technologies as re-usable, composable units that can be applied in creative ways by a global community of developers.
client functions were built into websites built using the time-tested HTML/CSS/JS stack.
However, to support the most diverse, complex dapps, developers require programmatic access to client
functions through an API. This opens up client technologies as re-usable, composable units that
can be applied in creative ways by a global community of developers.
To support this, Geth ships official Go packages that can be embedded into third party To support this, Geth ships official Go packages that can be embedded into third party desktop and server applications. There is also a [mobile API](/content/docs/developers/dapp-developer/mobile.md) that can be used to embed Geth into mobile applications.
desktop and server applications. There is also a [mobile API](/docs/dapp/mobile) that can be
used to embed Geth into mobile applications.
This page provides a high-level overview of the Go API. This page provides a high-level overview of the Go API.
*Note, this guide will assume some familiarity with Go development. It does not cover general topics *Note, this guide will assume some familiarity with Go development. It does not cover general topics about Go project layouts, import paths or any other standard methodologies. If you are new to Go, consider reading [Getting Started with Go](https://github.com/golang/go/wiki#getting-started-with-go) first.*
about Go project layouts, import paths or any other standard methodologies. If you are new to Go,
consider reading [Getting Started with Go][go-guide] first.*
## Overview ## Overview
@ -34,25 +21,17 @@ Geth's reusable Go libraries focus on three main usage areas:
- Remote node interfacing via different transports - Remote node interfacing via different transports
- Contract interactions through auto-generated bindings - Contract interactions through auto-generated bindings
The libraries are updated synchronously with the Geth Github repository. The libraries are updated synchronously with the Geth Github repository. The Go libraries can be viewed in full at [Go Packages](https://pkg.go.dev/github.com/ethereum/go-ethereum#section-directories).
The Go libraries can be viewed in full at [Go Packages][go-pkg-link].
Péter Szilágyi (@karalabe) gave a high level overview of the Go libraries in Péter Szilágyi (@karalabe) gave a high level overview of the Go libraries in a talk at DevCon2 in Shanghai in 2016. The slides are still a useful resource ([available here](https://ethereum.karalabe.com/talks/2016-devcon.html)) and the talk itself can be viewed by clicking the image below (it is also archived on [IPFS](https://ipfs.io/ipfs/QmQRuKPKWWJAamrMqAp9rytX6Q4NvcXUKkhvu3kuREKqXR)).
a talk at DevCon2 in Shanghai in 2016. The slides are still a useful resource
([available here][peter-slides]) and the talk itself can be viewed by clicking
the image below (it is also archived on [IPFS][ipfs-link]).
[![Peter's Devcon2 talk](/static/images/devcon2_labelled.webp)](https://www.youtube.com/watch?v=R0Ia1U9Gxjg) [![Peter's Devcon2 talk](/assets/devcon2_labelled.webp)](https://www.youtube.com/watch?v=R0Ia1U9Gxjg)
## Go packages ## Go packages
The `go-ethereum` library is distributed as a collection of standard Go packages straight from go-ethereum's The `go-ethereum` library is distributed as a collection of standard Go packages straight from go-ethereum's GitHub repository. The packages can be used directly via the official Go toolkit, without needing any third party tools.
GitHub repository. The packages can be used directly via the official Go toolkit, without needing any
third party tools.
The canonical import path for Geth is `github.com/ethereum/go-ethereum`, with all packages residing The canonical import path for Geth is `github.com/ethereum/go-ethereum`, with all packages residing underneath. Although there are [lots of them](https://pkg.go.dev/github.com/ethereum/go-ethereum/#section-directories) most developers will only care about a limited subset.
underneath. Although there are [lots of them][go-ethereum-dir] most developers will only care about
a limited subset.
All the Geth packages can be downloaded using: All the Geth packages can be downloaded using:
@ -60,23 +39,18 @@ All the Geth packages can be downloaded using:
$ go get -d github.com/ethereum/go-ethereum/... $ go get -d github.com/ethereum/go-ethereum/...
``` ```
More Go API support for dapp developers can be found on the [Go Contract Bindings](/docs/dapp/native-bindings) More Go API support for dapp developers can be found on the [Go Contract Bindings](/content/docs/developers/dapp-developer/native-bindings.md) and [Go Account Management](/docs/dapp/native-accounts) pages.
and [Go Account Management](/docs/dapp/native-accounts) pages.
## Tutorial ## Tutorial
This section includes some basic usage examples for the `ethclient` and `gethclient` packages available as This section includes some basic usage examples for the `ethclient` and `gethclient` packages available as part of the Go API. The `ethclient` package provides a client that implements the full Ethereum JSON-RPC API, whereas `gethclient` offers the Geth-specific API.
part of the Go API. The `ethclient` package provides a client that implements the full Ethereum JSON-RPC API,
whereas `gethclient` offers the Geth-specific API.
### Instantiating a client ### Instantiating a client
The client is an instance of the `Client` struct which has associated functions that wrap requests to the Ethereum The client is an instance of the `Client` struct which has associated functions that wrap requests to the Ethereum or Geth RPC API endpoints.
or Geth RPC API endpoints.
A client is instantiated by passing a raw url or path to an ipc file to the client's `Dial` function. In the following A client is instantiated by passing a raw url or path to an ipc file to the client's `Dial` function. In the following code snippet the path to the ipc file for a local Geth node is provided to `ethclient.Dial()`.
code snippet the path to the ipc file for a local Geth node is provided to `ethclient.Dial()`.
```go ```go
// create instance of ethclient and assign to cl // create instance of ethclient and assign to cl
@ -89,13 +63,9 @@ _ = cl
### Interacting with the client ### Interacting with the client
The client can now be used to handle requests to the Geth node using the full JSON-RPC API. For example, the function The client can now be used to handle requests to the Geth node using the full JSON-RPC API. For example, the function `BlockNumer()` wraps a call to the `eth_blockNumber` endpoint. The function `SendTransaction` wraps a call to `eth_sendTransaction`. The full list of client methods can be found [here](https://pkg.go.dev/github.com/ethereum/go-ethereum/ethclient#Client).
`BlockNumer()` wraps a call to the `eth_blockNumber` endpoint. The function `SendTransaction` wraps a call to
`eth_sendTransaction`. The full list of client methods can be found [here][ethclient-pkg].
Frequently, the functions take an instance of the `Context` type as their leading argument. This defines context about requests sent from the application such as deadlines, cancellation signals etc. More information on this can Frequently, the functions take an instance of the `Context` type as their leading argument. This defines context about requests sent from the application such as deadlines, cancellation signals etc. More information on this can be found in the [Go documentation](https://pkg.go.dev/golang.org/x/net/context). An empty context instance can be created using `Context.Background()`.
be found in the [Go documentation](https://pkg.go.dev/golang.org/x/net/context). An empty context instance can be
created using `Context.Background()`.
### Querying client for data ### Querying client for data
@ -137,12 +107,8 @@ if err != nil {
### Sending a transaction ### Sending a transaction
Sending a transaction is achieved using the `SendTransaction()` function. `SendTransaction` takes an instance of Sending a transaction is achieved using the `SendTransaction()` function. `SendTransaction` takes an instance of `context.Context` as its leading argument and a signed transaction as its second argument. The signed transaction must be generated in advance. Building the signed transaction is a multi-stage process that requires first generating a key pair if none exists already, retrieving some chain data and defining sender and recipient
`context.Context` as its leading argument and a signed transaction as its second argument. The signed transaction addresses. Then these data can be collected into a transaction object and signed. The resulting signed transaction can then be passed to `SendTransaction`.
must be generated in advance. Building the signed transaction is a multi-stage
process that requires first generating a key pair if none exists already, retrieving some chain data and defining sender and recipient
addresses. Then these data can be collected into a transaction object and signed. The resulting signed transaction
can then be passed to `SendTransaction`.
The example below assumes the following key pair has already been generated: The example below assumes the following key pair has already been generated:
@ -152,8 +118,7 @@ SK = "0xaf5ead4413ff4b78bc94191a2926ae9ccbec86ce099d65aaf469e9eb1a0fa87f"
ADDR = "0x6177843db3138ae69679A54b95cf345ED759450d" ADDR = "0x6177843db3138ae69679A54b95cf345ED759450d"
``` ```
The secret key and address can be used to send a transaction. In the example below 1 ETH is sent from the The secret key and address can be used to send a transaction. In the example below 1 ETH is sent from the address `ADDR` to an arbitrary recipient.
address `ADDR` to an arbitrary recipient.
```go ```go
import ( import (
@ -210,8 +175,7 @@ func sendTransaction(cl *ethclient.Client) error {
### gethclient ### gethclient
An instance of `gethclient` can be used in exactly the same way as `ethclient`. However, `gethclient` An instance of `gethclient` can be used in exactly the same way as `ethclient`. However, `gethclient` includes Geth-specific API methods. These additional methods are:
includes Geth-specific API methods. These additional methods are:
```shell ```shell
CallContract() CallContract()
@ -223,27 +187,13 @@ MemStats()
SetHead() SetHead()
SubscribePendingTransactions() SubscribePendingTransactions()
``` ```
*Note that both `ethclient` and `gethclient` have a `CallContract()` function - the difference is that *Note that both `ethclient` and `gethclient` have a `CallContract()` function - the difference is that the `gethclient` version includes an `overrides` argument.*
the `gethclient` version includes an `overrides` argument.*
Details relating to these endpoints can be found at [pkg.go.dev][go-api-docs] or the Geth [Github][ethclient-link]. Details relating to these endpoints can be found at [pkg.go.dev](https://pkg.go.dev/github.com/ethereum/go-ethereum@v1.10.19/ethclient/gethclient) or the Geth [Github](https://github.com/ethereum/go-ethereum/tree/master/ethclient). The code snippets in this tutorial were adapted from a more more in-depth set of examples available on [Github](https://github.com/MariusVanDerWijden/web3go).
The code snippets in this tutorial were adapted from a more more in-depth set of examples available on
[Github][web3go-link].
## Summary ## Summary
There are a wide variety of Go APIs available for dapp developers that abstract away the complexity of interacting with Ethereum There are a wide variety of Go APIs available for dapp developers that abstract away the complexity of interacting with Ethereum using a set of composable, reusable functions provided by Geth.
using a set of composable, reusable functions provided by Geth.
[go-guide]: https://github.com/golang/go/wiki#getting-started-with-go
[peter-slides]: https://ethereum.karalabe.com/talks/2016-devcon.html
[go-ethereum-dir]: https://pkg.go.dev/github.com/ethereum/go-ethereum/#section-directories
[ethclient-pkg]:https://pkg.go.dev/github.com/ethereum/go-ethereum/ethclient#Client
[go-pkg-link]: https://pkg.go.dev/github.com/ethereum/go-ethereum#section-directories
[ipfs-link]: https://ipfs.io/ipfs/QmQRuKPKWWJAamrMqAp9rytX6Q4NvcXUKkhvu3kuREKqXR
[dapp-link]: https://ethereum.org/en/glossary/#dapp
[web3-link]: https://ethereum.org/en/web3/
[ethclient-link]: https://github.com/ethereum/go-ethereum/tree/master/ethclient
[go-api-docs]:https://pkg.go.dev/github.com/ethereum/go-ethereum@v1.10.19/ethclient/gethclient
[web3go-link]:https://github.com/MariusVanDerWijden/web3go

View file

@ -1,87 +1,44 @@
--- ---
title: EVM Tracing title: EVM Tracing
sort_key: A description: Introduction to tracing EVM transactions using Geth
--- ---
There are two different types of [transactions][transactions] There are two different types of [transactions](https://ethereum.org/en/developers/docs/transactions) in Ethereum: simple value transfers and contract executions. A value transfer just moves Ether from one account to another. If however the recipient of a transaction is a contract account with associated [EVM](https://ethereum.org/en/developers/docs/evm) (Ethereum Virtual Machine) bytecode - beside transferring any Ether - the code will also be executed as part of the transaction.
in Ethereum: simple value transfers and contract executions. A value transfer just
moves Ether from one account to another. If however the recipient of a transaction is
a contract account with associated [EVM][evm] (Ethereum Virtual Machine) bytecode - beside
transferring any Ether - the code will also be executed as part of the transaction.
Having code associated with Ethereum accounts permits transactions to do arbitrarily Having code associated with Ethereum accounts permits transactions to do arbitrarily complex data storage and enables them to act on the previously stored data by further transacting internally with outside accounts and contracts. This creates an interlinked ecosystem of contracts, where a single transaction can interact with tens or hundreds of accounts.
complex data storage and enables them to act on the previously stored data by further
transacting internally with outside accounts and contracts. This creates an interlinked
ecosystem of contracts, where a single transaction can interact with tens or hundreds of
accounts.
The downside of contract execution is that it is very hard to say what a transaction The downside of contract execution is that it is very hard to say what a transaction actually did. A transaction receipt does contain a status code to check whether execution succeeded or not, but there is no way to see what data was modified, nor what external contracts where invoked. Geth resolves this by re-running transactions locally and collecting data about precisely what was executed by the EVM. This is known as "tracing" the transaction.
actually did. A transaction receipt does contain a status code to check whether execution
succeeded or not, but there is no way to see what data was modified, nor what external
contracts where invoked. Geth resolves this by re-running transactions locally and collecting
data about precisely what was executed by the EVM. This is known as "tracing" the transaction.
* TOC
{:toc}
## Tracing prerequisites ## Tracing prerequisites
In its simplest form, tracing a transaction entails requesting the Ethereum node to In its simplest form, tracing a transaction entails requesting the Ethereum node to reexecute the desired transaction with varying degrees of data collection and have it return the aggregated summary for post processing. Reexecuting a transaction however has a few prerequisites to be met.
reexecute the desired transaction with varying degrees of data collection and have it
return the aggregated summary for post processing. Reexecuting a transaction however has a
few prerequisites to be met.
In order for an Ethereum node to reexecute a transaction, all historical state accessed In order for an Ethereum node to reexecute a transaction, all historical state accessed by the transaction must be available. This includes:
by the transaction must be available. This includes:
* Balance, nonce, bytecode and storage of both the recipient as well as all internally invoked contracts. * Balance, nonce, bytecode and storage of both the recipient as well as all internally invoked contracts.
* Block metadata referenced during execution of both the outer as well as all internally created transactions. * Block metadata referenced during execution of both the outer as well as all internally created transactions.
* Intermediate state generated by all preceding transactions contained in the same block as the one being traced. * Intermediate state generated by all preceding transactions contained in the same block as the one being traced.
This means there are limits on the transactions that can be traced imposed by the synchronization and This means there are limits on the transactions that can be traced imposed by the synchronization and pruning configuration of a node.
pruning configuration of a node.
* An **archive** node retains **all historical data** back to genesis. It can therefore * An **archive** node retains **all historical data** back to genesis. It can therefore trace arbitrary transactions at any point in the history of the chain. Tracing a single transaction requires reexecuting all preceding transactions in the same block.
trace arbitrary transactions at any point in the history of the chain. Tracing a single
transaction requires reexecuting all preceding transactions in the same block.
* A **full synced** node retains the most recent 128 blocks in memory, so transactions in * A **full synced** node retains the most recent 128 blocks in memory, so transactions in that range are always accessible. Full nodes also store occasional checkpoints back to genesis that can be used to rebuild the state at any point on-the-fly. This means older transactions can be traced but if there is a large distance between the requested transaction and the most recent checkpoint rebuilding the state can take a long time. Tracing a single transaction requires reexecuting all preceding transactions in the same block **and** all preceding blocks until the previous stored snapshot.
that range are always accessible. Full nodes also store occasional checkpoints back to genesis
that can be used to rebuild the state at any point on-the-fly. This means older transactions * A **snap synced** node holds the most recent 128 blocks in memory, so transactions in that range are always accessible. However, snap-sync only starts processing from a relatively recent block (as opposed to genesis for a full node). Between the initial sync block and the 128 most recent blocks, the node stores occasional checkpoints that can be used to rebuild the state on-the-fly. This means transactions can be traced back as far as the block that was used for the initial sync. Tracing a single transaction requires reexecuting all preceding transactions in the same block,
can be traced but if there is a large distance between the requested transaction and the most
recent checkpoint rebuilding the state can take a long time. Tracing a single
transaction requires reexecuting all preceding transactions in the same block
**and** all preceding blocks until the previous stored snapshot. **and** all preceding blocks until the previous stored snapshot.
* A **snap synced** node holds the most recent 128 blocks in memory, so transactions in that * A **light synced** node retrieving data **on demand** can in theory trace transactions for which all required historical state is readily available in the network. This is because the data required to generate the trace is requested from an les-serving full node. In practice, data
range are always accessible. However, snap-sync only starts processing from a relatively recent
block (as opposed to genesis for a full node). Between the initial sync block and the 128 most
recent blocks, the node stores occasional checkpoints that can be used to rebuild the state on-the-fly.
This means transactions can be traced back as far as the block that was used for the initial sync.
Tracing a single transaction requires reexecuting all preceding transactions in the same block,
**and** all preceding blocks until the previous stored snapshot.
* A **light synced** node retrieving data **on demand** can in theory trace transactions
for which all required historical state is readily available in the network. This is because the data
required to generate the trace is requested from an les-serving full node. In practice, data
availability **cannot** be reasonably assumed. availability **cannot** be reasonably assumed.
*There are exceptions to the above rules when running batch traces of entire blocks or *There are exceptions to the above rules when running batch traces of entire blocks or chain segments. Those will be detailed later.*
chain segments. Those will be detailed later.*
## Basic traces ## Basic traces
The simplest type of transaction trace that Geth can generate are raw EVM opcode The simplest type of transaction trace that Geth can generate are raw EVM opcode traces. For every VM instruction the transaction executes, a structured log entry is emitted, containing all contextual metadata deemed useful. This includes the *program counter*, *opcode name*, *opcode cost*, *remaining gas*, *execution depth* and any *occurred error*. The structured logs can optionally also contain the content of the *execution stack*, *execution memory* and *contract storage*.
traces. For every VM instruction the transaction executes, a structured log entry is
emitted, containing all contextual metadata deemed useful. This includes the *program
counter*, *opcode name*, *opcode cost*, *remaining gas*, *execution depth* and any
*occurred error*. The structured logs can optionally also contain the content of the
*execution stack*, *execution memory* and *contract storage*.
The entire output of a raw EVM opcode trace is a JSON object having a few metadata The entire output of a raw EVM opcode trace is a JSON object having a few metadata fields: *consumed gas*, *failure status*, *return value*; and a list of *opcode entries*:
fields: *consumed gas*, *failure status*, *return value*; and a list of *opcode entries*:
```json ```json
{ {
@ -119,33 +76,23 @@ An example log for a single opcode entry has the following format:
### Generating basic traces ### Generating basic traces
To generate a raw EVM opcode trace, Geth provides a few [RPC API endpoints](/docs/rpc/ns-debug). To generate a raw EVM opcode trace, Geth provides a few [RPC API endpoints](/docs/rpc/ns-debug). The most commonly used is [`debug_traceTransaction`](/docs/rpc/ns-debug#debug_tracetransaction).
The most commonly used is [`debug_traceTransaction`](/docs/rpc/ns-debug#debug_tracetransaction).
In its simplest form, `traceTransaction` accepts a transaction hash as its only argument. It then In its simplest form, `traceTransaction` accepts a transaction hash as its only argument. It then traces the transaction, aggregates all the generated data and returns it as a **large** JSON object. A sample invocation from the Geth console would be:
traces the transaction, aggregates all the generated data and returns it as a **large**
JSON object. A sample invocation from the Geth console would be:
```js ```js
debug.traceTransaction("0xfc9359e49278b7ba99f59edac0e3de49956e46e530a53c15aa71226b7aa92c6f") debug.traceTransaction("0xfc9359e49278b7ba99f59edac0e3de49956e46e530a53c15aa71226b7aa92c6f")
``` ```
The same call can also be invoked from outside the node too via HTTP RPC (e.g. using Curl). In this The same call can also be invoked from outside the node too via HTTP RPC (e.g. using Curl). In this case, the HTTP endpoint must be enabled in Geth using the `--http` command and the `debug` API namespace must be exposed using `--http.api=debug`.
case, the HTTP endpoint must be enabled in Geth using the `--http` command and the `debug` API
namespace must be exposed using `--http.api=debug`.
``` ```
$ curl -H "Content-Type: application/json" -d '{"id": 1, "method": "debug_traceTransaction", "params": ["0xfc9359e49278b7ba99f59edac0e3de49956e46e530a53c15aa71226b7aa92c6f"]}' localhost:8545 $ curl -H "Content-Type: application/json" -d '{"id": 1, "method": "debug_traceTransaction", "params": ["0xfc9359e49278b7ba99f59edac0e3de49956e46e530a53c15aa71226b7aa92c6f"]}' localhost:8545
``` ```
To follow along with this tutorial, transaction hashes can be found from a local Geth node (e.g. by To follow along with this tutorial, transaction hashes can be found from a local Geth node (e.g. by attaching a [Javascript console](/docs/interface/javascript-console) and running `eth.getBlock('latest')` then passing a transaction hash from the returned block to `debug.traceTransaction()`) or from a block explorer (for [Mainnet](https://etherscan.io/) or a [testnet](https://goerli.etherscan.io/)).
attaching a [Javascript console](/docs/interface/javascript-console) and running `eth.getBlock('latest')`
then passing a transaction hash from the returned block to `debug.traceTransaction()`) or from a block
explorer (for [Mainnet](https://etherscan.io/) or a [testnet](https://goerli.etherscan.io/)).
It is also possible to configure the trace by passing Boolean (true/false) values for four parameters It is also possible to configure the trace by passing Boolean (true/false) values for four parameters that tweak the verbosity of the trace. By default, the *EVM memory* and *Return data* are not reported but the *EVM stack* and *EVM storage* are. To report the maximum amount of data:
that tweak the verbosity of the trace. By default, the *EVM memory* and *Return data* are not reported
but the *EVM stack* and *EVM storage* are. To report the maximum amount of data:
```shell ```shell
enableMemory: true enableMemory: true
@ -154,18 +101,15 @@ disableStorage: false
enableReturnData: true enableReturnData: true
``` ```
An example call, made in the Geth Javascript console, configured to report the maximum amount of data An example call, made in the Geth Javascript console, configured to report the maximum amount of data looks as follows:
looks as follows:
```js ```js
debug.traceTransaction("0xfc9359e49278b7ba99f59edac0e3de49956e46e530a53c15aa71226b7aa92c6f",{enableMemory: true, disableStack: false, disableStorage: false, enableReturnData: true}) debug.traceTransaction("0xfc9359e49278b7ba99f59edac0e3de49956e46e530a53c15aa71226b7aa92c6f",{enableMemory: true, disableStack: false, disableStorage: false, enableReturnData: true})
``` ```
Running the above operation on the Rinkeby network (with a node retaining enough history) Running the above operation on the Rinkeby network (with a node retaining enough history) will result in this [trace dump](https://gist.github.com/karalabe/c91f95ac57f5e57f8b950ec65ecc697f).
will result in this [trace dump](https://gist.github.com/karalabe/c91f95ac57f5e57f8b950ec65ecc697f).
Alternatively, disabling *EVM Stack*, *EVM Memory*, *Storage* and *Return data* (as demonstrated in the Curl request below) Alternatively, disabling *EVM Stack*, *EVM Memory*, *Storage* and *Return data* (as demonstrated in the Curl request below) results in the following, much shorter, [trace dump](https://gist.github.com/karalabe/d74a7cb33a70f2af75e7824fc772c5b4).
results in the following, much shorter, [trace dump](https://gist.github.com/karalabe/d74a7cb33a70f2af75e7824fc772c5b4).
``` ```
$ curl -H "Content-Type: application/json" -d '{"id": 1, "method": "debug_traceTransaction", "params": ["0xfc9359e49278b7ba99f59edac0e3de49956e46e530a53c15aa71226b7aa92c6f", {"disableStack": true, "disableStorage": true}]}' localhost:8545 $ curl -H "Content-Type: application/json" -d '{"id": 1, "method": "debug_traceTransaction", "params": ["0xfc9359e49278b7ba99f59edac0e3de49956e46e530a53c15aa71226b7aa92c6f", {"disableStack": true, "disableStorage": true}]}' localhost:8545
@ -173,20 +117,13 @@ $ curl -H "Content-Type: application/json" -d '{"id": 1, "method": "debug_traceT
### Limits of basic traces ### Limits of basic traces
Although the raw opcode traces generated above are useful, having an individual log entry for every single Although the raw opcode traces generated above are useful, having an individual log entry for every single opcode is too low level for most use cases, and will require developers to create additional tools to post-process the traces. Additionally, a full opcode trace can easily go into the hundreds of megabytes, making them very resource intensive to get out of the node and process externally.
opcode is too low level for most use cases, and will require developers to create additional tools to
post-process the traces. Additionally, a full opcode trace can easily go into the hundreds of
megabytes, making them very resource intensive to get out of the node and process externally.
To avoid those issues, Geth supports running custom JavaScript tracers *within* the Ethereum node, To avoid those issues, Geth supports running custom JavaScript tracers *within* the Ethereum node, which have full access to the EVM stack, memory and contract storage. This means developers only have to gather the data they actually need, and do any processing at the source.
which have full access to the EVM stack, memory and contract storage. This means developers only have to
gather the data they actually need, and do any processing at the source.
## Pruning ## Pruning
Geth does in-memory state-pruning by default, discarding state entries that it deems Geth does in-memory state-pruning by default, discarding state entries that it deems no longer necessary to maintain. This is configured via the `--gcmode` command. An error message alerting the user that the necessary state is not available is common in EVM tracing on
no longer necessary to maintain. This is configured via the `--gcmode` command. An error
message alerting the user that the necessary state is not available is common in EVM tracing on
anything other than an archive node. anything other than an archive node.
```sh ```sh
@ -196,37 +133,22 @@ Error: required historical state unavailable (reexec=128)
at <eval>:1:23(13) at <eval>:1:23(13)
``` ```
The pruning behaviour, and consequently the state availability and tracing capability of The pruning behaviour, and consequently the state availability and tracing capability of a node depends on its sync and pruning configuration. The 'oldest' block after which state is immediately available, and before which state is not immediately available, is known as the "pivot block". There are then several possible cases for a trace request on a Geth node.
a node depends on its sync and pruning configuration. The 'oldest' block after which
state is immediately available, and before which state is not immediately available,
is known as the "pivot block". There are then several possible cases for a trace request
on a Geth node.
For tracing a transaction in block `B` where the pivot block is `P` can regenerate the desired For tracing a transaction in block `B` where the pivot block is `P` can regenerate the desired state by replaying blocks from the last:
state by replaying blocks from the last :
1. a fast-sync'd node can regenerate the desired state by replaying blocks from the most recent 1. a fast-sync'd node can regenerate the desired state by replaying blocks from the most recent checkpoint between `P` and `B` as long as `P` < `B`. If `P` > `B` there is no available checkpoint and the state cannot be regenerated without replying the chain from genesis.
checkpoint between `P` and `B` as long as `P` < `B`. If `P` > `B` there is no available checkpoint
and the state cannot be regenerated without replying the chain from genesis.
2. a fully sync'd node can regenerate the desired state by replaying blocks from the last available 2. a fully sync'd node can regenerate the desired state by replaying blocks from the last available full state before `B`. A fully sync'd node re-executes all blocks from genesis, so checkpoints are available across the entire history of the chain. However, database pruning discards older data, moving `P` to a more recent position in the chain. If `P` > `B` there is no available checkpoint and the state cannot be regenerated without replaying the chain from genesis.
full state before `B`. A fully sync'd node re-executes all blocks from genesis, so checkpoints are available
across the entire history of the chain. However, database pruning discards older data, moving `P` to a more
recent position in the chain. If `P` > `B` there is no available checkpoint and the state cannot be
regenerated without replaying the chain from genesis.
3. A fully-sync'd node without pruning (i.e. an archive node configured with `--gcmode=archive`) 3. A fully-sync'd node without pruning (i.e. an archive node configured with `--gcmode=archive`) does not need to replay anything, it can immediately load up any state and serve the request for any `B`.
does not need to replay anything, it can immediately load up any state and serve the request for any `B`.
The time taken to regenerate a specific state increases with the distance between `P` and `B`. If the distance The time taken to regenerate a specific state increases with the distance between `P` and `B`. If the distance between `P` and `B` is large, the regeneration time can be substantial.
between `P` and `B` is large, the regeneration time can be substantial.
## Summary ## Summary
This page covered the concept of EVM tracing and how to generate traces with the default opcode-based tracers using RPC. This page covered the concept of EVM tracing and how to generate traces with the default opcode-based tracers using RPC. More advanced usage is possible, including using other built-in tracers as well as writing [custom tracing](/docs/dapp/custom-tracer) code in Javascript and Go. The API as well as the JS tracing hooks are defined in [the reference](/docs/rpc/ns-debug#debug_traceTransaction).
More advanced usage is possible, including using other built-in tracers as well as writing [custom tracing](/docs/dapp/custom-tracer) code in Javascript
and Go. The API as well as the JS tracing hooks are defined in [the reference](/docs/rpc/ns-debug#debug_traceTransaction).
[transactions]: https://ethereum.org/en/developers/docs/transactions
[evm]: https://ethereum.org/en/developers/docs/evm [evm]: