This guide will provide you with a minimal instruction set if you intend to test:
Spinning up a zhejiang testnet node using Geth&Lighthouse with Docker(-Compose)
Exiting/withdrawing a validator on zhejiang testnet
Preparing withdrawal credential changes
Feel free to check out elementary guides on how to run testnet nodes with the help of Docker or Docker-Compose.
Also, if you’re generally keen on running a production (or testnet) Ethereum node with Docker, check out the awesome eth-docker.net project.
Very fast node initialisation time (i.e. no extended sync periods + takes less than 2GBs of disk space)
Easy to obtain testnet ETH
It’s a short-lived, public testnet particularly designed for brief operation tests
Dry-run prior to more established testnets like Sepolia & Goerli which will follow in February/March ´23
As an example client pair we’ll use Geth & Lighthouse on an Ubuntu instance & pre-installed docker-compose - feel free to adapt to different client pairs using this documentation.
Navigate in a terminal/CLI to your user’s /home directory. Create a project directory with subfolders
$ mkdir -p zhejiang/{geth,lighthouse-bn,lighthouse-vc,JWT,validator_keys}; cd zhejiang
Retrieve configuration files for the zhejiang genesis from a repository maintained by the Ethereum Foundation
$ git clone https://github.com/ethpandaops/withdrawals-testnet.git
Generate a JasonWebToken (JWT) so that the execution and consensus client can communicate securely
$ openssl rand -hex 32 | tr -d "\n" > "$(pwd)/JWT/jwtsecret"
Provide Geth with the testnet genesis configuration
$ docker run -it -v $(pwd)/geth:/root/.ethereum -v $(pwd)/withdrawals-testnet/zhejiang-testnet/custom_config_data/genesis.json:/genesis.json ethpandaops/geth:master --datadir /root/.ethereum init genesis.json
Depending on your Docker configuration every Docker command should be preceded by
sudo
Copy & paste the below attached Docker-Compose code in a newly created file to be named “docker-compose.yaml” located in the project directory /zhejiang
👇
version: "3.4"
services:
consensus:
image: sigp/lighthouse:capella
container_name: beacon
tty: true
restart: on-failure
volumes:
- ./lighthouse-bn:/root/.lighthouse
- ./JWT:/JWT
- ./withdrawals-testnet/zhejiang-testnet/custom_config_data:/zhejiang
ports:
- 127.0.0.1:5052:5052 # consensus http
- 9000:9000/tcp # consensus p2p, open to internet
- 9000:9000/udp # consensus p2p, open to internet
command: >
lighthouse
--testnet-dir zhejiang
beacon_node
--datadir /root/.lighthouse
--eth1
--http
--http-allow-sync-stalled
--http-address 0.0.0.0
--enr-udp-port 9000
--enr-tcp-port 9000
--discovery-port 9000
--validator-monitor-auto
--execution-endpoints http://geth:8551
--execution-jwt /JWT/jwtsecret
--boot-nodes="enr:-Iq4QMCTfIMXnow27baRUb35Q8iiFHSIDBJh6hQM5Axohhf4b6Kr_cOCu0htQ5WvVqKvFgY28893DHAg8gnBAXsAVqmGAX53x8JggmlkgnY0gmlwhLKAlv6Jc2VjcDI1NmsxoQK6S-Cii_KmfFdUJL2TANL3ksaKUnNXvTCv1tLwXs0QgIN1ZHCCIyk,enr:-Ly4QOS00hvPDddEcCpwA1cMykWNdJUK50AjbRgbLZ9FLPyBa78i0NwsQZLSV67elpJU71L1Pt9yqVmE1C6XeSI-LV8Bh2F0dG5ldHOIAAAAAAAAAACEZXRoMpDuKNezAAAAckYFAAAAAAAAgmlkgnY0gmlwhEDhTgGJc2VjcDI1NmsxoQIgMUMFvJGlr8dI1TEQy-K78u2TJE2rWvah9nGqLQCEGohzeW5jbmV0cwCDdGNwgiMog3VkcIIjKA,enr:-MK4QMlRAwM7E8YBo6fqP7M2IWrjFHP35uC4pWIttUioZWOiaTl5zgZF2OwSxswTQwpiVCnj4n56bhy4NJVHSe682VWGAYYDHkp4h2F0dG5ldHOIAAAAAAAAAACEZXRoMpDuKNezAAAAckYFAAAAAAAAgmlkgnY0gmlwhJK-7tSJc2VjcDI1NmsxoQLDq7LlsXIXAoJXPt7rqf6CES1Q40xPw2yW0RQ-Ly5S1YhzeW5jbmV0cwCDdGNwgiMog3VkcIIjKA,enr:-MS4QCgiQisRxtzXKlBqq_LN1CRUSGIpDKO4e2hLQsffp0BrC3A7-8F6kxHYtATnzcrsVOr8gnwmBnHYTFvE9UmT-0EHh2F0dG5ldHOIAAAAAAAAAACEZXRoMpDuKNezAAAAckYFAAAAAAAAgmlkgnY0gmlwhKXoVKCJc2VjcDI1NmsxoQK6J-uvOXMf44iIlilx1uPWGRrrTntjLEFR2u-lHcHofIhzeW5jbmV0c4gAAAAAAAAAAIN0Y3CCIyiDdWRwgiMo,enr:-LK4QOQd-elgl_-dcSoUyHDbxBFNgQ687lzcKJiSBtpCyPQ0DinWSd2PKdJ4FHMkVLWD-oOquXPKSMtyoKpI0-Wo_38Bh2F0dG5ldHOIAAAAAAAAAACEZXRoMpDuKNezAAAAckYFAAAAAAAAgmlkgnY0gmlwhES3DaqJc2VjcDI1NmsxoQNIf37JZx-Lc8pnfDwURcHUqLbIEZ1RoxjZuBRtEODseYN0Y3CCIyiDdWRwgiMo,enr:-KG4QLNORYXUK76RPDI4rIVAqX__zSkc5AqMcwAketVzN9YNE8FHSu1im3qJTIeuwqI5JN5SPVsiX7L9nWXgWLRUf6sDhGV0aDKQ7ijXswAAAHJGBQAAAAAAAIJpZIJ2NIJpcIShI5NiiXNlY3AyNTZrMaECpA_KefrVAueFWiLLDZKQPPVOxMuxGogPrI474FaS-x2DdGNwgiMog3VkcIIjKA"
validator:
image: sigp/lighthouse:capella
container_name: vc
tty: true
restart: on-failure
volumes:
- ./lighthouse-vc:/root/.lighthouse
- ./withdrawals-testnet/zhejiang-testnet/custom_config_data:/zhejiang
depends_on:
- consensus
command: >
lighthouse
--testnet-dir zhejiang
validator
--beacon-nodes http://beacon:5052
--suggested-fee-recipient 0x0000000000000000000000000000000000000000
execution:
image: ethpandaops/geth:master
container_name: geth
tty: true
restart: on-failure
volumes:
- ./geth:/root/.ethereum
- ./JWT:/JWT
ports:
- 127.0.0.1:8551:8551 # engine rpc
- 30303:30303/tcp # execution p2p, open to internet
- 30303:30303/udp # execution p2p, open to internet
- 8545:8545
command: >
--datadir /root/.ethereum
--http
--http.addr 0.0.0.0
--http.vhosts *
--http.corsdomain *
--http.api engine,eth,web3,net,debug
--http.port 8545
--authrpc.jwtsecret /JWT/jwtsecret
--authrpc.addr 0.0.0.0
--authrpc.port 8551
--authrpc.vhosts *
--networkid 1337803
--syncmode full
--bootnodes "enode://691c66d0ce351633b2ef8b4e4ef7db9966915ca0937415bd2b408df22923f274873b4d4438929e029a13a680140223dcf701cabe22df7d8870044321022dfefa@64.225.78.1:30303,enode://89347b9461727ee1849256d78e84d5c86cc3b4c6c5347650093982b726d71f3d08027e280b399b7b6604ceeda863283dcfe1a01e93728b4883114e9f8c7cc8ef@146.190.238.212:30303,enode://c2892072efe247f21ed7ebea6637ade38512a0ae7c5cffa1bf0786d5e3be1e7f40ff71252a21b36aa9de54e49edbcfc6962a98032adadfa29c8524262e484ad3@165.232.84.160:30303,enode://71e862580d3177a99e9837bd9e9c13c83bde63d3dba1d5cea18e89eb2a17786bbd47a8e7ae690e4d29763b55c205af13965efcaf6105d58e118a5a8ed2b0f6d0@68.183.13.170:30303,enode://2f6cf7f774e4507e7c1b70815f9c0ccd6515ee1170c991ce3137002c6ba9c671af38920f5b8ab8a215b62b3b50388030548f1d826cb6c2b30c0f59472804a045@161.35.147.98:30303"
Start the Docker-Compose environment
$ docker-compose up
Eventually, stop the docker-compose environment: $ docker-compose stop
For stopping only the beacon or execution or validator client services use:
$ docker-compose stop execution/consensus/validator
Steps 1-4 are well-documented elsewhere:
Receive 33 zETH from a faucet
Generate validator keys (e.g. with Staking-CLI) using 0x00 credentials (for test purposes)
Deposit via zhejiang launchpad
Look out for your validator on a block explorer
Move generated keys into project folder subdirectory /validator_keys
Import validator key(s) to Lighthouse
👉 based of the project directory /zhejiang
prompt:
$ docker run -it -v $(pwd)/lighthouse-vc:/root/.lighthouse -v $(pwd)/validator_keys:/validator_keys -v $(pwd)/withdrawals-testnet/zhejiang-testnet/custom_config_data:/zhejiang sigp/lighthouse:capella lighthouse --testnet-dir zhejiang account validator import --directory /validator_keys
Provide the consensus client with the necessary information in order to be released from consensus duties.
While your validator client is running in the background prompt:
$ docker-compose run --rm --no-deps -v $(pwd)/lighthouse-vc:/root/.lighthouse -v $(pwd)/withdrawals-testnet/zhejiang-testnet/custom_config_data:/zhejiang consensus lighthouse --testnet-dir zhejiang account validator exit --beacon-node http://beacon:5052 --keystore /root/.lighthouse/custom/validators/<0x_yourvalidatorkey>/voting-keystore.json
Edit the validator key directory and voting-keystore.json filename accordingly
Note for mainnet: node operators have to keep on running their node until the validator reaches its assigned exit epoch (s. block explorer) - if it is shutdown too early, the validator will incur penalties.
…also known as “BLS to Execution” operation. This operation comprises of a message broadcast to the network which will lead to a change from the BLS withdrawal credentials (0x00) to a regular Ethereum address (0x01) of your choice.
Note: currently around ~60% or ~300,000 mainnet validators have BLS credentials and need to make a one-time change to a regular Ethereum address in order to fully or partially withdraw their stake or rewards.
Find out how to identify withdrawal credentials by entering a validator index on beaconcha.in:
If you want to test changing withdrawal credentials from 0x00 -> 0x01, check out these Docker instructions utilising a programm called ethdo
by attestant.io.
The official Staking-Deposit-CLI by the EF will be updated and include similar functionality shortly.
👉 Broadcasting of your BLS-to-execution key change will NOT happen before the (Zhejiang) Shanghai/Capella fork scheduled for the 07th of February 3 p.m. UTC
Up until then the generated message is just stored in a local pool. Once Shanghai/Capella is triggered, the BLS-to-execution messages will be automatically broadcasted/gossiped over the network to your peers.
As soon as a node holding your BLS-to-execution message proposes a block, the message will be executed.
Note for mainnet:
Be aware that changing withdrawal credentials involves providing withdrawal private keys. Thus,*never trust* instructions from a random stranger writing blogposts on mirror.xyz or elsewhere - instead: follow official announcements from client teams and developers
BLS-to-execution messages cannot be broadcasted until after the Shanghai/Capella hard fork
beaconcha.in have announced they will provide a web interface for dragging & dropping a signed credential-change.json file and submit it to the network
****
Please keep in mind this is a testnet guide that may contain mistakes and that takes shortcuts which come with trade-offs. It could quickly become outdated as it’s subject to ever evolving network and client changes.
****
featured image CC BY-NC 2.0 by Matthew Warner
********
This post was supported by a grant from a CLR funding round held by EthStaker, mainly matched by the EF.