System Requirements
The Zora Mainnet archive node has a size of 693GB on October 10th, 2024
Zora
Zora operates within the Optimism Superchain ecosystem and is built using the OP stack, which leverages the scalability and security of Optimism's Layer 2 infrastructure.
In this guide, we will walk you through the process of setting up a Zora Mainnet archive node using Optimism's op-geth
and op-node
tools.
Before you begin, ensure you have a synced Ethereum L1 RPC URL (such as Erigon) and an L1 Consensus Layer Beacon endpoint that includes all historical blobs data (for example, Lighthouse). Having a suitable beacon endpoint is crucial for the syncing process to initiate.
Tip: You can create a free account at Chainstack to obtain enough resources for syncing your node.
Pre-Requisites
To the archive node using Docker we need the following installed:
Commands:
Copy sudo apt update -y && sudo apt upgrade -y && sudo apt auto-remove -y
sudo apt install docker.io docker-compose git ufw -y
Firewall Setting:
Set explicit default UFW rules
Copy sudo ufw default deny incoming
sudo ufw default allow outgoing
Allow SSH, HTTP, and HTTPS
Copy sudo ufw allow 22/tcp
sudo ufw allow 80
sudo ufw allow 443
Allow Remote connection:
Copy sudo ufw allow from ${REMOTE.HOST.IP} to any port 8545
sudo ufw allow from ${REMOTE.HOST.IP} to any port 7545
Firewall Basic commands:
Copy services :
op-geth : # this is Optimism's geth client
...
volumes :
- /mnt/zora-data:/data # enable to have persistency between restarts
...
Example Docker Compose:
Copy version : '3.8'
services :
op-geth : # this is Optimism's geth client
pull_policy : always
build :
context : .
dockerfile : op-geth.Dockerfile
ports :
- 8545:8545 # RPC
- 8546:8546 # websocket
- 30303:30303 # P2P TCP (currently unused)
- 30303:30303/udp # P2P UDP (currently unused)
- 7301:6060 # metrics
env_file :
- .env.default
- networks/${CONDUIT_NETWORK:?set network}/.env
- .env
volumes :
#- ./geth-data/:/data # enable to have persistency between restarts
- ./networks/${CONDUIT_NETWORK:?set network}/genesis.json:/genesis.json
op-node :
pull_policy : always
build :
context : .
dockerfile : op-node.Dockerfile
depends_on :
- op-geth
ports :
- 7545:8545 # RPC
- 9222:9222 # P2P TCP
- 9222:9222/udp # P2P UDP
- 7300:7300 # metrics
- 6060:6060 # pprof
env_file :
- .env.default
- networks/${CONDUIT_NETWORK:?set network}/.env
- .env
volumes :
- ./networks/${CONDUIT_NETWORK:?set network}/rollup.json:/rollup.json
- ./networks/${CONDUIT_NETWORK:?set network}/genesis.json:/genesis.json
Start Services Containers:
Copy docker compose up -d --build
Check Status:
Below is the command for the request:
Copy curl -d '{"id":0,"jsonrpc":"2.0","method":"eth_getBlockByNumber","params":["latest",false]}' -H "Content-Type: application/json" http://localhost:8545 | jq .
You will see a response like:
Copy {
"jsonrpc" : "2.0" ,
"id" : 0 ,
"result" : {
"baseFeePerGas" : "0xfc" ,
"blobGasUsed" : "0x0" ,
"difficulty" : "0x0" ,
"excessBlobGas" : "0x0" ,
"extraData" : "0x" ,
"gasLimit" : "0x1c9c380" ,
"gasUsed" : "0xab4b" ,
"hash" : "0x3ef9dfddbcf06e31ea6fa488834682287e8405b685299b9c1acb939ec81308bd" ,
"logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
"miner" : "0x4200000000000000000000000000000000000011" ,
"mixHash" : "0xf4fd464784037be144c017dd88a03f1fc234c65728caa8dd2195e1303f84c107" ,
"nonce" : "0x0000000000000000" ,
"number" : "0x13edd8a" ,
"parentBeaconBlockRoot" : "0x94b9941e2ac80450845656ad054e6cbeb656e6f408194e55025be9d4da6bae70" ,
"parentHash" : "0x6b77bb5a6ef5a31cbc014867cb9a666c589a90a937b4b0e060aa4734b5ddc59e" ,
"receiptsRoot" : "0x49af9e31125af317a81e30bcf9db9419afdbb4afd808c2a16bef3ff9167db3a1" ,
"sha3Uncles" : "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347" ,
"size" : "0x348" ,
"stateRoot" : "0xba115af0f6448b6bc1333880b5c7a1b6a210b8774d698446b1f3810ed17f7fbc" ,
"timestamp" : "0x6706a2e3" ,
"totalDifficulty" : "0x0" ,
"transactions" : [
"0xaf32e05388d009011ad28fd010af52ee9da6decc0a04313843419fd6414ae935"
] ,
"transactionsRoot" : "0x854a1e051237917389c365790d1b1bb18059bf8f91602ef2e6e51555f71eae49" ,
"uncles" : [] ,
"withdrawals" : [] ,
"withdrawalsRoot" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421"
}
}
Sync Status:
Copy command -v jq & > /dev/null || { echo "jq is not installed" 1>&2 ; }
echo Latest synced block behind by: \
$((($( date +%s )-\
$( curl -s -d '{"id":0,"jsonrpc":"2.0","method":"optimism_syncStatus"}' -H "Content-Type: application/json" http://localhost:7545 |
jq -r .result.unsafe_l2.timestamp ))/60)) minutes
References: