Skip to main content

Running a node

Instructions to set up your Immutable zkEVM node.

Requirements

  • Minimum hardware requirements: 2 AWS vCPU, 4GB RAM, 100GB free storage space.
  • Ubuntu 22.04.1 (tested on 22.04.1)
  • Official Documentation

Prerequisites

💡Allowlisted Peering
Currently, peering with Immutable zkEVM is restricted to partners and requires that Immutable allowlist you either via WireGuard or static IP.
  1. Install Docker
  2. (Optional) If you plan to use WireGuard (see Get access to the Immutable zkEVM partner nodes), install it.
sudo apt-get install wireguard

Instructions

Get access to the Immutable zkEVM partner nodes

The Immutable zkEVM blockchain has dedicated nodes that serve as access points for partners wanting to peer with the network. Immutable protects these nodes from bad actors trying to disrupt partner services by putting limits on who can establish a connection.

Partners can choose between a static IP allowlist or a WireGuard tunnel to establish their connections.

The static IP allowlist ensures only a predetermined list of approved IP addresses can establish connections.

The WireGuard tunnel provides partners with a secure and private conduit for their connections to the Immutable zkEVM, without requiring a static IP.

Reach out to your Immutable point of contact providing your static IP. For example:

Please add my static IP to the Immutable allowlist: _STATIC_IP_

The Immutable team will reply with a confirmation that your IP has been added to the allowlist.

Setup the Immutable zkEVM node

  1. Create a data directory.
mkdir /opt/immutable-zkevm
  1. Pull the Docker image.
docker pull ghcr.io/immutable/go-ethereum/go-ethereum:latest
# Create a short-form tag we can reference in the next few commands
docker tag ghcr.io/immutable/go-ethereum/go-ethereum:latest geth
  1. Initialise the node.
docker run \
--rm \
-v /opt/immutable-zkevm:/mnt/geth \
--name geth \
geth immutable bootstrap rpc \
--zkevm testnet \
--datadir /mnt/geth
  1. Start the Immutable zkEVM node as a service
docker run \
-d \
--restart=always \
-v /opt/immutable-zkevm:/mnt/geth \
--name geth \
-p 8545:8545 \
geth \
--zkevm testnet \
--config /etc/geth/testnet.toml \
--datadir /mnt/geth \
--http \
--http.port "8545" \
--http.addr "0.0.0.0"

Verify your deployment

  1. Check the logs.
docker logs geth

An output similar to the following logs indicates you are synching from the genesis block.

INFO [12-04|04:54:26.418] Maximum peer count                       ETH=100 LES=0 total=100
INFO [12-04|04:54:26.421] Smartcard socket not found, disabling err="stat /run/pcscd/pcscd.comm: no such file or directory"
INFO [12-04|04:54:26.422] initialising New Relic agent...
ERROR[12-04|04:54:26.422] Failed to initialise New Relic agent: NEW_RELIC_APP_NAME missing
INFO [12-04|04:54:26.433] Enabling recording of key preimages since archive mode is used
INFO [12-04|04:54:26.446] Using pebble as the backing database
INFO [12-04|04:54:26.446] Allocated cache and file handles database=/mnt/geth/geth/chaindata cache=512.00MiB handles=524,288
INFO [12-04|04:54:26.504] Opened ancient database database=/mnt/geth/geth/chaindata/ancient/chain readonly=true
INFO [12-04|04:54:26.505] State scheme set to already existing scheme=hash
INFO [12-04|04:54:26.508] Set global gas cap cap=50,000,000
INFO [12-04|04:54:26.509] Initializing the KZG library backend=gokzg
INFO [12-04|04:54:26.650] Allocated trie memory caches clean=512.00MiB dirty=0.00B
INFO [12-04|04:54:26.650] Using pebble as the backing database
INFO [12-04|04:54:26.650] Allocated cache and file handles database=/mnt/geth/geth/chaindata cache=512.00MiB handles=524,288
INFO [12-04|04:54:26.730] Opened ancient database database=/mnt/geth/geth/chaindata/ancient/chain readonly=false
INFO [12-04|04:54:26.753] Initialising Ethereum protocol network=13473 dbversion=8
INFO [12-04|04:54:26.754]
INFO [12-04|04:54:26.754] ---------------------------------------------------------------------------------------------------------------------------------------------------------
INFO [12-04|04:54:26.754] Chain ID: 13473 (unknown)
INFO [12-04|04:54:26.754] Reorg Invariants Enabled: true
INFO [12-04|04:54:26.754] Consensus: Clique (proof-of-authority)
INFO [12-04|04:54:26.754]
INFO [12-04|04:54:26.754] Pre-Merge hard forks (block based):
INFO [12-04|04:54:26.754] - Homestead: #0 (https://github.com/ethereum/execution-specs/blob/master/network-upgrades/mainnet-upgrades/homestead.md)
INFO [12-04|04:54:26.754] - Tangerine Whistle (EIP 150): #0 (https://github.com/ethereum/execution-specs/blob/master/network-upgrades/mainnet-upgrades/tangerine-whistle.md)
INFO [12-04|04:54:26.754] - Spurious Dragon/1 (EIP 155): #0 (https://github.com/ethereum/execution-specs/blob/master/network-upgrades/mainnet-upgrades/spurious-dragon.md)
INFO [12-04|04:54:26.754] - Spurious Dragon/2 (EIP 158): #0 (https://github.com/ethereum/execution-specs/blob/master/network-upgrades/mainnet-upgrades/spurious-dragon.md)
INFO [12-04|04:54:26.754] - Byzantium: #0 (https://github.com/ethereum/execution-specs/blob/master/network-upgrades/mainnet-upgrades/byzantium.md)
INFO [12-04|04:54:26.754] - Constantinople: #0 (https://github.com/ethereum/execution-specs/blob/master/network-upgrades/mainnet-upgrades/constantinople.md)
INFO [12-04|04:54:26.754] - Petersburg: #0 (https://github.com/ethereum/execution-specs/blob/master/network-upgrades/mainnet-upgrades/petersburg.md)
INFO [12-04|04:54:26.754] - Istanbul: #0 (https://github.com/ethereum/execution-specs/blob/master/network-upgrades/mainnet-upgrades/istanbul.md)
INFO [12-04|04:54:26.754] - Muir Glacier: #0 (https://github.com/ethereum/execution-specs/blob/master/network-upgrades/mainnet-upgrades/muir-glacier.md)
INFO [12-04|04:54:26.754] - Berlin: #0 (https://github.com/ethereum/execution-specs/blob/master/network-upgrades/mainnet-upgrades/berlin.md)
INFO [12-04|04:54:26.754] - London: #0 (https://github.com/ethereum/execution-specs/blob/master/network-upgrades/mainnet-upgrades/london.md)
INFO [12-04|04:54:26.754] - Arrow Glacier: #0 (https://github.com/ethereum/execution-specs/blob/master/network-upgrades/mainnet-upgrades/arrow-glacier.md)
INFO [12-04|04:54:26.754] - Gray Glacier: #0 (https://github.com/ethereum/execution-specs/blob/master/network-upgrades/mainnet-upgrades/gray-glacier.md)
INFO [12-04|04:54:26.754]
INFO [12-04|04:54:26.754] The Merge is not yet available for this network!
INFO [12-04|04:54:26.754] - Hard-fork specification: https://github.com/ethereum/execution-specs/blob/master/network-upgrades/mainnet-upgrades/paris.md
INFO [12-04|04:54:26.754]
INFO [12-04|04:54:26.754] Post-Merge hard forks (timestamp based):
INFO [12-04|04:54:26.754]
INFO [12-04|04:54:26.754] ---------------------------------------------------------------------------------------------------------------------------------------------------------
INFO [12-04|04:54:26.754]
INFO [12-04|04:54:26.755] Loaded most recent local block number=1,343,036 hash=b5bb3f..cbe4f1 td=2,686,073 age=1m17s
WARN [12-04|04:54:26.893] Sanitizing invalid blobpool storage cap provided=0 updated=10,737,418,240
INFO [12-04|04:54:26.893] Initialized transaction indexer limit=2,350,000
INFO [12-04|04:54:26.929] Gasprice oracle is ignoring threshold set threshold=2
INFO [12-04|04:54:26.935] Shutdown tracker started marker
WARN [12-04|04:54:26.935] Engine API enabled protocol=eth
WARN [12-04|04:54:26.935] Engine API started but chain not configured for merge yet
INFO [12-04|04:54:26.935] Starting peer-to-peer node instance=Geth/v1.13.0-unstable-cb37d5a3-20231204/linux-amd64/go1.21.4
INFO [12-04|04:54:26.975] IPC endpoint opened url=/mnt/geth/geth.ipc
INFO [12-04|04:54:26.975] Loaded JWT secret file path=/mnt/geth/geth/jwtsecret crc32=0xaa03f756
time="2023-12-04T04:54:26Z" level=error msg="Failed to initialise New Relic middlware: nrApp is nil"
time="2023-12-04T04:54:26Z" level=error msg="Failed to initialise New Relic middlware: nrApp is nil"
INFO [12-04|04:54:26.976] WebSocket enabled url=ws://127.0.0.1:8551
INFO [12-04|04:54:26.976] HTTP server started endpoint=127.0.0.1:8551 auth=true prefix= cors=localhost vhosts=localhost
INFO [12-04|04:54:26.981] New local node record seq=1,701,654,445,241 id=660d517490a62260 ip=127.0.0.1 udp=0 tcp=0
INFO [12-04|04:54:26.981] Started P2P networking self=enode://9040706fed7d4ac85ff44ac1ad54b28ec39b585ec23a5dacb920163d95dd576ca0ab8d2ba4b590a16a183bc14114ac299f2712ada37f8060be684983b1d5016f@127.0.0.1:0
INFO [12-04|04:54:36.978] Block synchronisation started
INFO [12-04|04:54:37.205] Imported new chain segment number=1,343,079 hash=560a17..971f02 blocks=43 txs=0 mgas=0.000 elapsed=205.607ms mgasps=0.000 triedirty=0.00B
INFO [12-04|04:54:37.518] Imported new chain segment number=1,343,080 hash=db30ec..114a94 blocks=1 txs=0 mgas=0.000 elapsed=4.535ms mgasps=0.000 triedirty=0.00B
INFO [12-04|04:54:39.517] Imported new chain segment number=1,343,081 hash=b72134..f35f55 blocks=1 txs=0 mgas=0.000 elapsed=4.587ms mgasps=0.000 triedirty=0.00B
INFO [12-04|04:54:41.015] Imported new chain segment number=1,343,082 hash=882e89..2b8def blocks=1 txs=0 mgas=0.000 elapsed=5.473ms mgasps=0.000 triedirty=0.00B
INFO [12-04|04:54:43.012] Imported new chain segment number=1,343,083 hash=39f454..608c0c blocks=1 txs=0 mgas=0.000 elapsed=4.066ms mgasps=0.000 triedirty=0.00B
INFO [12-04|04:54:45.518] Imported new chain segment number=1,343,084 hash=aa9eb2..f83f8f blocks=1 txs=0 mgas=0.000 elapsed=4.481ms mgasps=0.000 triedirty=0.00B
INFO [12-04|04:54:47.517] Imported new chain segment number=1,343,085 hash=8161fb..9142ec blocks=1 txs=0 mgas=0.000 elapsed=3.971ms mgasps=0.000 triedirty=0.00B
INFO [12-04|04:54:49.516] Imported new chain segment number=1,343,086 hash=fd6e70..0bf228 blocks=1 txs=0 mgas=0.000 elapsed=4.095ms mgasps=0.000 triedirty=0.00B
INFO [12-04|04:54:51.011] Imported new chain segment number=1,343,087 hash=9bf651..57e23e blocks=1 txs=0 mgas=0.000 elapsed=5.172ms mgasps=0.000 triedirty=0.00B
...
  1. Check the chain ID.

From the container host.

curl http://localhost:8545 \
-X POST \
-H "Content-Type: application/json" \
--data '{"method":"eth_chainId","params":[],"id":1,"jsonrpc":"2.0"}'

Compare it to the output reported by Immutable nodes.

curl https://rpc.testnet.immutable.com \
-X POST \
-H "Content-Type: application/json" \
--data '{"method":"eth_chainId","params":[],"id":1,"jsonrpc":"2.0"}'

The output should be:

{"jsonrpc":"2.0","id":1,"result":"0x34a1"}