Geth
Go Ethereum, the reference execution client. Since the Merge a full node needs two processes: an execution client (Geth) and a consensus client (Lighthouse, Prysm, Teku, Nimbus), connected over the Engine API with a shared JWT secret. Geth alone no longer syncs mainnet.
For local development that separation is avoidable — geth --dev runs a
single-process chain that seals a block whenever a transaction arrives.
Install
# Windows: add the install directory to PATH
C:\Program Files\Geth
geth version
Development chain
The quickest path, and what most local work needs:
geth --dev --http --http.api eth,web3,net --datadir /tmp/geth-dev
--dev pre-funds a developer account, uses instant sealing and needs no genesis
file. Note that Anvil and the Hardhat network are usually more convenient for
contract work — see Development tools. Reach for Geth
when the node's own behaviour is what you are testing.
Private chain
genesis.json describes the chain's parameters and initial state. It is not the
genesis block itself — Geth builds that from it.
{
"config": {
"chainId": 15,
"homesteadBlock": 0,
"eip150Block": 0,
"eip155Block": 0,
"eip158Block": 0,
"byzantiumBlock": 0,
"constantinopleBlock": 0,
"petersburgBlock": 0,
"istanbulBlock": 0,
"berlinBlock": 0,
"londonBlock": 0,
"clique": {
"period": 5,
"epoch": 30000
}
},
"difficulty": "0x1",
"gasLimit": "0x1c9c380",
"extradata": "0x0000000000000000000000000000000000000000000000000000000000000000SEALER_ADDRESS_WITHOUT_0x0000000000000000000000000000000000000000000000000000000000000000000000000000000000",
"alloc": {
"0xYOUR_ADDRESS": { "balance": "1000000000000000000000" }
}
}
Things the short version of this file gets wrong:
chainId, notchainID. The JSON key is case-sensitive; the wrong spelling is ignored and the chain ID defaults to 0, which breaks EIP-155 replay protection and every wallet that connects.gasLimitmust be realistic."0x0000008"is 8 gas — not enough for any transaction, so the chain accepts nothing.0x1c9c380is 30 000 000, matching mainnet.- Proof of work is gone.
difficultyand mining no longer apply after the Merge. A standalone private chain uses Clique proof of authority, which needs thecliqueconfig block and the sealer address embedded inextradata. - Declare every fork. Omitting fork blocks leaves the chain on ancient rules, so recent opcodes are unavailable and contracts compiled with a current Solidity version fail to deploy.
allocpre-funds accounts. Without it there is no ether on the chain and nothing can be deployed, since PoA gives no block rewards.
Setting up the extradata field by hand is error-prone. puppeth used to
generate it and has been removed; the practical alternative for a throwaway
chain is geth --dev, and for a persistent one, a tool such as
ethereum-genesis-generator.
Initialise
geth init --datadir "E:\temp\eth-data" "E:\temp\eth-data\genesis.json"
Run this once per data directory. Re-running against an existing chain fails
rather than resetting it — delete the geth subdirectory to start over, but
keep keystore, which holds the accounts.
Run
geth --datadir "E:\temp\eth-data" --networkid 15 --http --http.addr 127.0.0.1 --http.api eth,net,web3
| Flag | Purpose |
|---|---|
--datadir | Chain data and keystore location |
--networkid | Must match chainId for a private chain |
--http | Enable the JSON-RPC HTTP server (port 8545) |
--http.addr | Bind address |
--http.api | Which API namespaces to expose |
--dev | Ephemeral development chain, instant sealing |
--syncmode light no longer exists. Light client support (LES) was deprecated
and removed; the modes are snap (default) and full.
Binding to --http.addr 0.0.0.0 exposes the RPC endpoint to the network. On a
node holding real keys that is remote control of the funds — bind to 127.0.0.1
and put a proxy in front if remote access is genuinely needed.
Accounts
The personal API was removed in Geth 1.14. Account management is now a
subcommand or an external signer:
geth account new --datadir "E:\temp\eth-data"
geth account list --datadir "E:\temp\eth-data"
geth account import --datadir "E:\temp\eth-data" private-key.txt
For signing from scripts, use Clef, the standalone signer, rather than unlocking an account inside the node.
JavaScript console
geth attach # IPC, same machine
geth attach ipc:\\.\pipe\geth.ipc # Windows named pipe
geth attach http://127.0.0.1:8545 # over HTTP
// Node information
admin.nodeInfo
admin.nodeInfo.enode // the address other nodes connect to
admin.peers
// Accounts and balances
eth.accounts
eth.blockNumber
eth.getBalance(eth.accounts[0])
web3.fromWei(eth.getBalance(eth.accounts[0]), "ether")
// Transactions
eth.sendTransaction({
from: eth.accounts[0],
to: eth.accounts[1],
value: web3.toWei(5, "ether")
})
eth.getBlock(6)
eth.getTransaction("0x3b446dd1241a0caaac0c33c66770205fa01368b2772ab391f9526436817402a8")
eth.getTransactionReceipt("0x...") // status 0x1 succeeded, 0x0 reverted
// Pending transactions
txpool.status
txpool.inspect
The console bundles an old web3.js 0.x, which is why it uses web3.toWei rather
than web3.utils.toWei. That applies only inside the console — application code
uses whatever version you installed.
These no longer work:
personal.newAccount() // removed in Geth 1.14
personal.unlockAccount(...) // removed
miner.start(1) // proof of work; removed after the Merge
admin.sleepBlocks(1) // removed
Related
- Ethereum fundamentals — chain ID versus network ID, gas, nonces.
- Development tools — Anvil and the Hardhat network, which are usually the better local chain.