Merge branch 'master' into downloads-desktop
This commit is contained in:
commit
4079c37950
@ -21,7 +21,7 @@
|
||||
"@next/mdx": "^12.3.0",
|
||||
"focus-visible": "^5.2.0",
|
||||
"framer-motion": "^7.3.2",
|
||||
"next": "^12.3.0",
|
||||
"next": "^13.0.2",
|
||||
"react": "18.2.0",
|
||||
"react-dom": "18.2.0",
|
||||
"react-syntax-highlighter": "^15.5.0"
|
||||
|
BIN
public/images/docs/state-pruning.png
Normal file
BIN
public/images/docs/state-pruning.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 742 KiB |
@ -20,7 +20,13 @@ export const Header: FC = () => {
|
||||
borderRight={{ base: 'none', sm: '2px solid #11866f' }}
|
||||
flexGrow={2}
|
||||
>
|
||||
<Text textStyle='header-font'>go-ethereum</Text>
|
||||
<NextLink href={'/'} passHref>
|
||||
<Link _hover={{ textDecoration: 'none' }}>
|
||||
<Text textStyle='header-font'>
|
||||
go-ethereum
|
||||
</Text>
|
||||
</Link>
|
||||
</NextLink>
|
||||
</Stack>
|
||||
|
||||
<Flex>
|
||||
|
@ -1,109 +0,0 @@
|
||||
---
|
||||
title: Built-in tracers
|
||||
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.
|
||||
|
||||
## Struct logger
|
||||
|
||||
Struct logger or 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:
|
||||
|
||||
| field | type | description |
|
||||
| ---------- | ------------- | -------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| pc | uint64 | program counter |
|
||||
| op | byte | opcode to be executed |
|
||||
| gas | uint64 | remaining gas |
|
||||
| gasCost | uint64 | cost for executing op |
|
||||
| memory | []byte | EVM memory. Enabled via `enableMemory` |
|
||||
| memSize | int | Size of memory |
|
||||
| stack | []uint256 | EVM stack. Disabled via `disableStack` |
|
||||
| returnData | []byte | Last call's return data. Enabled via `enableReturnData` |
|
||||
| storage | map[hash]hash | Storage slots of current contract read from and written to. Only emitted for `SLOAD` and `SSTORE`. Disabled via `disableStorage` |
|
||||
| depth | int | Current call depth |
|
||||
| refund | uint64 | Refund counter |
|
||||
| error | string | Error message if any |
|
||||
|
||||
Note that the fields `memory`, `stack`, `returnData`, and `storage` have dynamic size and depending on the exact transaction they could grow large in size. This is specially true for `memory` which could blow up the trace size. It is recommended to keep them disabled unless they are explicitly required for a given use-case.
|
||||
|
||||
## Native tracers
|
||||
|
||||
The following tracers are implement in Go and as such have offer good performance. They are selected by their name when invoking a tracing API method, e.g. `debug.traceTransaction(<txhash>, { tracer: 'callTracer' })`.
|
||||
|
||||
### 4byteTracer
|
||||
|
||||
Solidity contract functions are [addressed](https://docs.soliditylang.org/en/develop/abi-spec.html#function-selector) by the first four four byte of the Keccak-256 hash of their signature. Therefore when calling the function of a contract, the caller must send this function selector as well as the ABI-encoded arguments as call data.
|
||||
|
||||
The `4byteTracer` collects the function selectors of every function executed in the lifetime of a transaction, along with the size of the supplied call data. The result is a `map[string]int` where the keys are `SELECTOR-CALLDATASIZE` and the values are number of occurances of this key. E.g.:
|
||||
|
||||
```terminal
|
||||
> debug.traceTransaction( "0x214e597e35da083692f5386141e69f47e973b2c56e7a8073b1ea08fd7571e9de", {tracer: "4byteTracer"})
|
||||
{
|
||||
"0x27dc297e-128": 1,
|
||||
"0x38cc4831-0": 2,
|
||||
"0x524f3889-96": 1,
|
||||
"0xadf59f99-288": 1,
|
||||
"0xc281d19e-0": 1
|
||||
}
|
||||
```
|
||||
|
||||
### callTracer
|
||||
|
||||
The `callTracer` tracks all the call frames executed during a transaction, including depth 0. The result will be a nested list of call frames, resembling how EVM works. They form a tree with the top-level call at root and sub-calls as children of the higher levels. Each call frame has the following fields:
|
||||
|
||||
| field | type | description |
|
||||
| ------- | ----------- | ------------------------------------ |
|
||||
| type | string | CALL or CREATE |
|
||||
| from | string | address |
|
||||
| to | string | address |
|
||||
| value | string | hex-encoded amount of value transfer |
|
||||
| gas | string | hex-encoded gas provided for call |
|
||||
| gasUsed | string | hex-encoded gas used during call |
|
||||
| input | string | call data |
|
||||
| output | string | return data |
|
||||
| error | string | error, if any |
|
||||
| calls | []callframe | list of sub-calls |
|
||||
|
||||
Things to note about the call tracer:
|
||||
|
||||
- Calls to precompiles are also included in the result
|
||||
- In case a frame reverts, the field `output` will contain the raw return data, unlike [revertReasonTracer](#revertreasontracer) which parses the data and returns the revert message
|
||||
|
||||
### noopTracer
|
||||
|
||||
This tracer is noop. It returns an empty object and is only meant for testing the setup.
|
||||
|
||||
### prestateTracer
|
||||
|
||||
Executing a transaction requires the prior state, including account of sender and recipient, contracts that are called during execution, etc. The `prestateTracer` replays the tx and tracks every part of state that is touched. This is similar to the concept of a [stateless witness](https://ethresear.ch/t/the-stateless-client-concept/172), the difference being this tracer doesn't return any cryptographic proof, rather only the trie leaves. The result is an object. The keys are addresses of accounts. The value is an object with the following fields:
|
||||
|
||||
| field | type | description |
|
||||
| ------- | ----------------- | ----------------------------- |
|
||||
| balance | string | balance in Wei |
|
||||
| nonce | uint64 | nonce |
|
||||
| code | string | hex-encoded bytecode |
|
||||
| storage | map[string]string | storage slots of the contract |
|
||||
|
||||
### revertReasonTracer
|
||||
|
||||
The `revertReasonTracer` is useful for analyzing failed transactions. The return value is:
|
||||
|
||||
- In case the transaction reverted: reason of the revert as returned by the Solidity contract
|
||||
- Error message for any other failure
|
||||
|
||||
Example:
|
||||
|
||||
```terminal
|
||||
> debug.traceTransaction('0x97695ffb034be7e1faeb372a564bb951ba4ebf4fee4caff2f9d1702497bb2b8b', { tracer: 'revertReasonTracer' })
|
||||
"execution reverted: tokensMintedPerAddress exceed MAX_TOKENS_MINTED_PER_ADDRESS"
|
||||
```
|
||||
|
||||
## JS tracers
|
||||
|
||||
The following are a list of tracers written in JS that come as part of Geth:
|
||||
|
||||
- `bigramTracer`: Counts the opcode bigrams, i.e. how many times 2 opcodes were executed one after the other
|
||||
- `evmdisTracer`: Returns sufficient information from a trace to perform [evmdis](https://github.com/Arachnid/evmdis)-style disassembly
|
||||
- `opcountTracer` Counts the total number of opcodes executed
|
||||
- `trigramTracer`: Counts the opcode trigrams
|
||||
- `unigramTracer`: Counts the occurances of each opcode
|
@ -1,155 +0,0 @@
|
||||
---
|
||||
title: EVM Tracing
|
||||
description: Introduction to tracing EVM transactions using Geth
|
||||
---
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
## Tracing prerequisites
|
||||
|
||||
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.
|
||||
|
||||
In order for an Ethereum node to reexecute a transaction, all historical state accessed by the transaction must be available. This includes:
|
||||
|
||||
- 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.
|
||||
- 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 pruning configuration of a node.
|
||||
|
||||
- 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.
|
||||
|
||||
- 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.
|
||||
|
||||
- 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,
|
||||
**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.
|
||||
|
||||
_There are exceptions to the above rules when running batch traces of entire blocks or chain segments. Those will be detailed later._
|
||||
|
||||
## Basic traces
|
||||
|
||||
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_:
|
||||
|
||||
```json
|
||||
{
|
||||
"gas": 25523,
|
||||
"failed": false,
|
||||
"returnValue": "",
|
||||
"structLogs": []
|
||||
}
|
||||
```
|
||||
|
||||
An example log for a single opcode entry has the following format:
|
||||
|
||||
```json
|
||||
{
|
||||
"pc": 48,
|
||||
"op": "DIV",
|
||||
"gasCost": 5,
|
||||
"gas": 64532,
|
||||
"depth": 1,
|
||||
"error": null,
|
||||
"stack": [
|
||||
"00000000000000000000000000000000000000000000000000000000ffffffff",
|
||||
"0000000100000000000000000000000000000000000000000000000000000000",
|
||||
"2df07fbaabbe40e3244445af30759352e348ec8bebd4dd75467a9f29ec55d98d"
|
||||
],
|
||||
"memory": [
|
||||
"0000000000000000000000000000000000000000000000000000000000000000",
|
||||
"0000000000000000000000000000000000000000000000000000000000000000",
|
||||
"0000000000000000000000000000000000000000000000000000000000000060"
|
||||
],
|
||||
"storage": {}
|
||||
}
|
||||
```
|
||||
|
||||
### Generating basic traces
|
||||
|
||||
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).
|
||||
|
||||
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:
|
||||
|
||||
```js
|
||||
debug.traceTransaction('0xfc9359e49278b7ba99f59edac0e3de49956e46e530a53c15aa71226b7aa92c6f');
|
||||
```
|
||||
|
||||
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`.
|
||||
|
||||
```
|
||||
$ 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 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:
|
||||
|
||||
```shell
|
||||
enableMemory: true
|
||||
disableStack: false
|
||||
disableStorage: false
|
||||
enableReturnData: true
|
||||
```
|
||||
|
||||
An example call, made in the Geth Javascript console, configured to report the maximum amount of data looks as follows:
|
||||
|
||||
```js
|
||||
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) 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) 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
|
||||
```
|
||||
|
||||
### Limits of basic traces
|
||||
|
||||
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.
|
||||
|
||||
## Pruning
|
||||
|
||||
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
|
||||
anything other than an archive node.
|
||||
|
||||
```sh
|
||||
Error: required historical state unavailable (reexec=128)
|
||||
at web3.js:6365:37(47)
|
||||
at send (web3,js:5099:62(35))
|
||||
at <eval>:1:23(13)
|
||||
```
|
||||
|
||||
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.
|
||||
|
||||
For tracing a transaction in block `B` where the pivot block is `P` can regenerate the desired 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 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 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`) 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 between `P` and `B` is large, the regeneration time can be substantial.
|
||||
|
||||
## Summary
|
||||
|
||||
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).
|
||||
|
||||
[evm]:
|
463
src/pages/docs/developers/evm-tracing/built-in-tracers.md
Normal file
463
src/pages/docs/developers/evm-tracing/built-in-tracers.md
Normal file
@ -0,0 +1,463 @@
|
||||
---
|
||||
title: Built-in tracers
|
||||
description: Explanation of the tracers that come bundled in Geth as part of the tracing API.
|
||||
---
|
||||
|
||||
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
|
||||
|
||||
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:
|
||||
|
||||
| field | type | description |
|
||||
| ---------- | ------------- | -------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| pc | uint64 | program counter |
|
||||
| op | byte | opcode to be executed |
|
||||
| gas | uint64 | remaining gas |
|
||||
| gasCost | uint64 | cost for executing op |
|
||||
| memory | []byte | EVM memory. Enabled via `enableMemory` |
|
||||
| memSize | int | Size of memory |
|
||||
| stack | []uint256 | EVM stack. Disabled via `disableStack` |
|
||||
| returnData | []byte | Last call's return data. Enabled via `enableReturnData` |
|
||||
| storage | map[hash]hash | Storage slots of current contract read from and written to. Only emitted for `SLOAD` and `SSTORE`. Disabled via `disableStorage` |
|
||||
| depth | int | Current call depth |
|
||||
| refund | uint64 | Refund counter |
|
||||
| error | string | Error message if any |
|
||||
|
||||
Note that the fields `memory`, `stack`, `returnData`, and `storage` have dynamic size and depending on the exact transaction they could grow large in size. This is specially true for `memory` which could blow up the trace size. It is recommended to keep them disabled unless they are explicitly required for a given use-case.
|
||||
|
||||
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
|
||||
disableStack: false
|
||||
disableStorage: false
|
||||
enableReturnData: true
|
||||
```
|
||||
|
||||
An example call:
|
||||
|
||||
```js
|
||||
debug.traceTransaction('0xfc9359e49278b7ba99f59edac0e3de49956e46e530a53c15aa71226b7aa92c6f', {
|
||||
enableMemory: true,
|
||||
disableStack: false,
|
||||
disableStorage: false,
|
||||
enableReturnData: true
|
||||
});
|
||||
```
|
||||
|
||||
Return:
|
||||
|
||||
```terminal
|
||||
{
|
||||
"gas":25523,
|
||||
"failed":false,
|
||||
"returnValue":"",
|
||||
"structLogs":[
|
||||
{
|
||||
"pc":0,
|
||||
"op":"PUSH1",
|
||||
"gas":64580,
|
||||
"gasCost":3,
|
||||
"depth":1,
|
||||
"error":null,
|
||||
"stack":[
|
||||
|
||||
],
|
||||
"memory":null,
|
||||
"storage":{
|
||||
|
||||
}
|
||||
},
|
||||
{
|
||||
"pc":2,
|
||||
"op":"PUSH1",
|
||||
"gas":64577,
|
||||
"gasCost":3,
|
||||
"depth":1,
|
||||
"error":null,
|
||||
"stack":[
|
||||
"0000000000000000000000000000000000000000000000000000000000000060"
|
||||
],
|
||||
"memory":null,
|
||||
"storage":{
|
||||
|
||||
}
|
||||
},
|
||||
|
||||
...
|
||||
|
||||
```
|
||||
|
||||
## Native tracers
|
||||
|
||||
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
|
||||
|
||||
Solidity contract functions are [addressed](https://docs.soliditylang.org/en/develop/abi-spec.html#function-selector) using the first four four byte of the Keccak-256 hash of their signature. Therefore when calling the function of a contract, the caller must send this function selector as well as the ABI-encoded arguments as call data.
|
||||
|
||||
The `4byteTracer` collects the function selectors of every function executed in the lifetime of a transaction, along with the size of the supplied call data. The result is a `map[string]int` where the keys are `SELECTOR-CALLDATASIZE` and the values are number of occurances of this key. For example:
|
||||
|
||||
Example call:
|
||||
|
||||
```sh
|
||||
debug.traceTransaction( "0x214e597e35da083692f5386141e69f47e973b2c56e7a8073b1ea08fd7571e9de", {tracer: "4byteTracer"})
|
||||
```
|
||||
|
||||
Return:
|
||||
|
||||
```terminal
|
||||
{
|
||||
"0x27dc297e-128": 1,
|
||||
"0x38cc4831-0": 2,
|
||||
"0x524f3889-96": 1,
|
||||
"0xadf59f99-288": 1,
|
||||
"0xc281d19e-0": 1
|
||||
}
|
||||
```
|
||||
|
||||
### callTracer
|
||||
|
||||
The `callTracer` tracks all the call frames executed during a transaction, including depth 0. The result will be a nested list of call frames, resembling how EVM works. They form a tree with the top-level call at root and sub-calls as children of the higher levels. Each call frame has the following fields:
|
||||
|
||||
| field | type | description |
|
||||
| ------- | ----------- | ------------------------------------ |
|
||||
| type | string | CALL or CREATE |
|
||||
| from | string | address |
|
||||
| to | string | address |
|
||||
| value | string | hex-encoded amount of value transfer |
|
||||
| gas | string | hex-encoded gas provided for call |
|
||||
| gasUsed | string | hex-encoded gas used during call |
|
||||
| input | string | call data |
|
||||
| output | string | return data |
|
||||
| error | string | error, if any |
|
||||
| calls | []callframe | list of sub-calls |
|
||||
|
||||
|
||||
Example Call:
|
||||
|
||||
```sh
|
||||
> debug.traceTransaction("0x44bed3dc0f584b2a2ab32f5e2948abaaca13917eeae7ae3b959de3371a6e9a95", {tracer: 'callTracer'})
|
||||
```
|
||||
|
||||
Return:
|
||||
|
||||
```terminal
|
||||
{
|
||||
calls: [{
|
||||
from: "0xc8ba32cab1757528daf49033e3673fae77dcf05d",
|
||||
gas: "0x18461",
|
||||
gasUsed: "0x60",
|
||||
input: "0x000000204895cd480cc8412691a880028a25aec86786f1ed2aa5562bc400000000000000c6403c14f35be1da6f433eadbb6e9178a47fbc7c6c1d568d2f2b876e929089c8d8db646304fd001a187dc8a6",
|
||||
output: "0x557904b74478f8810cc02198544a030d1829bb491e14fe1dd0354e933c5e87bd",
|
||||
to: "0x0000000000000000000000000000000000000002",
|
||||
type: "STATICCALL"
|
||||
}, {
|
||||
from: "0xc8ba32cab1757528daf49033e3673fae77dcf05d",
|
||||
gas: "0x181db",
|
||||
gasUsed: "0x48",
|
||||
input: "0x557904b74478f8810cc02198544a030d1829bb491e14fe1dd0354e933c5e87bd",
|
||||
output: "0x5fb393023b12544491a5b8fb057943b4ebf5b1401e88e44a7800000000000000",
|
||||
to: "0x0000000000000000000000000000000000000002",
|
||||
type: "STATICCALL"
|
||||
}],
|
||||
from: "0x35a9f94af726f07b5162df7e828cc9dc8439e7d0",
|
||||
gas: "0x1a310",
|
||||
gasUsed: "0xfcb6",
|
||||
input: "0xd1a2eab2000000000000000000000000000000000000000000000000000000000024aea100000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000050000000204895cd480cc8412691a880028a25aec86786f1ed2aa5562bc400000000000000c6403c14f35be1da6f433eadbb6e9178a47fbc7c6c1d568d2f2b876e929089c8d8db646304fd001a187dc8a600000000000000000000000000000000",
|
||||
to: "0xc8ba32cab1757528daf49033e3673fae77dcf05d",
|
||||
type: "CALL",
|
||||
value: "0x0"
|
||||
}
|
||||
```
|
||||
|
||||
Things to note about the call tracer:
|
||||
|
||||
- Calls to precompiles are also included in the result
|
||||
- In case a frame reverts, the field `output` will contain the raw return data, unlike [revertReasonTracer](#revertreasontracer) which parses the data and returns the revert message
|
||||
|
||||
|
||||
### prestateTracer
|
||||
|
||||
The prestate tracer has two modes: `prestate` and `diff`. The `prestate` mode returns the accounts necessary to execute a given transaction. `diff` mode returns the differences between the transaction's pre and post-state (i.e. what changed because the transaction happened). The `prestateTracer` defaults to `prestate` mode. It reexecutes the given transaction and tracks every part of state that is touched. This is similar to the concept of a [stateless witness](https://ethresear.ch/t/the-stateless-client-concept/172), the difference being this tracer doesn't return any cryptographic proof, rather only the trie leaves. The result is an object. The keys are addresses of accounts. The value is an object with the following fields:
|
||||
|
||||
| field | type | description |
|
||||
| ------- | ----------------- | ----------------------------- |
|
||||
| balance | string | balance in Wei |
|
||||
| nonce | uint64 | nonce |
|
||||
| code | string | hex-encoded bytecode |
|
||||
| storage | map[string]string | storage slots of the contract |
|
||||
|
||||
To run this tracer in `diff` mode, pass `tracerConfig: {diffMode: true}` in the APi call.
|
||||
|
||||
Example:
|
||||
|
||||
```js
|
||||
debug.traceCall({from: "0x35a9f94af726f07b5162df7e828cc9dc8439e7d0", to: "0xc8ba32cab1757528daf49033e3673fae77dcf05d", data: "0xd1a2eab2000000000000000000000000000000000000000000000000000000000024aea100000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000050000000204895cd480cc8412691a880028a25aec86786f1ed2aa5562bc400000000000000c6403c14f35be1da6f433eadbb6e9178a47fbc7c6c1d568d2f2b876e929089c8d8db646304fd001a187dc8a600000000000000000000000000000000"}, 'latest', {tracer: 'prestateTracer'})
|
||||
```
|
||||
|
||||
Return:
|
||||
|
||||
```terminal
|
||||
{
|
||||
0x0000000000000000000000000000000000000002: {
|
||||
balance: "0x0"
|
||||
},
|
||||
0x008b3b2f992c0e14edaa6e2c662bec549caa8df1: {
|
||||
balance: "0x2638035a26d133809"
|
||||
},
|
||||
0x35a9f94af726f07b5162df7e828cc9dc8439e7d0: {
|
||||
balance: "0x7a48734599f7284",
|
||||
nonce: 1133
|
||||
},
|
||||
0xc8ba32cab1757528daf49033e3673fae77dcf05d: {
|
||||
balance: "0x0",
|
||||
code: "0x608060405234801561001057600080fd5b50600436106100885760003560e01c8063a9c2d...
|
||||
nonce: 1,
|
||||
storage: {
|
||||
0x0000000000000000000000000000000000000000000000000000000000000000: "0x000000000000000000000000000000000000000000000000000000000024aea6",
|
||||
0x59fb7853eb21f604d010b94c123acbeae621f09ce15ee5d7616485b1e78a72e9: "0x00000000000000c42b56a52aedf18667c8ae258a0280a8912641c80c48cd9548",
|
||||
0x8d8ebb65ec00cb973d4fe086a607728fd1b9de14aa48208381eed9592f0dee9a: "0x00000000000000784ae4881e40b1f5ebb4437905fbb8a5914454123b0293b35f",
|
||||
0xff896b09014882056009dedb136458f017fcef9a4729467d0d00b4fd413fb1f1: "0x000000000000000e78ac39cb1c20e9edc753623b153705d0ccc487e31f9d6749"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Return (same call with `{diffMode: True}`):
|
||||
|
||||
```terminal
|
||||
{
|
||||
post: {
|
||||
0x35a9f94af726f07b5162df7e828cc9dc8439e7d0: {
|
||||
nonce: 1135
|
||||
}
|
||||
},
|
||||
pre: {
|
||||
0x35a9f94af726f07b5162df7e828cc9dc8439e7d0: {
|
||||
balance: "0x7a48429e177130a",
|
||||
nonce: 1134
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
### revertReasonTracer
|
||||
|
||||
The `revertReasonTracer` is useful for analyzing failed transactions. If the transaction reverted, the reason for the revert (according to the Solidity contract) is returned. For any other failure, the error message is returned.
|
||||
|
||||
Example:
|
||||
|
||||
```js
|
||||
> debug.traceTransaction('0x97695ffb034be7e1faeb372a564bb951ba4ebf4fee4caff2f9d1702497bb2b8b', { tracer: 'revertReasonTracer' })
|
||||
```
|
||||
|
||||
Returns:
|
||||
|
||||
```terminal
|
||||
"execution reverted: tokensMintedPerAddress exceed MAX_TOKENS_MINTED_PER_ADDRESS"
|
||||
```
|
||||
|
||||
### noopTracer
|
||||
|
||||
This tracer is noop. It returns an empty object and is only meant for testing the setup.
|
||||
|
||||
|
||||
## Javascript 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.
|
||||
|
||||
### bigram
|
||||
|
||||
`bigramTracer` counts the opcode bigrams, i.e. how many times 2 opcodes were executed one after the other.
|
||||
|
||||
Example:
|
||||
|
||||
```js
|
||||
debug.traceCall({from: "0x35a9f94af726f07b5162df7e828cc9dc8439e7d0", to: "0xc8ba32cab1757528daf49033e3673fae77dcf05d", data: "0xd1a2eab2000000000000000000000000000000000000000000000000000000000024aea100000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000050000000204895cd480cc8412691a880028a25aec86786f1ed2aa5562bc400000000000000c6403c14f35be1da6f433eadbb6e9178a47fbc7c6c1d568d2f2b876e929089c8d8db646304fd001a187dc8a600000000000000000000000000000000"}, 'latest', {tracer: 'bigramTracer'})
|
||||
```
|
||||
|
||||
Returns:
|
||||
|
||||
```terminal
|
||||
{
|
||||
ADD-ADD: 1,
|
||||
ADD-AND: 2,
|
||||
ADD-CALLDATALOAD: 1,
|
||||
ADD-DUP1: 2,
|
||||
ADD-DUP2: 2,
|
||||
ADD-GT: 1,
|
||||
ADD-MLOAD: 1,
|
||||
ADD-MSTORE: 4,
|
||||
ADD-PUSH1: 1,
|
||||
ADD-PUSH2: 4,
|
||||
ADD-SLT: 1,
|
||||
ADD-SWAP1: 10,
|
||||
ADD-SWAP2: 1,
|
||||
ADD-SWAP3: 1,
|
||||
ADD-SWAP4: 3,
|
||||
ADD-SWAP5: 1,
|
||||
AND-DUP3: 2,
|
||||
AND-ISZERO: 4,
|
||||
...
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
### evmdis
|
||||
|
||||
`evmdisTracer` returns sufficient information from a trace to perform [evmdis](https://github.com/Arachnid/evmdis)-style disassembly
|
||||
|
||||
Example:
|
||||
|
||||
```js
|
||||
> debug.traceCall({from: "0x35a9f94af726f07b5162df7e828cc9dc8439e7d0", to: "0xc8ba32cab1757528daf49033e3673fae77dcf05d", data: "0xd1a2eab2000000000000000000000000000000000000000000000000000000000024aea100000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000050000000204895cd480cc8412691a880028a25aec86786f1ed2aa5562bc400000000000000c6403c14f35be1da6f433eadbb6e9178a47fbc7c6c1d568d2f2b876e929089c8d8db646304fd001a187dc8a600000000000000000000000000000000"}, 'latest', {tracer: 'evmdisTracer'})
|
||||
```
|
||||
|
||||
Returns:
|
||||
|
||||
```terminal
|
||||
[{
|
||||
depth: 1,
|
||||
len: 2,
|
||||
op: 96,
|
||||
result: ["80"]
|
||||
}, {
|
||||
depth: 1,
|
||||
len: 2,
|
||||
op: 96,
|
||||
result: ["40"]
|
||||
}, {
|
||||
depth: 1,
|
||||
op: 82,
|
||||
result: []
|
||||
}, {
|
||||
depth: 1,
|
||||
op: 52,
|
||||
result: ["0"]
|
||||
}, {
|
||||
depth: 1,
|
||||
op: 128,
|
||||
result: ["0", "0"]
|
||||
}, {
|
||||
depth: 1,
|
||||
op: 21,
|
||||
result: ["1"]
|
||||
}, {
|
||||
depth: 1,
|
||||
len: 3,
|
||||
op: 97,
|
||||
result: ["10"]
|
||||
}, {
|
||||
depth: 1,
|
||||
op: 87,
|
||||
result: []
|
||||
}, {
|
||||
depth: 1,
|
||||
op: 91,
|
||||
pc: 16,
|
||||
result: []
|
||||
},
|
||||
...
|
||||
```
|
||||
|
||||
### opcount
|
||||
|
||||
`opcountTracer` counts the total number of opcodes executed and simply returns the number.
|
||||
|
||||
Example:
|
||||
|
||||
```js
|
||||
debug.traceCall({from: "0x35a9f94af726f07b5162df7e828cc9dc8439e7d0", to: "0xc8ba32cab1757528daf49033e3673fae77dcf05d", data: "0xd1a2eab2000000000000000000000000000000000000000000000000000000000024aea100000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000050000000204895cd480cc8412691a880028a25aec86786f1ed2aa5562bc400000000000000c6403c14f35be1da6f433eadbb6e9178a47fbc7c6c1d568d2f2b876e929089c8d8db646304fd001a187dc8a600000000000000000000000000000000"}, 'latest', {tracer: 'opcountTracer'})
|
||||
```
|
||||
|
||||
Returns:
|
||||
|
||||
```terminal
|
||||
1384
|
||||
```
|
||||
|
||||
### trigram
|
||||
`trigramTracer` counts the opcode trigrams. Trigrams are the possible combinations of three opcodes this tracer reports how many times each combination is seen during execution.
|
||||
|
||||
Example:
|
||||
|
||||
```js
|
||||
debug.traceCall({from: "0x35a9f94af726f07b5162df7e828cc9dc8439e7d0", to: "0xc8ba32cab1757528daf49033e3673fae77dcf05d", data: "0xd1a2eab2000000000000000000000000000000000000000000000000000000000024aea100000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000050000000204895cd480cc8412691a880028a25aec86786f1ed2aa5562bc400000000000000c6403c14f35be1da6f433eadbb6e9178a47fbc7c6c1d568d2f2b876e929089c8d8db646304fd001a187dc8a600000000000000000000000000000000"}, 'latest', {tracer: 'trigramTracer'})
|
||||
```
|
||||
|
||||
Returns:
|
||||
```terminal
|
||||
{
|
||||
--PUSH1: 1,
|
||||
-PUSH1-MSTORE: 1,
|
||||
ADD-ADD-GT: 1,
|
||||
ADD-AND-DUP3: 2,
|
||||
ADD-CALLDATALOAD-PUSH8: 1,
|
||||
ADD-DUP1-PUSH1: 2,
|
||||
ADD-DUP2-ADD: 1,
|
||||
ADD-DUP2-MSTORE: 1,
|
||||
ADD-GT-ISZERO: 1,
|
||||
ADD-MLOAD-DUP6: 1,
|
||||
ADD-MSTORE-ADD: 1,
|
||||
ADD-MSTORE-PUSH1: 2,
|
||||
ADD-MSTORE-PUSH32: 1,
|
||||
ADD-PUSH1-KECCAK256: 1,
|
||||
ADD-PUSH2-JUMP: 2,
|
||||
ADD-PUSH2-JUMPI: 1,
|
||||
ADD-PUSH2-SWAP2: 1,
|
||||
ADD-SLT-PUSH2: 1,
|
||||
...
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
### unigram
|
||||
|
||||
`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,
|
||||
AND: 23,
|
||||
BYTE: 4,
|
||||
CALLDATACOPY: 1,
|
||||
CALLDATALOAD: 6,
|
||||
CALLDATASIZE: 2,
|
||||
CALLVALUE: 1,
|
||||
DIV: 9,
|
||||
DUP1: 29,
|
||||
DUP10: 2,
|
||||
DUP11: 1,
|
||||
DUP12: 3,
|
||||
DUP13: 2,
|
||||
...
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
## 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.
|
||||
|
||||
|
||||
To do this, the tracer is written as normal, but the parameter `stateOverrides` is passed an address and some bytecode.
|
||||
|
||||
```js
|
||||
var code = //contract bytecode
|
||||
var tracer = //tracer name
|
||||
debug.traceCall({from: , to: , input: }, 'latest', {stateOverrides: {'0x...': {code: code}}, tracer: tracer})
|
||||
```
|
||||
|
||||
## Summary
|
||||
|
||||
This page showed how to use the tracers that come bundled with Geth. There are a set written in Go and a set written in Javascript. They are invoked by passing their names when calling an API method.
|
@ -397,7 +397,7 @@ func (t *opcounter) Stop(err error) {
|
||||
}
|
||||
```
|
||||
|
||||
As can be seen every method of the [EVMLogger interface](https://pkg.go.dev/github.com/ethereum/go-ethereum/core/vm#EVMLogger) needs to be implemented (even if empty). Key parts to notice are the `init()` function which registers the tracer in Geth, the `CaptureState` hook where the opcode counts are incremented and `GetResult` where the result is serialized and delivered. To test this out the source is first compiled with `make geth`. Then in the console it can be invoked through the usual API methods by passing in the name it was registered under:
|
||||
Every method of the [EVMLogger interface](https://pkg.go.dev/github.com/ethereum/go-ethereum/core/vm#EVMLogger) needs to be implemented (even if empty). Key parts to notice are the `init()` function which registers the tracer in Geth, the `CaptureState` hook where the opcode counts are incremented and `GetResult` where the result is serialized and delivered. To test this, the source is first compiled with `make geth`. Then in the console it can be invoked through the usual API methods by passing in the name it was registered under:
|
||||
|
||||
```console
|
||||
> debug.traceTransaction('0x7ae446a7897c056023a8104d254237a8d97783a92900a7b0f7db668a9432f384', { tracer: 'opcounter' })
|
||||
@ -408,3 +408,7 @@ As can be seen every method of the [EVMLogger interface](https://pkg.go.dev/gith
|
||||
...
|
||||
}
|
||||
```
|
||||
|
||||
## Summary
|
||||
|
||||
This page described how to write custom tracers for Geth. Custom tracers can be written in Javascript or Go.
|
70
src/pages/docs/developers/evm-tracing/index.md
Normal file
70
src/pages/docs/developers/evm-tracing/index.md
Normal file
@ -0,0 +1,70 @@
|
||||
---
|
||||
title: EVM Tracing
|
||||
description: Introduction to tracing EVM transactions using Geth
|
||||
---
|
||||
|
||||
---
|
||||
title: EVM Tracing
|
||||
sort-key: A
|
||||
---
|
||||
|
||||
Tracing allows users to examine precisely what was executed by the EVM during some specific transaction or set of transactions. There are two different types of [transactions](https://ethereum.org/en/developers/docs/transactions) in Ethereum: value transfers and contract executions. A value transfer just moves ETH from one account to another. A contract interaction executes some code stored at a contract address which can include altering stored data and transacting multiple times with other contracts and externally-owned accounts. A contract execution transaction can therefore be a complicated web of interactions that can be difficult to unpick. The transaction receipt contains a status code that shows whether the transaction succeeded or failed, but more detailed information is not readily available, meaning it is very difficult to know what a contract execution actually did, what data was modified and which addresses were touched. This is the problem that EVM tracing solves. Geth traces transactions by re-running them locally and collecting data about precisely what was executed by the EVM.
|
||||
|
||||
Also see this [Devcon 2022 talk](https://www.youtube.com/watch?v=b8RdmGsilfU) on tracing in Geth.
|
||||
|
||||
## State availability
|
||||
|
||||
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 an aggregated summary. In order for a Geth node to reexecute a transaction, all historical state accessed by the transaction must be available. This includes:
|
||||
|
||||
- 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.
|
||||
- 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 pruning configuration of a node:
|
||||
|
||||
- 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.
|
||||
|
||||
- A **node synced from genesis** node only retains the most recent 128 block states in memory. Older states are represented by a sequence of occasional checkpoints that intermediate states can be regenerated from. This means that states within the msot recent 128 blocks are immediately available, older states have to be regenerated from snapshots "on-the-fly". If the distance between the requested transaction and the most recent checkpoint is large, 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.
|
||||
|
||||
- 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,
|
||||
**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.
|
||||
|
||||
![state pruning options](/public/images/state-pruning.png)
|
||||
|
||||
*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](/pages/docs/fundamentals/sync-modes.md).
|
||||
|
||||
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`.
|
||||
|
||||
It is also possible to force Geth to store the state for specific sequences of block by stopping Geth, running again with `--gcmode archive` for some period - this prevents state prunign for blocks that arrive while Geth is running with `--gcmode archive`.
|
||||
|
||||
_There are exceptions to the above rules when running batch traces of entire blocks or chain segments. Those will be detailed later._
|
||||
|
||||
## Types of trace
|
||||
|
||||
### 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
|
||||
functions that do some specific preprocessing on the trace data before it is returned.
|
||||
|
||||
More information about Geth's built-in tracers is available on the
|
||||
[built-in tracers](/pages/docs/developers/evm-tracing/built-in-tracers.md)
|
||||
page.
|
||||
|
||||
|
||||
### 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](/pages/docs/developers/evm-tracing/custom-tracers.md) page.
|
||||
|
||||
## 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. on their dedicated pages.
|
@ -52,7 +52,76 @@ go test -v -bench . -run BenchmarkJoin
|
||||
|
||||
For more information, see the [go test flags](https://golang.org/cmd/go/#hdr-Testing_flags) documentation.
|
||||
|
||||
### Stack Traces
|
||||
### Getting Stack Traces
|
||||
|
||||
A stack trace provides a very detailed look into the current state of the geth node. It helps us to debug issues easier as it contains information about what is currently done by the node. Stack traces can be created by running `debug.stacks()` in the Geth console. If the node was started without the console command or with a script in the background, the following command can be used to dump the stack trace into a file.
|
||||
|
||||
```
|
||||
geth attach <path-to-geth.ipc> --exec "debug.stacks()" > stacktrace.txt
|
||||
```
|
||||
|
||||
Geth logs the location of the IPC endpoint on startup. It is typically under `/home/user/.ethereum/geth.ipc` or `/tmp/geth.ipc`.
|
||||
|
||||
`debug.stacks()` also takes an optional `filter` argument. Passing a package name or filepath to `filter` restricts the output to stack traces involcing only that package/file. For example:
|
||||
|
||||
```sh
|
||||
debug.stacks("enode")
|
||||
```
|
||||
|
||||
returns data that looks like:
|
||||
|
||||
```terminal
|
||||
INFO [11-04|16:15:54.486] Expanded filter expression filter=enode expanded="`enode` in Value"
|
||||
goroutine 121 [chan receive, 3 minutes]:
|
||||
github.com/ethereum/go-ethereum/p2p/enode.(*FairMix).nextFromAny(...)
|
||||
github.com/ethereum/go-ethereum/p2p/enode/iter.go:241
|
||||
github.com/ethereum/go-ethereum/p2p/enode.(*FairMix).Next(0xc0008c6060)
|
||||
github.com/ethereum/go-ethereum/p2p/enode/iter.go:215 +0x2c5
|
||||
github.com/ethereum/go-ethereum/p2p.(*dialScheduler).readNodes(0xc00021c2c0, {0x18149b0, 0xc0008c6060})
|
||||
github.com/ethereum/go-ethereum/p2p/dial.go:321 +0x9f
|
||||
created by github.com/ethereum/go-ethereum/p2p.newDialScheduler
|
||||
github.com/ethereum/go-ethereum/p2p/dial.go:179 +0x425
|
||||
```
|
||||
|
||||
and
|
||||
```sh
|
||||
debug.stacks("consolecmd.go")
|
||||
```
|
||||
|
||||
returns data that looks like:
|
||||
|
||||
```terminal
|
||||
INFO [11-04|16:16:47.141] Expanded filter expression filter=consolecmd.go expanded="`consolecmd.go` in Value"
|
||||
goroutine 1 [chan receive]:
|
||||
github.com/ethereum/go-ethereum/internal/jsre.(*JSRE).Do(0xc0004223c0, 0xc0003c00f0)
|
||||
github.com/ethereum/go-ethereum/internal/jsre/jsre.go:230 +0xf4
|
||||
github.com/ethereum/go-ethereum/internal/jsre.(*JSRE).Evaluate(0xc00033eb60?, {0xc0013c00a0, 0x1e}, {0x180d720?, 0xc000010018})
|
||||
github.com/ethereum/go-ethereum/internal/jsre/jsre.go:289 +0xb3
|
||||
github.com/ethereum/go-ethereum/console.(*Console).Evaluate(0xc0005366e0, {0xc0013c00a0?, 0x0?})
|
||||
github.com/ethereum/go-ethereum/console/console.go:353 +0x6d
|
||||
github.com/ethereum/go-ethereum/console.(*Console).Interactive(0xc0005366e0)
|
||||
github.com/ethereum/go-ethereum/console/console.go:481 +0x691
|
||||
main.localConsole(0xc00026d580?)
|
||||
github.com/ethereum/go-ethereum/cmd/geth/consolecmd.go:109 +0x348
|
||||
github.com/ethereum/go-ethereum/internal/flags.MigrateGlobalFlags.func2.1(0x20b52c0?)
|
||||
github.com/ethereum/go-ethereum/internal/flags/helpers.go:91 +0x36
|
||||
github.com/urfave/cli/v2.(*Command).Run(0x20b52c0, 0xc000313540)
|
||||
github.com/urfave/cli/v2@v2.17.2-0.20221006022127-8f469abc00aa/command.go:177 +0x719
|
||||
github.com/urfave/cli/v2.(*App).RunContext(0xc0005501c0, {0x1816128?, 0xc000040110}, {0xc00003c180, 0x3, 0x3})
|
||||
github.com/urfave/cli/v2@v2.17.2-0.20221006022127-8f469abc00aa/app.go:387 +0x1035
|
||||
github.com/urfave/cli/v2.(*App).Run(...)
|
||||
github.com/urfave/cli/v2@v2.17.2-0.20221006022127-8f469abc00aa/app.go:252
|
||||
main.main()
|
||||
github.com/ethereum/go-ethereum/cmd/geth/main.go:266 +0x47
|
||||
|
||||
goroutine 159 [chan receive, 4 minutes]:
|
||||
github.com/ethereum/go-ethereum/node.(*Node).Wait(...)
|
||||
github.com/ethereum/go-ethereum/node/node.go:529
|
||||
main.localConsole.func1()
|
||||
github.com/ethereum/go-ethereum/cmd/geth/consolecmd.go:103 +0x2d
|
||||
created by main.localConsole
|
||||
github.com/ethereum/go-ethereum/cmd/geth/consolecmd.go:102 +0x32e
|
||||
```
|
||||
|
||||
If Geth is started with the `--pprof` option, a debugging HTTP server is made available on port 6060. Navigating to <http://localhost:6060/debug/pprof> displays the heap, running routines etc. By clicking "full goroutine stack dump" a trace can be generated that is useful for debugging.
|
||||
|
||||
|
@ -27,7 +27,7 @@ Starting Geth in developer mode is as simple as providing the `--dev` flag. It i
|
||||
Remix will be used to deploy a smart contract to the node which requires information to be exchanged externally to Geth's own domain. To permit this, enable `http` and the `net` namespace must be enabled and the Remix URL must be provided to `--http.corsdomain`. For this tutorial some other namespaces will also be enabled. The full command is as follows:
|
||||
|
||||
```shell
|
||||
geth --dev --http --http.api eth,web3,personal,net --http.corsdomain "http://remix.ethereum.org"
|
||||
geth --dev --http --http.api eth,web3,net --http.corsdomain "http://remix.ethereum.org"
|
||||
```
|
||||
|
||||
The terminal will display the following logs, confirming Geth has started successfully in developer mode:
|
||||
@ -83,7 +83,7 @@ Welcome to the Geth Javascript console!
|
||||
instance: Geth/v1.10.18-unstable-8d84a701-20220503/linux-amd64/go.1.18.1
|
||||
coinbase: 0x540dbaeb2390f2eb005f7a6dbf3436a0959197a9
|
||||
at block: 0 (Thu Jan 01 1970 01:00:00 GMT+0100 (BST))
|
||||
modules: eth:1.0 personal:1.0 rpc:1.0 web3:1.0
|
||||
modules: eth:1.0 rpc:1.0 web3:1.0
|
||||
|
||||
To exit, press ctrl-d or type exit
|
||||
>
|
||||
@ -118,10 +118,10 @@ Using `web3.fromWei()` is less error prone because the correct multiplier is bui
|
||||
1.157920892373162e+59
|
||||
```
|
||||
|
||||
A new account can be created and some of the ether from the coinbase transferred across to it. A new account is generated using the `newAccount` function in the `personal` namespace:
|
||||
A new account can be created using Clef. Some of the ether from the coinbase can then be transferred across to it. A new account is generated using the `newaccount` function on the command line:
|
||||
|
||||
```shell
|
||||
personal.newAccount()
|
||||
clef newaccount --keystore <path-to-keystore>
|
||||
```
|
||||
|
||||
The terminal will display a request for a password, twice. Once provided, a new account will be created and its address printed to the terminal. The account creation is also logged in the Geth terminal, including the location of the keyfile in the keystore. It is a good idea to back up the password somewhere at this point. If this were an account on a live network, intended to own assets of real-world value, it would be critical to back up the account password and the keystore in a secure manner.
|
||||
@ -280,7 +280,7 @@ The returned value is a left-padded hexadecimal value. For example, the return v
|
||||
This tutorial used an ephemeral blockchain that is completely destroyed and started afresh during each dev-mode session. However, it is also possible to create persistent blockchain and account data that can be reused across multiple sessions. This is done by providing the `--datadir` flag and a directory name when starting Geth in dev-mode.
|
||||
|
||||
```shell
|
||||
geth --datadir dev-chain --dev --http --http.api personal,web3,eth,net --http.corsdomain "remix.ethereum.org"
|
||||
geth --datadir dev-chain --dev --http --http.api web3,eth,net --http.corsdomain "remix.ethereum.org"
|
||||
```
|
||||
|
||||
## Re-using accounts
|
||||
@ -289,7 +289,7 @@ Geth will fail to start in dev-mode if keys have been manually created or import
|
||||
|
||||
```shell
|
||||
|
||||
geth --datadir dev-chain --dev --http --http.api personal,web3,eth,net --http.corsdomain "remix.ethereum.org" --password password.txt
|
||||
geth --datadir dev-chain --dev --http --http.api web3,eth,net --http.corsdomain "remix.ethereum.org" --password password.txt
|
||||
|
||||
```
|
||||
|
||||
|
@ -27,7 +27,7 @@ While the main network uses proof-of-work (PoW) to secure the blockchain, Geth a
|
||||
|
||||
#### Ethash
|
||||
|
||||
Geth's PoW algorithm, [Ethhash](https://ethereum.org/en/developers/docs/consensus-mechanisms/pow/mining-algorithms/ethash), is a system that allows open participation by anyone willing to dedicate resources to mining. While this is a critical property for a public network, the overall security of the blockchain strictly depends on the total amount of resources used to secure it. As such, PoW is a poor choice for private networks with few miners. The Ethash mining 'difficulty' is adjusted automatically so that new blocks are created approximately 12 seconds apart. As more mining resources are deployed on the network, creating a new block becomes harder so that the average block time matches the target block time.
|
||||
Geth's PoW algorithm, [Ethash](https://ethereum.org/en/developers/docs/consensus-mechanisms/pow/mining-algorithms/ethash), is a system that allows open participation by anyone willing to dedicate resources to mining. While this is a critical property for a public network, the overall security of the blockchain strictly depends on the total amount of resources used to secure it. As such, PoW is a poor choice for private networks with few miners. The Ethash mining 'difficulty' is adjusted automatically so that new blocks are created approximately 12 seconds apart. As more mining resources are deployed on the network, creating a new block becomes harder so that the average block time matches the target block time.
|
||||
|
||||
#### Clique
|
||||
|
||||
@ -388,19 +388,19 @@ TRACE[05-13|16:15:57.767] PING/v4 id=f1364e6d060c
|
||||
|
||||
It is now possible to attach a Javascript console to either node to query the network properties:
|
||||
|
||||
```shell
|
||||
```sh
|
||||
geth attach node1/geth.ipc
|
||||
```
|
||||
|
||||
Once the Javascript console is running, check that the node is connected to one other peer (node 2):
|
||||
|
||||
```shell
|
||||
```sh
|
||||
net.peerCount
|
||||
```
|
||||
|
||||
The details of this peer can also be queried and used to check that the peer really is Node 2:
|
||||
|
||||
```
|
||||
```sh
|
||||
admin.peers
|
||||
```
|
||||
|
||||
@ -441,9 +441,6 @@ eth.getBalance(eth.accounts[0])
|
||||
This account can then be unlocked and some ether sent to Node 2, using the following commands:
|
||||
|
||||
```javascript
|
||||
// unlock account
|
||||
personal.unlockAccount(eth.accounts[0]);
|
||||
|
||||
// send some Wei
|
||||
eth.sendTransaction({
|
||||
to: '0xc94d95a5106270775351eecfe43f97e8e75e59e8',
|
||||
|
@ -1,97 +1,155 @@
|
||||
---
|
||||
title: Account Management
|
||||
title: Account Management with Clef
|
||||
description: Guide to basic account management using Geth's built-in tools
|
||||
---
|
||||
|
||||
The recommended practise for managing accounts in Geth is to use Clef. However, Geth also has its own, convenient account management tools. Eventually, these built in tools will be deprecated in favour of using Clef as the default account manager. This page describes account management using Geth's built-in tools. It is recommended to also visit the following pages that explain how to use Clef.
|
||||
Geth uses an external signer called [Clef](/docs/clef/introduction) to manage accounts. This is a standalone pieve of software that runs independently of, but connects to, a Geth instance. Clef handles account creation, key management and signing transactions/data. This page explains how to use Clef to create and manage accounts for use with Geth. More information about Clef, including advanced setup options, are available in our dedicated Clef docs.
|
||||
|
||||
- [Getting started with Clef](/content/docs/getting_started/getting-started-with-clef.md)
|
||||
- [Introduction to Clef](/content/docs/tools/Clef/Introduction.md)
|
||||
- [Clef tutorial](/content/docs/tools/Clef/Tutorial.md)
|
||||
## Initialize Clef
|
||||
|
||||
## Account command
|
||||
The first time Clef is used it needs to be initialized with a master seed that unlocks Clef's secure vault and a path where the vault should be located. Clef will use the vault to store passwords for keystores, javascript auto-signing rules and hashes of rule files. To initialize Clef, pass a vault path to `clef init`, for example to store it in a new directory inside `/home/user/go-ethereum`:
|
||||
|
||||
Geth's `account` command is used to interact with accounts:
|
||||
|
||||
```
|
||||
geth account <command> [options...] [arguments...]
|
||||
```sh
|
||||
clef init /home/user/go-ethereum/clefdata
|
||||
```
|
||||
|
||||
The account command enables the user to create new accounts, list existing accounts, import private keys into a new account, update key formats and update the passwords that lock each account. In interactive mode, the user is prompted for passwords in the console when the `account` functions are invoked, whereas in non-interactive mode passwords to unlock accounts are saved to text files whose path is passed to Geth at startup. Non-interactive mode is only intended for use on private networks or known safe environments.
|
||||
It is extremely important to remember the master seed and keep it secure. It allows access to the accounts under Clef's management.
|
||||
|
||||
The `account` subcommands are:
|
||||
## Connecting Geth and Clef
|
||||
|
||||
```
|
||||
COMMANDS:
|
||||
list Print summary of existing accounts
|
||||
new Create a new account
|
||||
update Update an existing account
|
||||
import Import a private key into a new account
|
||||
Clef and Geth should be started separately but with complementary configurations so that they can communicate. This requires Clef to know the `chain_id` of the network Geth will connect to so that this information can be included in any signatures. Clef also needs to know the location of the keystore where accounts are (or will be) stored. This is usually in a subdirectory inside Geth's data directory. Clef is also given a data directory which is also often placed conveniently inside Geth's data directory. To enable communication with Clef using Curl, `--http` can be passed which will start an HTTP server on `localhost:8550` by default. To start Clef configured for a Geth node connecting to the Sepolia testnet:
|
||||
|
||||
```sh
|
||||
clef --chainid 11155111 --keystore ~/.go-ethereum/sepolia-data/keystore --configdir ~/go-ethereum/sepolia-data/clef --http
|
||||
```
|
||||
|
||||
Information about the subcommands can be displayed in the terminal using `geth account <command> --help`. For example, for the `list` subcommand:
|
||||
|
||||
```
|
||||
$ geth account list --help
|
||||
list [command options] [arguments...]
|
||||
|
||||
Print a short summary of all accounts
|
||||
|
||||
OPTIONS:
|
||||
--datadir "/home/.ethereum" Data directory for the databases and keystore
|
||||
--keystore Directory for the keystore (default = inside the datadir)
|
||||
```
|
||||
|
||||
## Creating new accounts
|
||||
|
||||
New accounts can be created using `account new`. This generates a new key pair and adds them to the `keystore` directory in the `datadir`. To
|
||||
create a new account in the default data directory:
|
||||
|
||||
```shell
|
||||
$ geth account new
|
||||
```
|
||||
|
||||
This returns the following to the terminal:
|
||||
Clef will start running in the terminal, beginning with a disclaimer and a prompt to click "ok":
|
||||
|
||||
```terminal
|
||||
Your new account is locked with a password. Please give a password. Do not forget this password.
|
||||
Passphrase:
|
||||
Repeat Passphrase:
|
||||
Address: {168bc315a2ee09042d83d7c5811b533620531f67}
|
||||
WARNING!
|
||||
|
||||
Clef is an account management tool. It may, like any software, contain bugs.
|
||||
|
||||
Please take care to
|
||||
- backup your keystore files,
|
||||
- verify that the keystore(s) can be opened with your password.
|
||||
|
||||
Clef is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY
|
||||
without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
PURPOSE. See the GNU General Public License for more details.
|
||||
|
||||
Enter 'ok' to proceed:
|
||||
>
|
||||
```
|
||||
|
||||
Geth can be started in a separate terminal. To connect to Clef, ensure the data directory is consistent with the path provided to Clef and pass the location of the the Clef IPC file - which Clef saves to the path provided to its `--configdir` flag - in this case we set it to `~/go-ethereum/sepolia-data/clef`:
|
||||
|
||||
```sh
|
||||
geth --sepolia --datadir sepolia <other flags> --signer=sepolia-data/clef/clef.ipc
|
||||
```
|
||||
|
||||
Remember that it is also necessary to have a consensus client running too, which requires `--http` and several `authrpc` values to be provided to Geth. A complete set of startup commands for the Geth-Lodestar client combinaton plus Clef is provided as an example in this [Gist](https://gist.github.com/jmcook1186/ea5de9215ecedb1b0105bcfa9c30d44c) - adapt it for different client combinations and configurations.
|
||||
|
||||
|
||||
## Interacting with Clef
|
||||
|
||||
There are two modes of interaction with Clef. One is direct interaction, which is achieved by passing requests by HTTP or IPC with JSON-RPC data as defined in Clef's external API. This is the way to do things in Clef that don't require Geth, such as creating and listing accounts, or signing data offline. The other way is via Geth. With Geth started with Clef as an external signer, requests made to Geth that touch account data will route via Clef for approval. By default, the user approves or denies interactions manually by typing `y` or `n` into the Clef console when prompted, but custom rules can also be created to automate common tasks.
|
||||
|
||||
### Creating accounts
|
||||
|
||||
New accounts can be created using Clef's `account new` method. This generates a new key pair and adds them to the given `keystore` directory:
|
||||
|
||||
```sh
|
||||
clef newaccount --keystore sepolia-data/keystore
|
||||
```
|
||||
|
||||
Clef will request the new password in the terminal.
|
||||
|
||||
The same can be achieved using raw JSON requests (this example send the request to Clef's exposed HTTP port using curl):
|
||||
|
||||
```shell
|
||||
curl -X POST --data '{"id": 0, "jsonrpc": "2.0", "method": "account_new", "params": []}' http://localhost:8550 -H "Content-Type: application/json"
|
||||
```
|
||||
The console will hang because Clef is waiting for manual approval. Switch to the Clef terminal and approve the action. Clef will prompt for a account password and then confirm the account creation in the terminal logs. A new keyfile has been added to the keystore in `go-ethereum/sepolia-data`. A JSON response is returned to the terminal the request originated from, containing the new account address in the `result` field.
|
||||
|
||||
```terminal
|
||||
{"jsonrpc": "2.0", "id": 0, "result": "0x168bc315a2ee09042d83d7c5811b533620531f67"}
|
||||
```
|
||||
|
||||
It is critical to backup the account password safely and securely as it cannot be retrieved or reset.
|
||||
|
||||
{% include note.html content=" If the password provided on account creation is lost or forgotten, there is no way to retrive it and the account will simply stay locked forever. The password MUST be backed up safely and securely!
|
||||
**IT IS CRITICAL TO BACKUP THE KEYSTORE AND REMEMBER PASSWORDS**" %}
|
||||
{% include note.html content=" If the password provided on account creation is lost or forgotten, there is no way to retrive it and the account will simply stay locked forever. The password MUST be backed up safely and securely! **IT IS CRITICAL TO BACKUP THE KEYSTORE AND REMEMBER PASSWORDS**" %}
|
||||
|
||||
The newly generated key files can be viewed in `<datadir>/keystore/`. The file naming format is `UTC--<date>--<address>` where `date` is the date and time of key creation formatted according to [UTC 8601](https://www.iso.org/iso-8601-date-and-time-format.html) with zero time offset and seconds precise to eight decimal places. `address` is the 40 hexadecimal characters that make up the account address without a leading `0x`, for example:
|
||||
|
||||
`UTC--2022-05-19T12-34-36.47413510Z--0b85e5a13e118466159b1e1b6a4234e5f9f784bb`
|
||||
|
||||
## Listing Accounts
|
||||
|
||||
Listing all existing accounts is achieved using the `account list` command. If the keystore is located anywhere other than the default location its path should be included with the `keystore` flag. For example, if the datadir is `some-dir`:
|
||||
An account can also be created by importing a raw private key (hex string) using `clef importraw` as follows:
|
||||
|
||||
```shell
|
||||
geth account list --keystore some-dir/keystore
|
||||
```sh
|
||||
clef importraw <hexkey>
|
||||
```
|
||||
|
||||
This command returns the following to the terminal for a keystore with two files:
|
||||
The terminal will respond with the following message, indicating the account has been created successfully:
|
||||
|
||||
```terminal
|
||||
Account 0: {5afdd78bdacb56ab1dad28741ea2a0e47fe41331} keystore:///tmp/mykeystore/UTC--2017-04-28T08-46-27.437847599Z--5afdd78bdacb56ab1dad28741ea2a0e47fe41331
|
||||
Account 1: {9acb9ff906641a434803efb474c96a837756287f} keystore:///tmp/mykeystore/UTC--2017-04-28T08-46-52.180688336Z--9acb9ff906641a434803efb474c96a837756287f
|
||||
## Info
|
||||
Key imported:
|
||||
Address 0x9160DC9105f7De5dC5E7f3d97ef11DA47269BdA6
|
||||
Keystore file: /home/user/.ethereum/keystore/UTC--2022-10-28T12-03-13.976383602Z--9160dc9105f7de5dc5e7f3d97ef11da47269bda6
|
||||
|
||||
The key is now encrypted; losing the password will result in permanently losing
|
||||
access to the key and all associated funds!
|
||||
|
||||
Make sure to backup keystore and passwords in a safe location.
|
||||
```
|
||||
|
||||
|
||||
### Listing accounts
|
||||
|
||||
The accounts in the keystore can be listed to the terminal using a simple CLI command as follows:
|
||||
|
||||
```
|
||||
clef list-accounts --keystore <path-to-keystore>
|
||||
```
|
||||
|
||||
or using `account_list` in a POST request as follows:
|
||||
|
||||
```sh
|
||||
curl -X POST --data '{"id": 0, "jsonrpc": "2.0", "method": "account_list", "params": []}' http://localhost:8550 -H "Content-Type: application/json"
|
||||
```
|
||||
|
||||
This returns a JSON object with the account addresses in an array in the `result` field.
|
||||
|
||||
```terminal
|
||||
{"jsonrpc": "2.0", "id": 0, "result": ["0x168bc315a2ee09042d83d7c5811b533620531f67", "0x0b85e5a13e118466159b1e1b6a4234e5f9f784bb"]}
|
||||
```
|
||||
|
||||
The ordering of accounts when they are listed is lexicographic, but is effectively chronological based on time of creation due to the timestamp in the file name. It is safe to transfer the entire `keystore` directory or individual key files between Ethereum nodes. This is important because when accounts are added from other nodes the order of accounts in the keystore may change. It is therefore important not to rely on account indexes in scripts or code snippets.
|
||||
|
||||
## Importing accounts
|
||||
Accounts can also be listed in the Javascript console using `eth.accounts`, which will defer to Clef for approval.
|
||||
|
||||
As well as individual account, any wallets managed by Clef can be listed (which will also print the wallet status and the address and URl of any accounts they contain. This uses the `list-wallets` CLI command.
|
||||
|
||||
```
|
||||
clef list-wallets --keystore <path-to-keystore>
|
||||
```
|
||||
|
||||
which returns:
|
||||
|
||||
```terminal
|
||||
- Wallet 0 at keystore:///home/user/Code/go-ethereum/testdata/keystore/UTC--2022-11-01T17-05-01.517877299Z--4f4094babd1a8c433e0f52a6ee3b6ff32dee6a9c (Locked )
|
||||
- Account 0: 0x4f4094BaBd1A8c433e0f52A6ee3B6ff32dEe6a9c (keystore:///home/user/go-ethereum/testdata/keystore/UTC--2022-11-01T17-05-01.517877299Z--4f4094babd1a8c433e0f52a6ee3b6ff32dee6a9c)
|
||||
- Wallet 1 at keystore:///home/user/go-ethereum/testdata/keystore/UTC--2022-11-01T17-05-11.100536003Z--8ef15919f852a8034688a71d8b57ab0187364009 (Locked )
|
||||
- Account 0: 0x8Ef15919F852A8034688a71d8b57Ab0187364009 (keystore:///home/user/go-ethereum/testdata/keystore/UTC--2022-11-01T17-05-11.100536003Z--8ef15919f852a8034688a71d8b57ab0187364009)
|
||||
```
|
||||
|
||||
### Import a keyfile
|
||||
|
||||
It is also possible to create a new account by importing a private key. For example, a user might already have some ether at an address they created using a browser wallet and now wish to use a new Geth node to interact with their funds. In this case, the private key can be exported from the browser wallet and imported into Geth. Geth requires the private key to be stored as a file which contains the private key as unencrypted
|
||||
canonical elliptic curve bytes encoded into hex (i.e. plain text key without leading 0x). The new account is then saved in encrypted format, protected by a passphrase the user provides on request. As always, this passphrase must be securely and safely backed up - there is no way to retrieve or reset it if it is forgotten!
|
||||
It is also possible to create an account by importing an existing private key. For example, a user might already have some ether at an address they created using a browser wallet and now wish to use a new Geth node to interact with their funds. In this case, the private key can be exported from the browser wallet and imported into Geth. It is possible to do this using Clef, but currently the method is not externally exposed and requires implementing a UI. There is a Python UI on the Geth Github that could be used as an example or it can be done using the default console UI. However, for now the most straightforward way to import an accoutn from a private key is to use Geth's `account import`.
|
||||
|
||||
Geth requires the private key to be stored as a file which contains the private key as unencrypted canonical elliptic curve bytes encoded into hex (i.e. plain text key without leading 0x). The new account is then saved in encrypted format, protected by a passphrase the user provides on request. As always, this passphrase must be securely and safely backed up - there is no way to retrieve or reset it if it is forgotten!
|
||||
|
||||
```shell
|
||||
$ geth account import --datadir /some-dir ./keyfile
|
||||
@ -106,7 +164,7 @@ Repeat Passphrase:
|
||||
Address: {7f444580bfef4b9bc7e14eb7fb2a029336b07c9d}
|
||||
```
|
||||
|
||||
This import/export process is not necessary for transferring accounts between Geth instances because the key files can simply be copied directly from one keystore to another.
|
||||
This import/export process is **not necessary** for users transferring accounts between Geth instances because the key files can simply be copied directly from one keystore to another.
|
||||
|
||||
It is also possible to import an account in non-interactive mode by saving the account password as plaintext in a `.txt` file and passing its path with the `--password` flag on startup.
|
||||
|
||||
@ -116,7 +174,7 @@ geth account import --password path/password.txt path/keyfile
|
||||
|
||||
In this case, it is important to ensure the password file is not readable by anyone but the intended user. This can be achieved by changing the file permissions. On Linux, the following commands update the file permissions so only the current user has access:
|
||||
|
||||
```shell
|
||||
```sh
|
||||
chmod 700 /path/to/password
|
||||
cat > /path/to/password
|
||||
<type password here>
|
||||
@ -124,137 +182,52 @@ cat > /path/to/password
|
||||
|
||||
### Import a presale wallet
|
||||
|
||||
Assuming the password is known, importing a presale wallet is very easy. The `wallet import` commands are used, passing the path to the wallet.
|
||||
Assuming the password is known, importing a presale wallet is very easy. Geth's `wallet import` commands are used, passing the path to the wallet.
|
||||
|
||||
```shell
|
||||
```sh
|
||||
geth wallet import /path/presale.wallet
|
||||
```
|
||||
|
||||
## Updating accounts
|
||||
|
||||
The `account update` subcommand is used to unlock an account and migrate it to the newest format. This is useful for accounts that may have been created in a format that has since been deprecated. The same command can be used to update the account password. The current password and account address are needed in order to update the account, as follows:
|
||||
Clef can be used to set and remove passwords for an existing keystore file. To set a new password, pass the account address to `setpw`:
|
||||
|
||||
```sh
|
||||
clef setpw a94f5374fce5edbc8e2a8697c15331677e6ebf0b
|
||||
```
|
||||
|
||||
This will cause Clef to prompt for a new password, twice, and then the Clef master password to decrypt the keyfile.
|
||||
|
||||
Geth's `account update` subcommand can also be used to update the account password:
|
||||
|
||||
```shell
|
||||
geth account update a94f5374fce5edbc8e2a8697c15331677e6ebf0b
|
||||
```
|
||||
|
||||
The following will be returned to the terminal:
|
||||
|
||||
```terminal
|
||||
Unlocking account a94f5374fce5edbc8e2a8697c15331677e6ebf0b | Attempt 1/3
|
||||
Passphrase:
|
||||
0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b
|
||||
Account 'a94f5374fce5edbc8e2a8697c15331677e6ebf0b' unlocked.
|
||||
Please give a new password. Do not forget this password.
|
||||
Passphrase:
|
||||
Repeat Passphrase:
|
||||
0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b
|
||||
```
|
||||
|
||||
Alternatively, in non-interactive mode the path to a password file containing the account password in unencrypted plaintext can be passed with the `--password` flag:
|
||||
|
||||
```shell
|
||||
geth account update a94f5374fce5edbc8e2a8697c15331677e6ebf0b --password path/password.txt
|
||||
```
|
||||
|
||||
Updating the account replaces the original file with a new one - this means the original file is no longer available after it has been updated.
|
||||
Updating the account using `geth account update` replaces the original file with a new one - this means the original file is no longer available after it has been updated. This can be used to update a key file to the latest format.
|
||||
|
||||
## Unlocking accounts
|
||||
|
||||
In Geth, accounts are locked unless they are explicitly unlocked. If an account is intended to be used by apps connecting to Geth via RPC then it can be unlocked in non-interactive mode by passing the `--unlock` flag with a comma-separated list of account addresses (or keystore indexes) to unlock. This unlocks the accounts for one session only. Including the `--unlock` flag without any account addresses defaults to unlocking the first account
|
||||
in the keystore.
|
||||
With Clef, indiscriminate account unlocking is no longer a feature. Instead, Clef unlocks are locked until actions are explicitly approved manually by a user, unless they conform to some specific scenario that has been encoded in a ruleset. Please refer to our Clef docs for instructions for how to create rulesets.
|
||||
|
||||
```shell
|
||||
geth <other commands> --unlock 0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b
|
||||
```
|
||||
|
||||
Geth will start and prompt the user to input the account password in the terminal. Alternatively, the user can provide a password as a text file and pass its path to `--password`:
|
||||
### Transactions
|
||||
|
||||
```shell
|
||||
geth <other commands> --unlock 0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b --password path/password.txt
|
||||
```
|
||||
|
||||
{% include note.html content=" By default, account **unlocking is forbidden when HTTP or Websocket access is enabled** (i.e. by passing `--http` or `ws` flag). This is because an attacker that manages to access the node via the externally-exposed HTTP/WS port can then control the unlocked account.
|
||||
It is possible to force account unlock by including the `--allow-insecure-unlock` flag but this is unsafe and **not recommended** except for expert users that completely understand how it can be used safely. This is not a hypothetical risk: **there are bots that continually scan for http-enabled Ethereum nodes to attack**" %}
|
||||
|
||||
## Accounts in the Javascript console
|
||||
|
||||
Account management can also be achieved in the Javascript console attached to a running Geth instance. Assuming Geth is already running, in a new terminal attach a Javascript console using the `geth.ipc` file. This file can be found in the data directory. Assuming the data directory is named `data` the console can be started using:
|
||||
|
||||
```shell
|
||||
geth attach data/geth.ipc
|
||||
```
|
||||
|
||||
### New accounts
|
||||
|
||||
New accounts can be generated using the Javascript console using `personal.newAccount()`. A new password is requested in the console and successful account creation is confirmed by the new account address being displayed.
|
||||
|
||||
```shell
|
||||
personal.newAccount()
|
||||
```
|
||||
|
||||
Accounts can also be created by importing private keys directly in the Javascript console. The private key is passed as an unencrypted hex-encoded string to `personal.importRawKey()` along with a passphrase that will be used to encrypt the key. A new key file will be generated from the private key and saved to the keystore.
|
||||
|
||||
```shell
|
||||
personal.importRawKey("hexstringkey", "password")
|
||||
```
|
||||
|
||||
### Listing accounts
|
||||
|
||||
The `accounts` function in the `eth` namespace can be used to list the accounts that currently exist in the keystore.:
|
||||
|
||||
```
|
||||
eth.accounts
|
||||
```
|
||||
|
||||
or alternatively the same is achieved using:
|
||||
|
||||
```
|
||||
personal.listAccounts
|
||||
```
|
||||
|
||||
This returns an array of account addresses to the terminal.
|
||||
|
||||
### Unlocking accounts
|
||||
|
||||
To unlock an account, the `personal.unlockAccount` function can be used:
|
||||
|
||||
```
|
||||
personal.unlockAccount(eth.accounts[1])
|
||||
```
|
||||
|
||||
The account passphrase is requested:
|
||||
|
||||
```terminal
|
||||
Unlock account 0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b
|
||||
Passphrase:
|
||||
true
|
||||
```
|
||||
|
||||
This unlocked account can now be used to sign and send transactions. it is also possible to pass the passphrase as an argument to `personal.unlockAccount()` along with a duration after which the accout will automatically re-lock (in seconds), as follows:
|
||||
|
||||
```shell
|
||||
personal.unlockAccount(eth.accounts[1], "passphrase", 60)
|
||||
```
|
||||
|
||||
This unlocks the account for 60 seconds. However, this is not recommended because the command history is logged by the Javascript console which could compromise the security of the account. An unlocked account can be manually re-locked using `personal.lockAccount()`, passing the address as the sole argument.
|
||||
|
||||
### Unlocking for transactions
|
||||
|
||||
Sending transactions from the Javascript console also requires the sender account to be unlocked. There are two ways to send transactions: `eth.sendTransaction` and `personal.sendTransaction`. The difference between these two functions is that `eth.sendTransaction` requires the account to be
|
||||
unlocked globally, at the node level (i.e., by unlocking it on the command line at the start of the Geth session). On the other hand, `personal.sendTransaction` takes a passphrase argument that unlocks the account temporarily in order to sign the transaction, then locks it again
|
||||
immediately afterwards. For example, to send 5 ether between two accounts in the keystore:
|
||||
Transactions can be sent using raw JSON requests to Geth or using `web3js` in the Javascript console. Either way, with Clef acting as the signer the transactions will not get sent until approval is given in Clef. The following code snippet shows how a transaction could be sent between two accounts in the keystore using the Javascript console.
|
||||
|
||||
```shell
|
||||
var tx = {from: eth.accounts[1], to: eth.accounts[2], value: web3.toWei(5, "ether")}
|
||||
|
||||
# this requires global account unlock for eth.accounts[1]
|
||||
# this will hang until approval is given in the Clef console
|
||||
eth.sendTransaction(tx)
|
||||
|
||||
# this unlocks eth.accounts[1] temporarily just to send the transaction
|
||||
personal.sendTransaction(tx, "password")
|
||||
```
|
||||
|
||||
## Summary
|
||||
|
||||
This page has demonstrated how to use Geth's built-in account management tools, both on the command line and in the Javascript console. Accounts are stored encrypted by a password. It is critical that the account passwords and the keystore directory are safely and securely backed up.
|
||||
This page has demonstrated how to manage accounts using Clef and Geth's account management tools. Accounts are stored encrypted by a password. It is critical that the account passwords and the keystore directory are safely and securely backed up.
|
||||
|
@ -4,23 +4,29 @@ description: Introduction to how Ethereum nodes are organized and where Geth fit
|
||||
---
|
||||
|
||||
## Node architecture
|
||||
|
||||
Geth is an [execution client](https://ethereum.org/en/developers/docs/nodes-and-clients/#execution-clients). Originally, an execution client alone was enough to run a full Ethereum node. However, ever since Ethereum turned off [proof-of-work](https://ethereum.org/en/developers/docs/consensus-mechanisms/pow/) and implemented [proof-of-stake](https://ethereum.org/en/developers/docs/consensus-mechanisms/pow/), Geth has needed to be coupled to another piece of software called a [“consensus client”](https://ethereum.org/en/developers/docs/nodes-and-clients/#consensus-clients) in order to keep track of the Ethereum blockchain.
|
||||
An Ethereum node is composed of two clients: an [execution client](https://ethereum.org/en/developers/docs/nodes-and-clients/#execution-clients) and a [consensus client](https://ethereum.org/en/developers/docs/nodes-and-clients/#consensus-clients). Geth is an [execution client](https://ethereum.org/en/developers/docs/nodes-and-clients/#execution-clients). Originally, an execution client alone was enough to run a full Ethereum node. However, ever since Ethereum turned off [proof-of-work](https://ethereum.org/en/developers/docs/consensus-mechanisms/pow/) and implemented [proof-of-stake](https://ethereum.org/en/developers/docs/consensus-mechanisms/pow/), Geth has needed to be coupled to another piece of software called a [“consensus client”](https://ethereum.org/en/developers/docs/nodes-and-clients/#consensus-clients) in order to keep track of the Ethereum blockchain.
|
||||
|
||||
The execution client (Geth) is responsible for transaction handling, transaction gossip, state management and supporting the Ethereum Virtual Machine ([EVM])(https://ethereum.org/en/developers/docs/evm/). However, Geth is **not** responsible for block building, block gossiping or handling consensus logic. These are in the remit of the consensus client.
|
||||
|
||||
The relationship between the two Ethereum clients is shown in the schematic below. The two clients each connect to their own respective peer-to-peer (P2P) networks. This is because the execution clients gossip transactions over their P2P network enabling them to manage their local transaction pool. The consensus clients gossip blocks over their P2P network, enabling consensus and chain growth.
|
||||
|
||||
![node-architecture](/images/docs/node_architecture.png)
|
||||
![node-architecture](/public/images/docs/node_architecture.png)
|
||||
|
||||
For this two-client structure to work, consensus clients must be able to pass bundles of transactions to Geth to be executed. Executing the transactions locally is how the client validates that the transactions do not violate any Ethereum rules and that the proposed update to Ethereum’s state is correct. Likewise, when the node is selected to be a block producer the consensus client must be able to request bundles of transactions from Geth to include in the new block. This inter-client communication is handled by a local RPC connection using the [engine API](https://github.com/ethereum/execution-apis/blob/main/src/engine/specification.md).
|
||||
|
||||
## What does Geth do?
|
||||
|
||||
As an execution client, Geth is responsible for creating the execution payloads - the bundles of transactions - that consensus clients include in their blocks. Geth is also responsible for re-executing transactions that arrive in new blocks to ensure they are valid. Executing transactions is done on Geth's embedded computer, known as the Ethereum Virtual Machine (EVM).
|
||||
As an execution client, Geth is responsible for creating the execution payloads - the list of transactions, updated state trie plus other execution related data - that consensus clients include in their blocks. Geth is also responsible for re-executing transactions that arrive in new blocks to ensure they are valid. Executing transactions is done on Geth's embedded computer, known as the Ethereum Virtual Machine (EVM).
|
||||
|
||||
Geth also offers a user-interface to Ethereum by exposing a set of RPC methods that enable users to query the Ethereum blockchain, submit transactions and deploy smart contracts using the command line, programmatically using Geth's built-in console, web3 development frameworks such as Hardhat and Truffle or via web-apps and wallets.
|
||||
Geth also offers a user-interface to Ethereum by exposing a set of [RPC methods](/developers/docs/apis/json-rpc) that enable users to query the Ethereum blockchain, submit transactions and deploy smart contracts. Often, the RPC calls are abstracted by a library such as [Web3js](https://web3js.readthedocs.io/en/v1.8.0/) or [Web3py](https://web3py.readthedocs.io/en/v5/) for example in Geth's built-in Javascript console, development frameworks or web-apps.
|
||||
|
||||
In summary, Geth is: - a user gateway to Ethereum - home to the Ethereum Virtual Machine, Ethereum's state and transaction pool.
|
||||
## What does the consensus client do? {#consensus-client}
|
||||
|
||||
The consensus client deals with all the logic that enables a node to stay in sync with the Ethereum network. This includes receiving blocks from peers and running a fork choice algorithm to ensure the node always follows the chain with the greatest accumulation of attestations (weighted by validator effective balances). The consensus client has its own peer-to-peer network, separate from the network that connects execution clients to each other. The consensus clients share blocks and attestations over their peer-to-peer network. The consensus client itself does not participate in attesting to or proposing blocks - this is done by a validator which is an optional add-on to a consensus client. A consensus client without a validator only keeps up with the head of the chain, allowing the node to stay synced. This enables a user to transact with Ethereum using their execution client, confident that they are on the right chain.
|
||||
|
||||
## Validators {#validators}
|
||||
|
||||
Validators can be added to consensus clients if 32 ETH have been sent to the deposit contract. The validator client comes bundled with the consensus client and can be added to a node at any time. The validator handles attestations and block proposals. They enable a node to accrue rewards or lose ETH via penalties or slashing. Running the validator software also makes a node eligible to be selected to propose a new block.
|
||||
|
||||
Read more about [proof-of-stake](https://ethereum.org/en/developers/docs/consensus-mechanisms/pos/).
|
||||
|
||||
|
@ -43,6 +43,10 @@ A light node syncs very quickly and stores the bare minimum of blockchain data.
|
||||
|
||||
Read more about light nodes on our [LES page](/docs/interface/les.md).
|
||||
|
||||
The following diagram shows how Geth stores state data in the different sync modes:
|
||||
|
||||
![state pruning options](/public/images/docs/state-pruning.png)
|
||||
|
||||
## Consensus layer syncing
|
||||
|
||||
Now that Ethereum has switched to proof-of-stake, all consensus logic and block propagation is handled by consensus clients. This means that syncing the blockchain is a process shared between the consensus and execution clients. Blocks are downloaded by the consensus client and verified by the execution client. In order for Geth to sync, it requires a header from its connected consensus client. Geth does not import any data until it is instructed to by the consensus client. **Geth cannot sync without being connected to a consensus client**. This includes block-by-block syncing from genesis.
|
||||
|
@ -5,7 +5,7 @@ description: Guide to getting up and running with Geth using Clef as an external
|
||||
|
||||
This page explains how to set up Geth and execute some basic tasks using the command line tools. In order to use Geth, the software must first be installed. There are several ways Geth can be installed depending on the operating system and the user's choice of installation method, for example using a package manager, container or building from source. Instructions for installing Geth can be found on the ["Install and Build"](content/docs/getting_started/Installing-Geth.md) pages. Geth also needs to be connected to a consensus client in order to function as an Ethereum node. The tutorial on this page assumes Geth and a consensus client have been installed successfully and that a firewall has been configured to block external traffic to the JSON-RPC port `8545` see [Security](/content/docs/fundamentals/security.md).
|
||||
|
||||
This page provides step-by-step instructions covering the fundamentals of using Geth. This includes generating accounts, joining an Ethereum network, syncing the blockchain and sending ether between accounts. This tutorial also uses [Clef](/content/docs/tools/Clef/Tutorial.md). Clef is an account management tool external to Geth itself that allows users to sign transactions. It is developed and maintained by the Geth team and is intended to eventually replace the account management tool built in to Geth.
|
||||
This page provides step-by-step instructions covering the fundamentals of using Geth. This includes generating accounts, joining an Ethereum network, syncing the blockchain and sending ether between accounts. This tutorial uses [Clef](/content/docs/tools/Clef/Tutorial.md). Clef is an account management tool external to Geth itself that allows users to sign transactions. It is developed and maintained by the Geth team and is intended to eventually replace the account management tool built in to Geth.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
@ -19,8 +19,7 @@ In order to get the most value from the tutorials on this page, the following sk
|
||||
Users that need to revisit these fundamentals can find helpful resources relating to the command line [here](https://developer.mozilla.org/en-US/docs/Learn/Tools_and_testing/Understanding_client-side_tools/Command_line), Ethereum and its testnets [here](https://ethereum.org/en/developers/tutorials/), http [here](https://developer.mozilla.org/en-US/docs/Web/HTTP) and Javascript [here](https://www.javascript.com/learn). Information on node architecture can be found [here](/content/docs/fundamentals/node-architecture.md) and our guide for configuring Geth to connect to a
|
||||
consensus client is [here](/content/docs/getting_started/consensus-clients.md).
|
||||
|
||||
{% include note.html content="If Geth was installed from source on Linux, `make` saves the binaries for Geth and the associated tools in `/build/bin`. To run these programs it is convenient to move them to the top level project directory (e.g. running `mv ./build/bin/* ./`) from `/go-ethereum`. Then `./` must be prepended to the commands in the code snippets in order to execute a particular program, e.g. `./geth` instead of simply `geth`. If the executables are not
|
||||
moved then either navigate to the `bin` directory to run them (e.g. `cd ./build/bin` and `./geth`) or provide their path (e.g. `./build/bin/geth`). These instructions can be ignored for other installations." %}
|
||||
{% include note.html content="If Geth was installed from source on Linux, `make` saves the binaries for Geth and the associated tools in `/build/bin`. To run these programs it is convenient to move them to the top level project directory (e.g. running `mv ./build/bin/* ./`) from `/go-ethereum`. Then `./` must be prepended to the commands in the code snippets in order to execute a particular program, e.g. `./geth` instead of simply `geth`. If the executables are not moved then either navigate to the `bin` directory to run them (e.g. `cd ./build/bin` and `./geth`) or provide their path (e.g. `./build/bin/geth`). These instructions can be ignored for other installations." %}
|
||||
|
||||
## Background
|
||||
|
||||
@ -83,9 +82,7 @@ The previous commands used Clef's `newaccount` function to add new key pairs to
|
||||
To start Clef, run the Clef executable passing as arguments the keystore file location, config directory location and a chain ID. The config directory was automatically created inside the `geth-tutorial` directory during the previous step. The [chain ID](https://chainlist.org/) is an integer that defines which Ethereum network to connect to. Ethereum mainnet has chain ID 1. In this tutorial Chain ID 5 is used which is that of the Goerli testnet. It is very important that this chain ID parameter is set to 5. The following command starts Clef on Goerli:
|
||||
|
||||
```shell
|
||||
|
||||
clef --keystore geth-tutorial/keystore --configdir geth-tutorial/clef --chainid 5
|
||||
|
||||
```
|
||||
|
||||
After running the command above, Clef requests the user to type “ok” to proceed. On typing "ok" and pressing enter, Clef returns the following to the terminal:
|
||||
@ -147,8 +144,7 @@ WARN [02-10|13:59:06.999] Failed to open wallet url=extapi://
|
||||
INFO [02-10|13:59:08.793] Block synchronisation started
|
||||
```
|
||||
|
||||
This indicates that Geth has started up and is searching for peers to connect to. Once it finds peers it can request block headers from them, starting at the genesis block for the Goerli blockchain. Geth continues to download blocks sequentially, saving the data in files in `/go-ethereum/geth-tutorial/geth/chaindata/`.
|
||||
This is confirmed by the logs printed to the terminal. There should be a rapidly-growing sequence of logs in the terminal with the following syntax:
|
||||
This indicates that Geth has started up and is searching for peers to connect to. Once it finds peers it can request block headers from them, starting at the genesis block for the Goerli blockchain. Geth continues to download blocks sequentially, saving the data in files in `/go-ethereum/geth-tutorial/geth/chaindata/`. This is confirmed by the logs printed to the terminal. There should be a rapidly-growing sequence of logs in the terminal with the following syntax:
|
||||
|
||||
```terminal
|
||||
INFO [04-29][15:54:09.238] Looking for peers peercount=2 tried=0 static=0
|
||||
@ -156,16 +152,13 @@ INFO [04-29][15:54:19.393] Imported new block headers count=2 elapsed=1.127ms
|
||||
INFO [04-29][15:54:19:656] Imported new block receipts count=698 elapsed=4.464ms number=994566 hash=56dc44..007c93 age=13h9m9s
|
||||
```
|
||||
|
||||
These logs indicate that Geth is running as expected. 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:
|
||||
These logs indicate that Geth is running as expected. 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:
|
||||
|
||||
```shell
|
||||
curl http://localhost:8545
|
||||
```
|
||||
|
||||
If there is no error message reported to the terminal, everything is OK. Geth must be running in order for a user to interact with the Ethereum network. If this terminal is closed down then Geth must be restarted 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>`.
|
||||
If there is no error message reported to the terminal, everything is OK. Geth must be running in order for a user to interact with the Ethereum network. If this terminal is closed down then Geth must be restarted 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>`.
|
||||
|
||||
{% include note.html content="Snap syncing Goerli will take some time and until the sync is finished you can't use the node to transfer funds. You can also try doing a [light sync](interface/les) which will be much quicker but depends on light servers being available to serve your node the data it needs." %}
|
||||
|
||||
@ -177,8 +170,7 @@ The address generated by Clef in Step 1 can be pasted into the Paradigm Multifau
|
||||
|
||||
## Step 5: Interact with Geth
|
||||
|
||||
For interacting with the blockchain, Geth provides JSON-RPC APIs. [JSON-RPC](https://ethereum.org/en/developers/docs/apis/json-rpc/) is a way to execute specific
|
||||
tasks by sending instructions to Geth in the form of [JSON](https://www.json.org/json-en.html) objects. RPC stands for "Remote Procedure Call" and it refers to the ability to send these JSON-encoded instructions from locations outside of those managed by Geth. It is possible to interact with Geth by sending these JSON encoded instructions directly over Geth's exposed http port using tools like Curl. However, this is somewhat user-unfriendly and error-prone, especially for more complex instructions. For this reason, there are a set of libraries built on top of JSON-RPC that provide a more user-friendly interface for interacting with Geth. One of the most widely used is Web3.js.
|
||||
For interacting with the blockchain, Geth provides JSON-RPC APIs. [JSON-RPC](https://ethereum.org/en/developers/docs/apis/json-rpc/) is a way to execute specific tasks by sending instructions to Geth in the form of [JSON](https://www.json.org/json-en.html) objects. RPC stands for "Remote Procedure Call" and it refers to the ability to send these JSON-encoded instructions from locations outside of those managed by Geth. It is possible to interact with Geth by sending these JSON encoded instructions directly over Geth's exposed http port using tools like Curl. However, this is somewhat user-unfriendly and error-prone, especially for more complex instructions. For this reason, there are a set of libraries built on top of JSON-RPC that provide a more user-friendly interface for interacting with Geth. One of the most widely used is Web3.js.
|
||||
|
||||
Geth provides a Javascript console that exposes the Web3.js API. This means that with Geth running in one terminal, a Javascript environment can be opened in another allowing the user to interact with Geth using Web3.js. There are three transport protocols that can be used to connect the Javascript environment to Geth:
|
||||
|
||||
|
@ -3,11 +3,9 @@ title: Getting Started with Geth
|
||||
description: Instructions for getting up and running with Geth
|
||||
---
|
||||
|
||||
This page explains how to set up Geth and execute some basic tasks using the command line tools. In order to use Geth, the software must first be installed. There are several ways Geth can be installed depending on the operating system and the user's choice of installation method, for example using a package manager, container or building from source. Instructions for installing Geth can be found on the ["Install and Build"](content/docs/getting_started/Installing-Geth.md) pages. Geth
|
||||
also needs to be connected to a consensus client in order to function as an Ethereum node. The tutorial on this page assumes Geth and a consensus client have been installed successfully and that a firewall has been configured to block external traffic to the JSON-RPC port `8545` see [Security](/content/docs/fundamentals/security.md).
|
||||
This page explains how to set up Geth and execute some basic tasks using the command line tools. In order to use Geth, the software must first be installed. There are several ways Geth can be installed depending on the operating system and the user's choice of installation method, for example using a package manager, container or building from source. Instructions for installing Geth can be found on the ["Install and Build"](content/docs/getting_started/Installing-Geth.md) pages. Geth also needs to be connected to a consensus client in order to function as an Ethereum node. The tutorial on this page assumes Geth and a consensus client have been installed successfully and that a firewall has been configured to block external traffic to the JSON-RPC port `8545` see [Security](/content/docs/fundamentals/security.md).
|
||||
|
||||
This page provides step-by-step instructions covering the fundamentals of using Geth. This includes generating accounts, joining an Ethereum network, syncing the blockchain and sending ether between accounts. This page uses Geth's built in account management tool. This is the simplest method for creating and accessing
|
||||
accounts in Geth, is sufficiently secure for many purposes and provides a good entry point for understanding some of the basic Geth workflows. However, Geth also comes bundled with an external signer and account management tool called [Clef](/tools/Clef/introduction). It is best practise to use Clef instead of Geth's built-in account management tools because Clef is decoupled from Geth and can be run in a separate, secure environment. This page should be used as an initial entry point into basic Geth and readers should plan to advance from this page to [Getting started with Geth and Clef](/content/docs/getting_started/getting-started-with-clef.md). Eventually, Clef is intended to replace Geth's built-in account management tools.
|
||||
This page provides step-by-step instructions covering the fundamentals of using Geth. This includes generating accounts, joining an Ethereum network, syncing the blockchain and sending ether between accounts. This page uses Geth's built in account management tool. This is the simplest method for creating and accessing accounts in Geth, is sufficiently secure for many purposes and provides a good entry point for understanding some of the basic Geth workflows. However, Geth also comes bundled with an external signer and account management tool called [Clef](/tools/Clef/introduction). It is best practise to use Clef instead of Geth's built-in account management tools because Clef is decoupled from Geth and can be run in a separate, secure environment. This page should be used as an initial entry point into basic Geth and readers should plan to advance from this page to [Getting started with Geth and Clef](/content/docs/getting_started/getting-started-with-clef.md). Eventually, Clef is intended to replace Geth's built-in account management tools.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
@ -151,7 +149,7 @@ Welcome to the Geth JavaScript console!
|
||||
instance: Geth/v1.10.15-stable/darwin-amd64/go1.17.5
|
||||
at block: 6354736 (Thu Feb 10 2022 14:01:46 GMT+0100 (WAT))
|
||||
datadir: /home/go-ethereum/geth-tutorial
|
||||
modules: admin:1.0 clique:1.0 debug:1.0 eth:1.0 miner:1.0 net:1.0 personal:1.0 rpc:1.0 txpool:1.0 web3:1.0
|
||||
modules: admin:1.0 clique:1.0 debug:1.0 eth:1.0 miner:1.0 net:1.0 rpc:1.0 txpool:1.0 web3:1.0
|
||||
|
||||
To exit, press ctrl-d or type exit
|
||||
```
|
||||
@ -203,15 +201,7 @@ eth.sendTransaction({
|
||||
});
|
||||
```
|
||||
|
||||
This command will return an error message indicating that `authentication is needed: password or unlock`. This is a security feature that prevents unauthorized access to sensitive account operations. There are two ways to unlock the account. The first is to start Geth with the account permanently unlocked (by passing `--unlock <address>` at startup). This is not recommended because the account remains unlocked all the time Geth is running, creating a security weakness. Instead, it is better to temporarily unlock the account for the specific transaction. This requires using the `sendTransaction` method from the `personal` namespace instead of the `eth` namespace. The password can be provided as a string in the method call as follows:
|
||||
|
||||
```sh
|
||||
personal.sendTransaction({
|
||||
from: "0xca57f3b40b42fcce3c37b8d18adbca5260ca72ec",
|
||||
to: "0xce8dba5e4157c2b284d8853afeeea259344c1653",
|
||||
value: web3.toWei(0.1, "ether")
|
||||
}, "password")
|
||||
```
|
||||
This command will return an error message indicating that `authentication is needed: password or unlock`. This is a security feature that prevents unauthorized access to sensitive account operations. There are two ways to unlock the account. The first is to start Geth with the account permanently unlocked (by passing `--unlock <address>` at startup). This is not recommended because the account remains unlocked all the time Geth is running, creating a security weakness. Instead, it is better to temporarily unlock the account for the specific transaction using Clef. This requires Geth to be started with Clef as an external signer, and for Clef to know the location of the keystore (please see the [account management](/pages/docs/fundamentals/account-management.md) or [Clef](/pages/docs/tools/clef/Introduction.md) pages for setup details).
|
||||
|
||||
In the Javascript console, the transaction hash is displayed. This will be used in the next section to retrieve the transaction details.
|
||||
|
||||
|
@ -15,7 +15,8 @@ This returns a result which is also a JSON object, with values expressed as hexa
|
||||
{"id":2,"jsonrpc":"2.0","result":"0x1639e49bba16280000"}
|
||||
```
|
||||
|
||||
While this approach is valid, it is also a very low level and rather error-prone way to interact with Geth. Most developers prefer to use convenience libraries that abstract away some of the more tedious and awkward tasks such as converting values from hexadecimal strings into numbers, or converting between denominations of ether (Wei, Gwei, etc). One such library is [Web3.js](https://web3js.readthedocs.io/en/v1.7.3/). This is a collection of Javascript libraries for interacting with an Ethereum node at a higher level than sending raw JSON objects to the node. The purpose of Geth's Javascript console is to provide a built-in environment to use a subset of the Web3.js libraries to interact with a Geth node.
|
||||
This is a low level and rather error-prone way to interact with Geth. Most developers prefer to use convenience libraries that abstract away some of the more tedious and awkward tasks such as converting values from hexadecimal strings into numbers, or converting between denominations of ether (Wei, Gwei, etc). One such library is [Web3.js](https://web3js.readthedocs.io/en/v1.7.3/).
|
||||
The purpose of Geth's Javascript console is to provide a built-in environment to use a subset of the Web3.js libraries to interact with a Geth node.
|
||||
|
||||
{% include note.html content="The web3.js version that comes bundled with Geth is not up to date with the official Web3.js documentation. There are several Web3.js libraries that are not available in the Geth Javascript Console. There are also administrative APIs included in the Geth console that are not documented in the Web3.js documentation. The full list of libraries available in the Geth console is available on the [JSON-RPC API page](/docs/rpc/server)." %}
|
||||
|
||||
@ -38,7 +39,6 @@ Alternatively, a Javascript console can be attached to an existing Geth instance
|
||||
geth <other flags> --ws
|
||||
|
||||
# enable http
|
||||
|
||||
geth <other flags> --http
|
||||
```
|
||||
|
||||
@ -52,7 +52,7 @@ geth <other commands> --http --http.addr 192.60.52.21 --http.port 8552 --http.ap
|
||||
geth <other commands> --ws --ws.addr 192.60.52.21 --ws.port 8552 --ws.api eth,web3,admin
|
||||
```
|
||||
|
||||
It is important to note that by default **some functionality, including account unlocking is forbidden when HTTP or Websockets access is enabled**. This is because an attacker that manages to access the node via the externally-exposed HTTP/WS port then control the unlocked account. It is possible to force account unlock by including the `--allow-insecure-unlock` flag but this is not recommended if there is any chance of the node connecting to Ethereum Mainnet. This is not a hypothetical risk: **there are bots that continually scan for http-enabled Ethereum nodes to attack**"
|
||||
It is important to note that by default **some functionality, including account unlocking is forbidden when HTTP or Websockets access is enabled**. This is because an attacker that manages to access the node via the externally-exposed HTTP/WS port then control the unlocked account. This is not a hypothetical risk: **there are bots that continually scan for http-enabled Ethereum nodes to attack**"
|
||||
|
||||
The Javascript console can also be connected to a Geth node using IPC. When Geth is started, a `geth.ipc` file is automatically generated and saved to the data directory. This file, or a custom path to a specific ipc file can be passed to `geth attach` as follows:
|
||||
|
||||
@ -69,7 +69,7 @@ instance: Geth/v1.10.18-unstable-8d85a701-20220503/linux-amd64/go1.18.1
|
||||
coinbase: 0x281aabb85c68e1638bb092750a0d9bb06ba103ee
|
||||
at block: 12305815 (Thu May 26 2022 16:16:00 GMT+0100 (BST))
|
||||
datadir: /home/go-ethereum/data
|
||||
modules: admin:1.0 debug:1.0 eth:1.0 ethash:1.0 miner:1.0 net:1.0 personal:1.0 rpc:1.0 txpool:1.0 web3:1.0
|
||||
modules: admin:1.0 debug:1.0 eth:1.0 ethash:1.0 miner:1.0 net:1.0 rpc:1.0 txpool:1.0 web3:1.0
|
||||
|
||||
To exit, press ctrl-d or type exit
|
||||
>
|
||||
@ -77,22 +77,18 @@ To exit, press ctrl-d or type exit
|
||||
|
||||
## Interactive use
|
||||
|
||||
Once the console has been started, it can be used to interact with Geth. The console supports Javascript and the full Geth [JSON-RPC API](/docs/rpc/server). For example, to create an account:
|
||||
|
||||
```js
|
||||
personal.newAccount();
|
||||
```
|
||||
Once the console has been started, it can be used to interact with Geth. The console supports Javascript and the full Geth [JSON-RPC API](/docs/rpc/server). For example:
|
||||
|
||||
To check the balance of the first account already existing in the keystore:
|
||||
|
||||
```js
|
||||
eth.getBalance(personal.listAccounts[0]);
|
||||
eth.getBalance(eth.accounts[0]);
|
||||
```
|
||||
|
||||
To make a transaction (without global account unlocking):
|
||||
To send a transaction (without global account unlocking):
|
||||
|
||||
```js
|
||||
personal.sendTransaction({
|
||||
eth.sendTransaction({
|
||||
to: eth.accounts[0],
|
||||
to: eth.accounts[1],
|
||||
value: web3.toWei(0.5, 'ether')
|
||||
@ -109,6 +105,8 @@ geth console --preload "/my/scripts/folder/utils.js"
|
||||
|
||||
Once the interactive session is over, the console can be closed down by typing `exit` or `CTRL-D`.
|
||||
|
||||
Remember that interactions that touch accounts need approval in Clef - either manually or by writing a custom ruleset.
|
||||
|
||||
## Non-interactive Use: Script Mode
|
||||
|
||||
It is also possible to execute JavaScript code non-interactively by passing the `--exec` and a JSON-RPC-API endpoint
|
||||
|
@ -0,0 +1,118 @@
|
||||
---
|
||||
title: JavaScript Console 2: Contracts
|
||||
description: Instructions for working with contracts in the Javascript console.
|
||||
---
|
||||
|
||||
The [Introduction to the Javascript console](src/pages/docs/interacting-with-geth/javascript-console.md) page outlined how a Javascript console can be attached to Geth to provide a more user-friendly interface to Ethereum than interacting directly with the JSON-RPC API. This page will describe how to deploy contracts and interact with contracts using the attached console. This page will assume the Javascript console is attached to a running Geth instance using IPC. Clef should be used to manage accounts.
|
||||
|
||||
## Deploying a contract
|
||||
|
||||
First we need a contract to deploy. We can use the well-known `Storage.sol` contract written in Solidity. The following Solidity code can be copied and pasted into a text editor and saved as `go-ethereum/storage-contract/Storage.sol`.
|
||||
|
||||
```Solidity
|
||||
// SPDX License-Identifier: GPL 3.0
|
||||
|
||||
pragma solidity ^0.8.0;
|
||||
|
||||
contract Storage{
|
||||
|
||||
uint256 value = 5;
|
||||
|
||||
function set(uint256 number) public{
|
||||
value = number;
|
||||
}
|
||||
|
||||
function retrieve() public view returns (uint256){
|
||||
return value;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
The contract needs to be compiled before Geth can understand it. Compiling the contract creates an [Application Binary Interface](src/pages/docs/tools/abigen.md) and the contract bytecode. This requires a Solidity compiler (e.g. `solc`) to be installed on the local machine. Then, compile and save the ABI and bytecode to a new `build` subdirectory using the following terminal commands:
|
||||
|
||||
```sh
|
||||
cd ~/go-ethereum/storage-contract
|
||||
solc --bin Storage.sol -o build
|
||||
solc --abi Storage.sol -o build
|
||||
```
|
||||
|
||||
The outputs look as follows:
|
||||
|
||||
```sh
|
||||
# build/Storage.bin
|
||||
608060405234801561001057600080fd5b50610150806100206000396000f3fe608060405234801561001057600080fd5b50600436106100365760003560e01c80632e64cec11461003b5780636057361d14610059575b600080fd5b610043610075565b60405161005091906100a1565b60405180910390f35b610073600480360381019061006e91906100ed565b61007e565b005b60008054905090565b8060008190555050565b6000819050919050565b61009b81610088565b82525050565b60006020820190506100b66000830184610092565b92915050565b600080fd5b6100ca81610088565b81146100d557600080fd5b50565b6000813590506100e7816100c1565b92915050565b600060208284031215610103576101026100bc565b5b6000610111848285016100d8565b9150509291505056fea264697066735822122031443f2fb748bdb27e539fdbeb0c6f575aec50508baaa7e4dbeb08577ef19b3764736f6c63430008110033
|
||||
```
|
||||
|
||||
```json
|
||||
# Storage.abi
|
||||
[{"inputs":[],"name":"retrieve","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"number","type":"uint256"}],"name":"store","outputs":[],"stateMutability":"nonpayable","type":"function"}]
|
||||
```
|
||||
|
||||
These are all the data required to deploy the contract using the Geth Javascript console. Open the Javascript console using `./geth attach geth.ipc`.
|
||||
|
||||
Now, for convenice we can store the abi and bytecode in variables in the console:
|
||||
|
||||
```js
|
||||
var abi = [{"inputs":[],"name":"retrieve","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"number","type":"uint256"}],"name":"store","outputs":[],"stateMutability":"nonpayable","type":"function"}]
|
||||
|
||||
var bytecode = "608060405234801561001057600080fd5b50610150806100206000396000f3fe608060405234801561001057600080fd5b50600436106100365760003560e01c80632e64cec11461003b5780636057361d14610059575b600080fd5b610043610075565b60405161005091906100a1565b60405180910390f35b610073600480360381019061006e91906100ed565b61007e565b005b60008054905090565b8060008190555050565b6000819050919050565b61009b81610088565b82525050565b60006020820190506100b66000830184610092565b92915050565b600080fd5b6100ca81610088565b81146100d557600080fd5b50565b6000813590506100e7816100c1565b92915050565b600060208284031215610103576101026100bc565b5b6000610111848285016100d8565b9150509291505056fea264697066735822122031443f2fb748bdb27e539fdbeb0c6f575aec50508baaa7e4dbeb08577ef19b3764736f6c63430008110033"
|
||||
```
|
||||
|
||||
The ABI can be used to create an instance of the contract:
|
||||
|
||||
```js
|
||||
var contract = eth.contract(abi)
|
||||
```
|
||||
|
||||
This contract instance can then be deployed to the blockchain. This is done using `eth.sendTransaction`, passing the contract bytecode in the `data` field. For convenience we can create a transaction JSON object first, then pass it to `eth.sendTransaction` later. Let's use the first account in `eth.accounts` as the sender. The amount of gas to include can be determined using `eth.estimateGas`:
|
||||
|
||||
```js
|
||||
var gas = eth.estimateGas({data: bytecode})
|
||||
```
|
||||
|
||||
Note that each command that touches accounts will require **approval in Clef** unless a custom rule has been implemented. The bytecode, gas and address of the sender can be bundled together into an object that will be passed to the contract's `new()` method which deploys the contract.
|
||||
|
||||
```js
|
||||
var tx = {'from': eth.accounts[0], data: bytecode, gas: gas}
|
||||
var deployed_contract = contract.new(tx)
|
||||
```
|
||||
|
||||
The transaction hash and deployment address can now been viewed in the console by entering the variable name (in this case `deployed_contract`):
|
||||
|
||||
```js
|
||||
{
|
||||
abi:[{
|
||||
inputs: [],
|
||||
name: "retrieve",
|
||||
outputs: [{...}],
|
||||
stateMutability: "view",
|
||||
type: "function"
|
||||
},{
|
||||
inputs: [],
|
||||
name: "store",
|
||||
outputs: [{...}],
|
||||
stateMutability: "nonpayable",
|
||||
type: "function"
|
||||
}],
|
||||
address: "0x2d6505f8b1130a22a5998cd31788bf6c751247f",
|
||||
transactionHash: "0x5040a8916b23b76696ea9eba5b072546e1112cc481995219081fc86f5b911bf3",
|
||||
allEvents: function bound(),
|
||||
retrieve: function bound(),
|
||||
store: function bound()
|
||||
}
|
||||
```
|
||||
|
||||
Passing the transaction hash to `eth.getTransaction()` returns the deployment transaction details including the contract bytecode in the `input` field. To interact with the contract, create an instance by passing the deployment address to `contract.at` then call the methods.
|
||||
|
||||
```js
|
||||
var instance = contract.at("0x2d6505f8b1130a22a5998cd31788bf6c751247f")
|
||||
// store() alters the state and therefore requires sendTransaction()
|
||||
contract.set.sendTransaction(42, {from: eth.accounts[0], gas: 1000000})
|
||||
// retrieve does not alter state so it can be executed using call()
|
||||
contract.retrieve().call()
|
||||
|
||||
>> 2
|
||||
```
|
||||
|
||||
## Summary
|
||||
This page demonstrated how to create, compile, deploy and interact with an Ethereum smart contract using Geth's Javascript console.
|
@ -38,10 +38,10 @@ geth --http --http.port 3334
|
||||
|
||||
Not all of the JSON-RPC method namespaces are enabled for HTTP requests by default. Instead, they have to be whitelisted explicitly when Geth is started. Calling non-whitelisted RPC namespaces returns an RPC error with code `-32602`.
|
||||
|
||||
The default whitelist allows access to the `eth`, `net` and `web3` namespaces. To enable access to other APIs like account management (`personal`) and debugging (`debug`), they must be configured using the `--http.api` flag. Enabling these APIs over HTTP is **not recommended** because access to these methods increases the attack surface.
|
||||
The default whitelist allows access to the `eth`, `net` and `web3` namespaces. To enable access to other APIs like debugging (`debug`), they must be configured using the `--http.api` flag. Enabling these APIs over HTTP is **not recommended** because access to these methods increases the attack surface.
|
||||
|
||||
```sh
|
||||
geth --http --http.api personal,eth,net,web3
|
||||
geth --http --http.api eth,net,web3
|
||||
```
|
||||
|
||||
Since the HTTP server is reachable from any local application, additional protection is built into the server to prevent misuse of the API from web pages. To enable access to the API from a web page (for example to use the online IDE, [Remix](https://remix.ethereum.org)), the server needs to be configured to accept Cross-Origin requests. This is achieved using the `--http.corsdomain` flag.
|
||||
|
@ -27,6 +27,22 @@ Ethereum Node Records can be decoded, verified and displayed to the terminal usi
|
||||
|
||||
Use `devp2p enrdump <base64>` to verify and display an Ethereum Node Record.
|
||||
|
||||
The following is an example of the data returned by `enrdump`:
|
||||
|
||||
```terminal
|
||||
./devp2p enrdump "enr:-J24QG3pjTFObcDvTOTJr2qPOTDH3-YxDqS47Ylm-kgM5BUwb1oD5Id6fSRTfUzTahTa7y4TWx_HSV7wri7T6iYtyAQHg2V0aMfGhLjGKZ2AgmlkgnY0gmlwhJ1a19CJc2VjcDI1NmsxoQPlCNb7N__vcnsNC8YYkFkmNj8mibnR5NuvSowcRZsLU4RzbmFwwIN0Y3CCdl-DdWRwgnZf" Node ID: 001816492db22f7572e9eea1c871a2ffe75c28162a9fbc5a9d240e480a7c176f URLv4: ./devp2p enrdump "enr:-J24QG3pjTFObcDvTOTJr2qPOTDH3-YxDqS47Ylm-kgM5BUwb1oD5Id6fSRTfUzTahTa7y4TWx_HSV7wri7T6iYtyAQHg2V0aMfGhLjGKZ2AgmlkgnY0gmlwhJ1a19CJc2VjcDI1NmsxoQPlCNb7N__vcnsNC8YYkFkmNj8mibnR5NuvSowcRZsLU4RzbmFwwIN0Y3CCdl-DdWRwgnZf"
|
||||
Node ID: 001816492db22f7572e9eea1c871a2ffe75c28162a9fbc5a9d240e480a7c176f
|
||||
URLv4: enode://e508d6fb37ffef727b0d0bc618905926363f2689b9d1e4dbaf4a8c1c459b0b534dcdf84342b78250a6dc013c9ee9f89d095d7a6d1ef0c5f4c57a083b22c557ef@157.90.215.208:30303
|
||||
Record has sequence number 7 and 7 key/value pairs.
|
||||
"eth" c7c684b8c6299d80
|
||||
"id" "v4"
|
||||
"ip" 157.90.215.208
|
||||
"secp256k1" a103e508d6fb37ffef727b0d0bc618905926363f2689b9d1e4dbaf4a8c1c459b0b53
|
||||
"snap" c0
|
||||
"tcp" 30303
|
||||
"udp" 30303
|
||||
```
|
||||
|
||||
Read more on [Ethereum Node Records](https://ethereum.org/en/developers/docs/networking-layer/network-addresses/#enr) or browse the [specs](https://github.com/ethereum/devp2p/blob/591edbd36eb57280384d07373a818c00bddf3b31/enr.md).
|
||||
|
||||
## Node Key Management
|
||||
|
@ -132,7 +132,7 @@ const HomePage: NextPage = ({}) => {
|
||||
>
|
||||
<Text fontFamily='"Inter", sans-serif' lineHeight='26px'>
|
||||
The Geth team comprises 10 developers distributed across the world. The Geth team
|
||||
is funded directly by The Ethereum Foundation.
|
||||
is funded exclusively by The Ethereum Foundation.
|
||||
</Text>
|
||||
</HomeSection>
|
||||
</GridItem>
|
||||
|
182
yarn.lock
182
yarn.lock
@ -1062,10 +1062,10 @@
|
||||
hey-listen "^1.0.8"
|
||||
tslib "^2.3.1"
|
||||
|
||||
"@next/env@12.3.0":
|
||||
version "12.3.0"
|
||||
resolved "https://registry.yarnpkg.com/@next/env/-/env-12.3.0.tgz#85f971fdc668cc312342761057c59cb8ab1abadf"
|
||||
integrity sha512-PTJpjAFVbzBQ9xXpzMTroShvD5YDIIy46jQ7d4LrWpY+/5a8H90Tm8hE3Hvkc5RBRspVo7kvEOnqQms0A+2Q6w==
|
||||
"@next/env@13.0.2":
|
||||
version "13.0.2"
|
||||
resolved "https://registry.yarnpkg.com/@next/env/-/env-13.0.2.tgz#5fbd7b4146175ae406edfb4a38b62de8c880c09d"
|
||||
integrity sha512-Qb6WPuRriGIQ19qd6NBxpcrFOfj8ziN7l9eZUfwff5gl4zLXluqtuZPddYZM/oWjN53ZYcuRXzL+oowKyJeYtA==
|
||||
|
||||
"@next/eslint-plugin-next@12.2.5":
|
||||
version "12.2.5"
|
||||
@ -1079,70 +1079,70 @@
|
||||
resolved "https://registry.yarnpkg.com/@next/mdx/-/mdx-12.3.0.tgz#ba6a1d27f0ef9b46b00e09ca0b514787abdf5b81"
|
||||
integrity sha512-XyzLhgsKa4lKb3dw8HFtj4MM0jilDStKtosFrkt8AX44zEwxPoJPaIvMCWNsRwq72YTzQLqh1gjepIe9zCKZwQ==
|
||||
|
||||
"@next/swc-android-arm-eabi@12.3.0":
|
||||
version "12.3.0"
|
||||
resolved "https://registry.yarnpkg.com/@next/swc-android-arm-eabi/-/swc-android-arm-eabi-12.3.0.tgz#9a934904643591cb6f66eb09803a92d2b10ada13"
|
||||
integrity sha512-/PuirPnAKsYBw93w/7Q9hqy+KGOU9mjYprZ/faxMUJh/dc6v3rYLxkZKNG9nFPIW4QKNTCnhP40xF9hLnxO+xg==
|
||||
"@next/swc-android-arm-eabi@13.0.2":
|
||||
version "13.0.2"
|
||||
resolved "https://registry.yarnpkg.com/@next/swc-android-arm-eabi/-/swc-android-arm-eabi-13.0.2.tgz#66669b8aab5062f554b8e9905d855679aabf0342"
|
||||
integrity sha512-X54UQCTFyOGnJP//Z71dPPlp4BCYcQL2ncikKXQcPzVpqPs4C3m+tKC8ivBNH6edAXkppwsLRz1/yQwgSZ9Swg==
|
||||
|
||||
"@next/swc-android-arm64@12.3.0":
|
||||
version "12.3.0"
|
||||
resolved "https://registry.yarnpkg.com/@next/swc-android-arm64/-/swc-android-arm64-12.3.0.tgz#c1e3e24d0625efe88f45a2135c8f5c4dff594749"
|
||||
integrity sha512-OaI+FhAM6P9B6Ybwbn0Zl8YwWido0lLwhDBi9WiYCh4RQmIXAyVIoIJPHo4fP05+mXaJ/k1trvDvuURvHOq2qw==
|
||||
"@next/swc-android-arm64@13.0.2":
|
||||
version "13.0.2"
|
||||
resolved "https://registry.yarnpkg.com/@next/swc-android-arm64/-/swc-android-arm64-13.0.2.tgz#c0641d30525e0fb22bf1e2baf6c461d2d9e52f1a"
|
||||
integrity sha512-1P00Kv8uKaLubqo7JzPrTqgFAzSOmfb8iwqJrOb9in5IvTRtNGlkR4hU0sXzqbQNM/+SaYxze6Z5ry1IDyb/cQ==
|
||||
|
||||
"@next/swc-darwin-arm64@12.3.0":
|
||||
version "12.3.0"
|
||||
resolved "https://registry.yarnpkg.com/@next/swc-darwin-arm64/-/swc-darwin-arm64-12.3.0.tgz#37a9f971b9ad620184af69f38243a36757126fb9"
|
||||
integrity sha512-9s4d3Mhii+WFce8o8Jok7WC3Bawkr9wEUU++SJRptjU1L5tsfYJMrSYCACHLhZujziNDLyExe4Hwwsccps1sfg==
|
||||
"@next/swc-darwin-arm64@13.0.2":
|
||||
version "13.0.2"
|
||||
resolved "https://registry.yarnpkg.com/@next/swc-darwin-arm64/-/swc-darwin-arm64-13.0.2.tgz#d7e01a33393e83456dbfdc41446bb8a923968ff7"
|
||||
integrity sha512-1zGIOkInkOLRv0QQGZ+3wffYsyKI4vIy62LYTvDWUn7TAYqnmXwougp9NSLqDeagLwgsv2URrykyAFixA/YqxA==
|
||||
|
||||
"@next/swc-darwin-x64@12.3.0":
|
||||
version "12.3.0"
|
||||
resolved "https://registry.yarnpkg.com/@next/swc-darwin-x64/-/swc-darwin-x64-12.3.0.tgz#fb017f1066c8cf2b8da49ef3588c8731d8bf1bf3"
|
||||
integrity sha512-2scC4MqUTwGwok+wpVxP+zWp7WcCAVOtutki2E1n99rBOTnUOX6qXkgxSy083yBN6GqwuC/dzHeN7hIKjavfRA==
|
||||
"@next/swc-darwin-x64@13.0.2":
|
||||
version "13.0.2"
|
||||
resolved "https://registry.yarnpkg.com/@next/swc-darwin-x64/-/swc-darwin-x64-13.0.2.tgz#d4a3fbe51edf871a675d89a7afdc78174d1e5841"
|
||||
integrity sha512-ECDAjoMP1Y90cARaelS6X+k6BQx+MikAYJ8f/eaJrLur44NIOYc9HA/dgcTp5jenguY4yT8V+HCquLjAVle6fA==
|
||||
|
||||
"@next/swc-freebsd-x64@12.3.0":
|
||||
version "12.3.0"
|
||||
resolved "https://registry.yarnpkg.com/@next/swc-freebsd-x64/-/swc-freebsd-x64-12.3.0.tgz#e7955b016f41e0f95088e3459ff4197027871fbf"
|
||||
integrity sha512-xAlruUREij/bFa+qsE1tmsP28t7vz02N4ZDHt2lh3uJUniE0Ne9idyIDLc1Ed0IF2RjfgOp4ZVunuS3OM0sngw==
|
||||
"@next/swc-freebsd-x64@13.0.2":
|
||||
version "13.0.2"
|
||||
resolved "https://registry.yarnpkg.com/@next/swc-freebsd-x64/-/swc-freebsd-x64-13.0.2.tgz#1b54c3f38d3b36f86663a8dfcc81ea05e01f5172"
|
||||
integrity sha512-2DcL/ofQdBnQX3IoI9sjlIAyLCD1oZoUBuhrhWbejvBQjutWrI0JTEv9uG69WcxWhVMm3BCsjv8GK2/68OKp7A==
|
||||
|
||||
"@next/swc-linux-arm-gnueabihf@12.3.0":
|
||||
version "12.3.0"
|
||||
resolved "https://registry.yarnpkg.com/@next/swc-linux-arm-gnueabihf/-/swc-linux-arm-gnueabihf-12.3.0.tgz#d2233267bffaa24378245b328f2f8a01a37eab29"
|
||||
integrity sha512-jin2S4VT/cugc2dSZEUIabhYDJNgrUh7fufbdsaAezgcQzqfdfJqfxl4E9GuafzB4cbRPTaqA0V5uqbp0IyGkQ==
|
||||
"@next/swc-linux-arm-gnueabihf@13.0.2":
|
||||
version "13.0.2"
|
||||
resolved "https://registry.yarnpkg.com/@next/swc-linux-arm-gnueabihf/-/swc-linux-arm-gnueabihf-13.0.2.tgz#18495cff32c0b2182cfbf677614219d7072214da"
|
||||
integrity sha512-Y3OQF1CSBSWW2vGkmvOIuOUNqOq8qX7f1ZpcKUVWP3/Uq++DZmVi9d18lgnSe1I3QFqc+nXWyun9ljsN83j0sw==
|
||||
|
||||
"@next/swc-linux-arm64-gnu@12.3.0":
|
||||
version "12.3.0"
|
||||
resolved "https://registry.yarnpkg.com/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-12.3.0.tgz#149a0cb877352ab63e81cf1dd53b37f382929d2a"
|
||||
integrity sha512-RqJHDKe0WImeUrdR0kayTkRWgp4vD/MS7g0r6Xuf8+ellOFH7JAAJffDW3ayuVZeMYOa7RvgNFcOoWnrTUl9Nw==
|
||||
"@next/swc-linux-arm64-gnu@13.0.2":
|
||||
version "13.0.2"
|
||||
resolved "https://registry.yarnpkg.com/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-13.0.2.tgz#5fb2563651166c3c6f32bf9e2f9cc6a16a9ef783"
|
||||
integrity sha512-mNyzwsFF6kwZYEjnGicx9ksDZYEZvyzEc1BtCu8vdZi/v8UeixQwCiAT6FyYX9uxMPEkzk8qiU0t0u9gvltsKw==
|
||||
|
||||
"@next/swc-linux-arm64-musl@12.3.0":
|
||||
version "12.3.0"
|
||||
resolved "https://registry.yarnpkg.com/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-12.3.0.tgz#73ec7f121f56fd7cf99cf2b00cf41f62c4560e90"
|
||||
integrity sha512-nvNWoUieMjvDjpYJ/4SQe9lQs2xMj6ZRs8N+bmTrVu9leY2Fg3WD6W9p/1uU9hGO8u+OdF13wc4iRShu/WYIHg==
|
||||
"@next/swc-linux-arm64-musl@13.0.2":
|
||||
version "13.0.2"
|
||||
resolved "https://registry.yarnpkg.com/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-13.0.2.tgz#b9f33c5e17cfe04aa5769b717284cf80865761e6"
|
||||
integrity sha512-M6SdYjWgRrY3tJBxz0663zCRPTu5BRONmxlftKWWHv9LjAJ59neTLaGj4rp0A08DkJglZIoCkLOzLrzST6TGag==
|
||||
|
||||
"@next/swc-linux-x64-gnu@12.3.0":
|
||||
version "12.3.0"
|
||||
resolved "https://registry.yarnpkg.com/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-12.3.0.tgz#6812e52ef21bfd091810f271dd61da11d82b66b9"
|
||||
integrity sha512-4ajhIuVU9PeQCMMhdDgZTLrHmjbOUFuIyg6J19hZqwEwDTSqQyrSLkbJs2Nd7IRiM6Ul/XyrtEFCpk4k+xD2+w==
|
||||
"@next/swc-linux-x64-gnu@13.0.2":
|
||||
version "13.0.2"
|
||||
resolved "https://registry.yarnpkg.com/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-13.0.2.tgz#29efcc2fd0122689d7e06c5b6b0883fe495db2bf"
|
||||
integrity sha512-pi63RoxvG4ES1KS06Zpm0MATVIXTs/TIbLbdckeLoM40u1d3mQl/+hSSrLRSxzc2OtyL8fh92sM4gkJrQXAMAw==
|
||||
|
||||
"@next/swc-linux-x64-musl@12.3.0":
|
||||
version "12.3.0"
|
||||
resolved "https://registry.yarnpkg.com/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-12.3.0.tgz#c9e7ffb6d44da330961c1ce651c5b03a1becfe22"
|
||||
integrity sha512-U092RBYbaGxoMAwpauePJEu2PuZSEoUCGJBvsptQr2/2XIMwAJDYM4c/M5NfYEsBr+yjvsYNsOpYfeQ88D82Yg==
|
||||
"@next/swc-linux-x64-musl@13.0.2":
|
||||
version "13.0.2"
|
||||
resolved "https://registry.yarnpkg.com/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-13.0.2.tgz#d68fdf6eefc57813fa91559c7089b49d6131ecab"
|
||||
integrity sha512-9Pv91gfYnDONgjtRm78n64b/c54+azeHtlnqBLTnIFWSMBDRl1/WDkhKWIj3fBGPLimtK7Tko3ULR3og9RRUPw==
|
||||
|
||||
"@next/swc-win32-arm64-msvc@12.3.0":
|
||||
version "12.3.0"
|
||||
resolved "https://registry.yarnpkg.com/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-12.3.0.tgz#e0d9d26297f52b0d3b3c2f5138ddcce30601bc98"
|
||||
integrity sha512-pzSzaxjDEJe67bUok9Nxf9rykbJfHXW0owICFsPBsqHyc+cr8vpF7g9e2APTCddtVhvjkga9ILoZJ9NxWS7Yiw==
|
||||
"@next/swc-win32-arm64-msvc@13.0.2":
|
||||
version "13.0.2"
|
||||
resolved "https://registry.yarnpkg.com/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-13.0.2.tgz#acdcb3023045f60cca510f659a2349895e6405bd"
|
||||
integrity sha512-Nvewe6YZaizAkGHHprbMkYqQulBjZCHKBGKeFPwoPtOA+a2Qi4pZzc/qXFyC5/2A6Z0mr2U1zg9rd04WBYMwBw==
|
||||
|
||||
"@next/swc-win32-ia32-msvc@12.3.0":
|
||||
version "12.3.0"
|
||||
resolved "https://registry.yarnpkg.com/@next/swc-win32-ia32-msvc/-/swc-win32-ia32-msvc-12.3.0.tgz#37daeac1acc68537b8e76cd81fde96dce11f78b4"
|
||||
integrity sha512-MQGUpMbYhQmTZ06a9e0hPQJnxFMwETo2WtyAotY3GEzbNCQVbCGhsvqEKcl+ZEHgShlHXUWvSffq1ZscY6gK7A==
|
||||
"@next/swc-win32-ia32-msvc@13.0.2":
|
||||
version "13.0.2"
|
||||
resolved "https://registry.yarnpkg.com/@next/swc-win32-ia32-msvc/-/swc-win32-ia32-msvc-13.0.2.tgz#a78ee9211471768febac9df915c2a8dbbcd05e41"
|
||||
integrity sha512-ZUBYGZw5G3QrqDpRq1EWi3aHmvPZM8ijK5TFL6UbH16cYQ0JpANmuG2P66KB93Qe/lWWzbeAZk/tj1XqwoCuPA==
|
||||
|
||||
"@next/swc-win32-x64-msvc@12.3.0":
|
||||
version "12.3.0"
|
||||
resolved "https://registry.yarnpkg.com/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-12.3.0.tgz#c1b983316307f8f55fee491942b5d244bd2036e2"
|
||||
integrity sha512-C/nw6OgQpEULWqs+wgMHXGvlJLguPRFFGqR2TAqWBerQ8J+Sg3z1ZTqwelkSi4FoqStGuZ2UdFHIDN1ySmR1xA==
|
||||
"@next/swc-win32-x64-msvc@13.0.2":
|
||||
version "13.0.2"
|
||||
resolved "https://registry.yarnpkg.com/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-13.0.2.tgz#e86c2de910cd68a17974db5556d4588737412c68"
|
||||
integrity sha512-fA9uW1dm7C0mEYGcKlbmLcVm2sKcye+1kPxh2cM4jVR+kQQMtHWsjIzeSpe2grQLSDan06z4n6hbr8b1c3hA8w==
|
||||
|
||||
"@nodelib/fs.scandir@2.1.5":
|
||||
version "2.1.5"
|
||||
@ -1518,10 +1518,10 @@ callsites@^3.0.0:
|
||||
resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73"
|
||||
integrity sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==
|
||||
|
||||
caniuse-lite@^1.0.30001332:
|
||||
version "1.0.30001393"
|
||||
resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001393.tgz#1aa161e24fe6af2e2ccda000fc2b94be0b0db356"
|
||||
integrity sha512-N/od11RX+Gsk+1qY/jbPa0R6zJupEa0lxeBG598EbrtblxVCTJsQwbRBm6+V+rxpc5lHKdsXb9RY83cZIPLseA==
|
||||
caniuse-lite@^1.0.30001406:
|
||||
version "1.0.30001431"
|
||||
resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001431.tgz#e7c59bd1bc518fae03a4656be442ce6c4887a795"
|
||||
integrity sha512-zBUoFU0ZcxpvSt9IU66dXVT/3ctO1cy4y9cscs1szkPlcWb6pasYM144GqrUygUbT+k7cmUCW61cvskjcv0enQ==
|
||||
|
||||
ccount@^2.0.0:
|
||||
version "2.0.1"
|
||||
@ -1580,6 +1580,11 @@ character-reference-invalid@^2.0.0:
|
||||
resolved "https://registry.yarnpkg.com/character-reference-invalid/-/character-reference-invalid-2.0.1.tgz#85c66b041e43b47210faf401278abf808ac45cb9"
|
||||
integrity sha512-iBZ4F4wRbyORVsu0jPV7gXkOsGYjGHPmAyv+HiHG8gi5PtC9KI2j1+v8/tlibRvjoWX027ypmG/n0HtO5t7unw==
|
||||
|
||||
client-only@0.0.1:
|
||||
version "0.0.1"
|
||||
resolved "https://registry.yarnpkg.com/client-only/-/client-only-0.0.1.tgz#38bba5d403c41ab150bff64a95c85013cf73bca1"
|
||||
integrity sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==
|
||||
|
||||
color-convert@^1.9.0:
|
||||
version "1.9.3"
|
||||
resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8"
|
||||
@ -3222,31 +3227,31 @@ natural-compare@^1.4.0:
|
||||
resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7"
|
||||
integrity sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==
|
||||
|
||||
next@^12.3.0:
|
||||
version "12.3.0"
|
||||
resolved "https://registry.yarnpkg.com/next/-/next-12.3.0.tgz#0e4c1ed0092544c7e8f4c998ca57cf6529e286cb"
|
||||
integrity sha512-GpzI6me9V1+XYtfK0Ae9WD0mKqHyzQlGq1xH1rzNIYMASo4Tkl4rTe9jSqtBpXFhOS33KohXs9ZY38Akkhdciw==
|
||||
next@^13.0.2:
|
||||
version "13.0.2"
|
||||
resolved "https://registry.yarnpkg.com/next/-/next-13.0.2.tgz#b8c8642c70f736ed91105645391d335fc51c8f62"
|
||||
integrity sha512-uQ5z5e4D9mOe8+upy6bQdYYjo/kk1v3jMW87kTy2TgAyAsEO+CkwRnMgyZ4JoHEnhPZLHwh7dk0XymRNLe1gFw==
|
||||
dependencies:
|
||||
"@next/env" "12.3.0"
|
||||
"@next/env" "13.0.2"
|
||||
"@swc/helpers" "0.4.11"
|
||||
caniuse-lite "^1.0.30001332"
|
||||
caniuse-lite "^1.0.30001406"
|
||||
postcss "8.4.14"
|
||||
styled-jsx "5.0.6"
|
||||
styled-jsx "5.1.0"
|
||||
use-sync-external-store "1.2.0"
|
||||
optionalDependencies:
|
||||
"@next/swc-android-arm-eabi" "12.3.0"
|
||||
"@next/swc-android-arm64" "12.3.0"
|
||||
"@next/swc-darwin-arm64" "12.3.0"
|
||||
"@next/swc-darwin-x64" "12.3.0"
|
||||
"@next/swc-freebsd-x64" "12.3.0"
|
||||
"@next/swc-linux-arm-gnueabihf" "12.3.0"
|
||||
"@next/swc-linux-arm64-gnu" "12.3.0"
|
||||
"@next/swc-linux-arm64-musl" "12.3.0"
|
||||
"@next/swc-linux-x64-gnu" "12.3.0"
|
||||
"@next/swc-linux-x64-musl" "12.3.0"
|
||||
"@next/swc-win32-arm64-msvc" "12.3.0"
|
||||
"@next/swc-win32-ia32-msvc" "12.3.0"
|
||||
"@next/swc-win32-x64-msvc" "12.3.0"
|
||||
"@next/swc-android-arm-eabi" "13.0.2"
|
||||
"@next/swc-android-arm64" "13.0.2"
|
||||
"@next/swc-darwin-arm64" "13.0.2"
|
||||
"@next/swc-darwin-x64" "13.0.2"
|
||||
"@next/swc-freebsd-x64" "13.0.2"
|
||||
"@next/swc-linux-arm-gnueabihf" "13.0.2"
|
||||
"@next/swc-linux-arm64-gnu" "13.0.2"
|
||||
"@next/swc-linux-arm64-musl" "13.0.2"
|
||||
"@next/swc-linux-x64-gnu" "13.0.2"
|
||||
"@next/swc-linux-x64-musl" "13.0.2"
|
||||
"@next/swc-win32-arm64-msvc" "13.0.2"
|
||||
"@next/swc-win32-ia32-msvc" "13.0.2"
|
||||
"@next/swc-win32-x64-msvc" "13.0.2"
|
||||
|
||||
object-assign@^4.1.1:
|
||||
version "4.1.1"
|
||||
@ -3831,10 +3836,12 @@ style-value-types@5.1.2:
|
||||
hey-listen "^1.0.8"
|
||||
tslib "2.4.0"
|
||||
|
||||
styled-jsx@5.0.6:
|
||||
version "5.0.6"
|
||||
resolved "https://registry.yarnpkg.com/styled-jsx/-/styled-jsx-5.0.6.tgz#fa684790a9cc3badded14badea163418fe568f77"
|
||||
integrity sha512-xOeROtkK5MGMDimBQ3J6iPId8q0t/BDoG5XN6oKkZClVz9ISF/hihN8OCn2LggMU6N32aXnrXBdn3auSqNS9fA==
|
||||
styled-jsx@5.1.0:
|
||||
version "5.1.0"
|
||||
resolved "https://registry.yarnpkg.com/styled-jsx/-/styled-jsx-5.1.0.tgz#4a5622ab9714bd3fcfaeec292aa555871f057563"
|
||||
integrity sha512-/iHaRJt9U7T+5tp6TRelLnqBqiaIT0HsO0+vgyj8hK2KUk7aejFqRrumqPUlAqDwAj8IbS/1hk3IhBAAK/FCUQ==
|
||||
dependencies:
|
||||
client-only "0.0.1"
|
||||
|
||||
stylis@4.0.13:
|
||||
version "4.0.13"
|
||||
@ -3907,7 +3914,7 @@ tsconfig-paths@^3.14.1:
|
||||
minimist "^1.2.6"
|
||||
strip-bom "^3.0.0"
|
||||
|
||||
tslib@2.4.0, tslib@^2.0.0, tslib@^2.0.3, tslib@^2.1.0, tslib@^2.3.1, tslib@^2.4.0:
|
||||
tslib@2.4.0, tslib@^2.0.0, tslib@^2.0.3, tslib@^2.1.0, tslib@^2.3.1:
|
||||
version "2.4.0"
|
||||
resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.4.0.tgz#7cecaa7f073ce680a05847aa77be941098f36dc3"
|
||||
integrity sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==
|
||||
@ -3917,6 +3924,11 @@ tslib@^1.8.1:
|
||||
resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00"
|
||||
integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==
|
||||
|
||||
tslib@^2.4.0:
|
||||
version "2.4.1"
|
||||
resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.4.1.tgz#0d0bfbaac2880b91e22df0768e55be9753a5b17e"
|
||||
integrity sha512-tGyy4dAjRIEwI7BzsB0lynWgOpfqjUdq91XXAlIWD2OwKBH7oCl/GZG/HT4BOHrTlPMOASlMQ7veyTqpmRcrNA==
|
||||
|
||||
tsutils@^3.21.0:
|
||||
version "3.21.0"
|
||||
resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-3.21.0.tgz#b48717d394cea6c1e096983eed58e9d61715b623"
|
||||
|
Loading…
Reference in New Issue
Block a user