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*.
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_.
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*:
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_:
```json
{
@ -36,8 +36,7 @@ An example log for a single opcode entry has the following format:
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`.
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/)).
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:
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:
```shell
enableMemory: true
@ -72,12 +71,17 @@ enableReturnData: true
An example call, made in the Geth Javascript console, configured to report the maximum amount of data looks as follows:
The above operation was run on the (now-deprecated) Rinkeby network (with a node retaining enough history), resulting 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) results in the following, much shorter, [trace dump](https://gist.github.com/karalabe/d74a7cb33a70f2af75e7824fc772c5b4).
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).
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.
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.
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.
@ -5,7 +5,6 @@ description: Explanation of the tracers that come bundled in Geth as part of the
Geth comes bundled with a choice of tracers that can be invoked via the [tracing API](/docs/rpc/ns-debug). Some of these built-in tracers are implemented natively in Go, and others in Javascript. The default tracer is the opcode logger (otherwise known as struct logger) which is the default tracer for all the methods. Other tracers have to be specified by passing their name to the `tracer` parameter in the API call.
## Struct/opcode logger {#struct-opcode-logger}
The struct logger (aka opcode logger) is a native Go tracer which executes a transaction and emits the opcode and execution context at every step. This is the tracer that will be used when no name is passed to the API, e.g. `debug.traceTransaction(<txhash>)`. The following information is emitted at each step:
@ -94,7 +93,6 @@ Return:
The following tracers are implement in Go. This means they are much more performant than other tracers that are written in Javascript. The tracers are selected by passing their name to the `tracer` parameter when invoking a tracing API method, e.g. `debug.traceTransaction(<txhash>, { tracer: 'callTracer' })`.
### 4byteTracer {#4byte-tracer}
Solidity contract functions are
@ -138,7 +136,6 @@ The `callTracer` tracks all the call frames executed during a transaction, inclu
| revertReason | string | Solidity revert reason, if any |
| calls | []callframe | list of sub-calls |
Example Call:
```sh
@ -211,7 +208,15 @@ To run this tracer in `diff` mode, pass `tracerConfig: {diffMode: true}` in the
Example:
```js
debug.traceCall({from: "0x35a9f94af726f07b5162df7e828cc9dc8439e7d0", to: "0xc8ba32cab1757528daf49033e3673fae77dcf05d", data: "0xd1a2eab2000000000000000000000000000000000000000000000000000000000024aea100000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000050000000204895cd480cc8412691a880028a25aec86786f1ed2aa5562bc400000000000000c6403c14f35be1da6f433eadbb6e9178a47fbc7c6c1d568d2f2b876e929089c8d8db646304fd001a187dc8a600000000000000000000000000000000"}, 'latest', {tracer: 'prestateTracer'})
@ -264,7 +269,6 @@ Return (same call with `{diffMode: True}`):
This tracer is noop. It returns an empty object and is only meant for testing the setup.
## Javascript tracers {#js-tracers}
There are also a set of tracers written in Javascript. These are less performant than the Go native tracers because of overheads associated with interpreting the Javascript in Geth's Go environment.
@ -276,7 +280,15 @@ There are also a set of tracers written in Javascript. These are less performant
Example:
```js
debug.traceCall({from: "0x35a9f94af726f07b5162df7e828cc9dc8439e7d0", to: "0xc8ba32cab1757528daf49033e3673fae77dcf05d", data: "0xd1a2eab2000000000000000000000000000000000000000000000000000000000024aea100000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000050000000204895cd480cc8412691a880028a25aec86786f1ed2aa5562bc400000000000000c6403c14f35be1da6f433eadbb6e9178a47fbc7c6c1d568d2f2b876e929089c8d8db646304fd001a187dc8a600000000000000000000000000000000"}, 'latest', {tracer: 'bigramTracer'})
`unigramTracer` counts the frequency of occurrance of each opcode.
Example:
```js
> debug.traceCall({from: "0x35a9f94af726f07b5162df7e828cc9dc8439e7d0", to: "0xc8ba32cab1757528daf49033e3673fae77dcf05d", data: "0xd1a2eab2000000000000000000000000000000000000000000000000000000000024aea100000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000050000000204895cd480cc8412691a880028a25aec86786f1ed2aa5562bc400000000000000c6403c14f35be1da6f433eadbb6e9178a47fbc7c6c1d568d2f2b876e929089c8d8db646304fd001a187dc8a600000000000000000000000000000000"}, 'latest', {tracer: 'unigramTracer'})
```
Returns:
```terminal
{
ADD: 36,
@ -447,7 +477,7 @@ Returns:
## State overrides {#state-overrides}
It is possible to give temporary state modifications to Geth in order to simulate the effects of `eth_call`. For example, some new byetcode could be deployed to some address *temporarily just for the duration of the execution* and then a transaction interacting with that address canm be traced. This can be used for scenario testing or determining the outcome of some hypothetical transaction before executing for real.
It is possible to give temporary state modifications to Geth in order to simulate the effects of `eth_call`. For example, some new byetcode could be deployed to some address _temporarily just for the duration of the execution_ and then a transaction interacting with that address canm be traced. This can be used for scenario testing or determining the outcome of some hypothetical transaction before executing for real.
To do this, the tracer is written as normal, but the parameter `stateOverrides` is passed an address and some bytecode.
*This image shows the state stored by each sync-mode - red indicates stored state. The full width of each line represents origin to present head*
_This image shows the state stored by each sync-mode - red indicates stored state. The full width of each line represents origin to present head_
More detailed information about syncing is available on the [sync modes page](/docs/interface/sync-modes).
When a trace of a specific transaction is executed, the state is prepared by fetching the state of the parent block from the database. If it is not available, Geth will crawl backwards in time to find the next available state but only up to a limit defined in the `reexec` parameter which defaults to 128 blocks. If no state is available within the `reexec` window then the trace fails with `Error: required historical state unavailable` and the `reexec` parameter must be increased. If a valid state *is* found in the `reexec` window, then Geth sequentially re-executes the transcations in each block between the last available state and the target block. The greater the value of `reexec` the longer the tracing will take because more blocks have to be re-executed to regenerate the target state.
When a trace of a specific transaction is executed, the state is prepared by fetching the state of the parent block from the database. If it is not available, Geth will crawl backwards in time to find the next available state but only up to a limit defined in the `reexec` parameter which defaults to 128 blocks. If no state is available within the `reexec` window then the trace fails with `Error: required historical state unavailable` and the `reexec` parameter must be increased. If a valid state _is_ found in the `reexec` window, then Geth sequentially re-executes the transcations in each block between the last available state and the target block. The greater the value of `reexec` the longer the tracing will take because more blocks have to be re-executed to regenerate the target state.
The `debug_getAccessibleStates` endpoint is a useful tool for estimating a suitable value for `reexec`. Passing the number of the block that contains the target transaction and a search distance to this endpoint will return the number of blocks behind the current head where the most recent available state exists. This value can be passed to the tracer as `re-exec`.
@ -48,11 +46,10 @@ _There are exceptions to the above rules when running batch traces of entire blo
### Basic traces {#basic-traces}
The simplest type of transaction trace that Geth can generate are raw EVM opcode traces. For every EVM 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 simplest type of transaction trace that Geth can generate are raw EVM opcode traces. For every EVM 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_.
Read more about Geth's basic traces on the [basic traces page](/docs/evm-tracing/basic-traces).
### Built-in tracers {#built-in-tracers}
The tracing API accepts an optional `tracer` parameter that defines how the data returned to the API call should be processed. If this parameter is ommitted the default tracer is used. The default is the struct (or 'opcode') logger. These raw opcode traces are sometimes useful, but the returned data is very low level and can be too extensive and awkward to read for many use-cases. 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. For these reasons, there are a set of non-default built-in tracers that can be named in the API call to return different data from the method. Under the hood, these tracers are Go or Javascript
@ -60,14 +57,12 @@ functions that do some specific preprocessing on the trace data before it is ret
More information about Geth's built-in tracers is available on the [built-in tracers](/docs/evm-tracing/builtin-tracers) page.
### Custom tracers {#custom-tracers}
In addition to built-in tracers, it is possible to provide custom code that hooks to events in the EVM to process and return data in a consumable format. Custom tracers can be written either in Javascript or Go. JS tracers are good for quick prototyping and experimentation as well as for less intensive applications. Go tracers are performant but require the tracer to be compiled together with the Geth source code. This means developers only have to gather the data they actually need, and do any processing at the source.
More information about custom tracers is available on the [custom tracers](/docs/evm-tracing/custom-tracer) page.
## Summary {#summary}
This page gave an introduction to the concept of tracing and explained issues around state availability. More detailed information on Geth's built-in and custom tracers can be found on their dedicated pages.
@ -156,6 +156,7 @@ This message will be displayed periodically until state healing has finished:
```
INFO [10-20|20:20:09.510] State heal in progress accounts=313,309@17.95MiB slots=363,525@28.77MiB codes=7222@50.73MiB nodes=49,616,912@12.67GiB pending=29805
```
When state healing is finished, the node is in sync and ready to use.
Sending an empty Curl request to the http server provides a quick way to confirm that this too has been started without any issues. In a third terminal, the following command can be run:
@ -166,7 +167,6 @@ curl http://localhost:8545
If there is no error message reported to the terminal, everything is OK. Geth must be running and synced in order for a user to interact with the Ethereum network. If the terminal running Geth is closed down then Geth must be restarted again in a new terminal. Geth can be started and stopped easily, but it must be running for any interaction with Ethereum to take place. To shut down Geth, simply press `CTRL+C` in the Geth terminal. To start it again, run the previous command `geth --datadir <other commands>`.
## Step 4: Get Testnet Ether {#get-test-eth}
In order to make some transactions, the user must fund their account with ether. On Ethereum mainnet, ether can only be obtained in three ways: 1) by receiving it as a reward for mining/validating; 2) receiving it in a transfer from another Ethereum user or contract; 3) receiving it from an exchange, 3) having paid for it with fiat money. On Ethereum testnets, the ether has no real world value so it 4) can be made freely available via faucets. Faucets allow users to request a transfer of testnet ether to their account.
Retrieves an ancient binary blob from the freezer. The freezer is a collection of append-only immutable files. The first argument `kind` specifies which table to look up data from. The list of all table kinds are as follows:
@ -106,8 +102,6 @@ Returns the raw value of a key stored in the database.
Sets the current head of the local chain by block number. **Note**, this is a destructive action and may severely damage your chain. Use with *extreme* caution.
Sets the current head of the local chain by block number. **Note**, this is a destructive action and may severely damage your chain. Use with _extreme_ caution.
When JS-based tracing (see below) was first implemented, the intended usecase was to enable long-running tracers that could stream results back via a subscription channel. This method works a bit differently. (For full details, see [PR](https://github.com/ethereum/go-ethereum/pull/17914))
@ -378,23 +361,27 @@ When JS-based tracing (see below) was first implemented, the intended usecase wa
- It streams output to disk during the execution, to not blow up the memory usage on the node
- It uses `jsonl` as output format (to allow streaming)
- Uses a cross-client standardized output, so called 'standard json'
* Uses `op` for string-representation of opcode, instead of `op`/`opName` for numeric/string, and other simlar small differences.
* has `refund`
* Represents memory as a contiguous chunk of data, as opposed to a list of `32`-byte segments like `debug_traceTransaction`
- Uses `op` for string-representation of opcode, instead of `op`/`opName` for numeric/string, and other simlar small differences.
- has `refund`
- Represents memory as a contiguous chunk of data, as opposed to a list of `32`-byte segments like `debug_traceTransaction`
This means that this method is only 'useful' for callers who control the node -- at least sufficiently to be able to read the artefacts from the filesystem after the fact.
The method can be used to dump a certain transaction out of a given block:
Files are created in a temp-location, with the naming standard `block_<blockhash:4>-<txindex>-<txhash:4>-<random suffix>`. Each opcode immediately streams to file, with no in-geth buffering aside from whatever buffering the os normally does.
On the server side, it also adds some more info when regenerating historical state, namely, the reexec-number if `required historical state is not avaiable` is encountered, so a user can experiment with increasing that setting. It also prints out the remaining block until it reaches target:
@ -409,6 +396,7 @@ INFO [10-15|13:48:34.421] Wrote trace file=/tmp/block_0x14490c57-2-0x3f4263fe-05
```
The `options` is as follows:
```
type StdTraceConfig struct {
*vm.LogConfig
@ -421,7 +409,6 @@ type StdTraceConfig struct {
This method is similar to `debug_standardTraceBlockToFile`, but can be used to obtain info about a block which has been _rejected_ as invalid (for some reason).
### debug_startCPUProfile
Turns on CPU profiling indefinitely, writing to the given file.
@ -552,7 +539,6 @@ Similar to [debug_traceBlock](#debug_traceblock), `traceBlockByHash` accepts a b
References:
[RLP](https://github.com/ethereum/wiki/wiki/RLP)
### debug_traceBlockFromFile
Similar to [debug_traceBlock](#debug_traceblock), `traceBlockFromFile` accepts a file containing the RLP of the block. For the second parameter see [TraceConfig](#traceconfig) reference.
@ -589,6 +575,7 @@ No specific call options:
structLogs: []
}
```
Tracing a call with a destination and specific sender, disabling the storage and memory output (less data returned over RPC)
In addition to the hash of the transaction you may give it a secondary *optional* argument, which specifies the options for this specific call. The possible options are:
In addition to the hash of the transaction you may give it a secondary _optional_ argument, which specifies the options for this specific call. The possible options are:
*`disableStorage`: `BOOL`. Setting this to true will disable storage capture (default = false).
*`disableStack`: `BOOL`. Setting this to true will disable stack capture (default = false).
*`enableMemory`: `BOOL`. Setting this to true will enable memory capture (default = false).
*`enableReturnData`: `BOOL`. Setting this to true will enable return data capture (default = false).
*`tracer`: `STRING`. Name for built-in tracer or Javascript expression. See below for more details.
-`disableStorage`: `BOOL`. Setting this to true will disable storage capture (default = false).
-`disableStack`: `BOOL`. Setting this to true will disable stack capture (default = false).
-`enableMemory`: `BOOL`. Setting this to true will enable memory capture (default = false).
-`enableReturnData`: `BOOL`. Setting this to true will enable return data capture (default = false).
-`tracer`: `STRING`. Name for built-in tracer or Javascript expression. See below for more details.
If set, the previous four arguments will be ignored.
*`timeout`: `STRING`. Overrides the default timeout of 5 seconds for JavaScript-based tracing calls.
-`timeout`: `STRING`. Overrides the default timeout of 5 seconds for JavaScript-based tracing calls.
Valid values are described [here](https://golang.org/pkg/time/#ParseDuration).
*`tracerConfig`: Config for the specified `tracer`. For example see callTracer's [config](/docs/evm-tracing/builtin-tracers#config).
-`tracerConfig`: Config for the specified `tracer`. For example see callTracer's [config](/docs/evm-tracing/builtin-tracers#config).
Geth comes with a bundle of [built-in tracers](/docs/evm-tracing/builtin-tracers), each providing various data about a transaction. This method defaults to the [struct logger](/docs/evm-tracing/builtin-tracers#structopcode-logger). The `tracer` field of the second parameter can be set to use any of the other tracers. Alternatively a [custom tracer](/docs/evm-tracing/custom-tracer) can be implemented in either Go or Javascript.
@ -742,31 +727,30 @@ Sets the logging verbosity pattern.
If you want to see messages from a particular Go package (directory) and all subdirectories, use:
```javascript
```javascript
> debug.vmodule("eth/*=6")
```
If you want to restrict messages to a particular package (e.g. p2p) but exclude subdirectories, use:
```javascript
```javascript
> debug.vmodule("p2p=6")
```
If you want to see log messages from a particular source file, use
```javascript
```javascript
> debug.vmodule("server.go=6")
```
You can compose these basic patterns. If you want to see all output from peer.go in a package below eth (eth/peer.go, eth/downloader/peer.go) as well as output from package p2p at level <= 5, use:
As opposed to `listAccounts`, this method lists full details, including usb path or keystore-file paths. The equivalent method is `clef_listWallets`. This method can be called from the terminal using:
```sh
@ -107,11 +107,12 @@ Example call (Javascript console):
```js
// this command requires 2x approval in Clef because it loads account data via eth.accounts[0]
// and eth.accounts[1]
var tx = {from: eth.accounts[0], to: eth.accounts[1], value: web3.toWei(0.1, "ether")}
var tx = {from: eth.accounts[0], to: eth.accounts[1], value: web3.toWei(0.1, 'ether') };
// only .sc files are being considered for signatures (https://github.com/ethereum/go-ethereum/blob/7519505d6fbd1fd29a8595aafbf880a04fb3e7e1/downloads.html#L299)