Guide to Deploying your own Local Ethereum PoS Testnet
By Zoraiz Mahmood, Blockchain Engineer (Views are my own)
Rate limited on the Alchemy Sepolia Faucet again? Tired of paying for Goerli Eth?
This guide will walk you through the process to deploying your own local multi-validator Ethereum Proof of Stake Testnet. You'll learn about genesis files, bootnodes, execution clients, consensus clients and more. By the end of this, you'll have deployed a local Proof of Stake Testnet that you can interact with. The entire process will be explained and run in a local setup, to empower readers to modify the setup as required.
I'm Rez, a Blockchain Engineer. I've worked for 5 years with blockchain technology, having worked across more than 6 different blockchain protocols and 4 different smart contract languages. Currently, I'm a Senior Blockchain Engineer at Immutable. You can find me on twitter/X @0xZorz.
Architecture
We want the deployment to mimick the conditions of Ethereum mainnet as closely as possible. This means, block time and slashing conditions should be consistent.
We'll be using Geth as our execution client and Prysm as our consensus client.
To ensure that readers can follow along with appropriate version, this Github repository will be used. The Github repository serves as an automated deployment of this local network and serves as the source of truth for a local deployment. This article will be a walkthrough of the scripts in the github repository. I recommend following along this script
Let's discuss the fundamental issues that arise when attempting to bootstrap a PoS network.
Peer Discovery
When bootstrapping a new network with multiple nodes, we need a way for nodes to 'discover' eachother over the network. A parallel can be made to service discovery in the microservices architecture which is a solved problem. Both the execution client (Go-Ethereum) and the consensus client (Prysm) have independent peer discovery mechanisms, as such we create two bootnodes which serve as the registry for peers. A bootnode can also participate in consensus.
In the script provided,
For Geth, we create the bootnode as such (see the script in Github for full context)
For Prysm, there is no explicit bootnode binary, so instead we set the first Prysm node as the consensus client bootnode
Initial Validator Set
WIthout a running blockchain, there is no way to execute a 'deposit'. Who are you going to send the transaction to? For this reason, we generate an initial validator set. This initial validator set is defined according to the ETH2 interop standards. This will define the genesis state of the beacon chain such that a number of validators have deposited, even when they haven't. In a network with real value, this would be problematic as the validators have essentially been minted 32 ETH each for free. In this script, this is observed when we make the genesis for the beacon chain, defining the number of validators.
Syncing
When bootstrapping a new network, we need to ensure that nodes have peered with eachother before they start producing blocks, otherwise they will produce different different parrallel chains and none of the chains will get enough votes to reconcile the forks. For this reason, we define the min-sync-peers
flag when starting the consensus client
Now with a knowledge of the some core issues, let's dive in to the actual scripts
Running the Testnet
Step 1
Clone the template repository recursively, as we use git submodules.
git clone --recursive https://github.com/rzmahmood/ethereum-pos-testnet.git
cd ethereum-pos-testnet
Step 2
Install dependencies
Step 3
Build the dependencies (Go-Ethereum & Prysm)
./build-dependencies
Step 4
Run the testnet!
./testnet.sh
This setup will spin up a chain with two local nodes. You can configure the chain by modifying the script. To see how you can start executing transactions, see the github README.
If you have any issues or found this useful, find me on Twitter
Hi @REZ
Hope you are doing well !
I have separated the testnet.sh in different .sh files to monitor the execution client and consensus client logs but after running the two nodes from different droplets , both are creating a two blockchains.
Here detail overview :
Machine 1 : Running the bootnode
Machine 2: Running the execution node with machine-1 bootnode and consensus client with no bootstrap node.
Machine 3: Running the execution node with machine-1 bootnode and consensus client with bootstrap node (machine-2).
How many NUM_NODES have to enter in two different droplets if i want to run 1 one node from each droplet ?