Ethereum in a Box takes its inspiration from the excellent article from Afri at ChainSafe, which details how to stand up a local testnet, merged since genesis. This project takes that a bit further by implementing all of the steps in shell scripts, Docker and Docker Compose files. Furthermore, we enable the Shapella hardforks from genesis.
You can use ethiab
to learn how a private Ethereum network is bootstrapped and see it go through genesis, this is the boostrap mode. You can also coordinate genesis with others, where a coordinator creates mnemonics for all participants, and participants download the config they need to participate.
The genesis.json
file is not currently setup with any allocations, and the validators have BLS withdrawal credentials at genesis, so there's no ETH to use. I haven't even tested creating a new account using Clef.
In bootstrap mode, the containers run inside a Docker bridge network (172.16.8.0/24). The P2P ports of ec2 bc2 are exposed out of the container to the host. If you set ENABLE_EXTERNAL_DISCOVERY
in the .env
(the default), the enode
of ec2 and enr
record of bc2 will be set using the externally accessible IP address. You'd then need to allow the P2P ports through firewalls and routers.
In peer mode, the containers run inside a Docker bridge network (172.16.9.0/24), the P2P ports are always exposed from the container to the host, and the enode
and enr
records are updated with the externally accessible IP address.
There is a list things of I'm intending to do, curently in this README, soon to be in the Issues tracker.
This project is about bootstrapping a private / semi-private Ethereum testnet / devnet. By definition, any Ether associated with these networks will have no value at all. With that in mind, security best practices have not necessarily been observed and nothing in this project should be referred to for configuring clients for Ethereum mainnet. We are very clearly putting mnemonics in files, transmitting them over HTTP, using the password "password" for validator keys, etc. Never do this. Let's be careful out there.
- Modern Linux shell
- Developed / tested on
Debian 11
- Should work on modern
Ubuntu
- Developed / tested on
Docker
andDocker Compose
- Tested with docker version v24.0.2, docker compose v2.8.1
- Clone this repo
- If you'll be coordinating with others, add a unique string for each participant in the list contained in
consensus/participants.yaml
. Each key would be shared with a particpant. Keep the keys simple, as they'll be used as the basis for a file for each participant, e.g.peer1
becomespeer1.yaml
. - You may want to adjust certain parameters in the .env file, like the EC and BN host ports, in case the ones in the committed .env file are already in use.
- From the
ethiab/bootstrap
repo folder, runningdocker compose up
will start the clients and countdown about five minutes to genesis, showing you the union of all container logs in the terminal (attached mode). Runningdocker compose up -d
will run all containers detached. - If you run in detached mode, to see a particular container logs, run
docker logs -f <containername>
, e.g.docker logs -f ethiab-vc
, to see the validator client logs - To pass additional parameters to the EC, BN, and VC client, edit the
.env
file values. This can be useful to increase log levels, for example.
- Clone this repo
- Edit the .env file in the
ethiab/peer
folder, be sure to set thePEER_KEY
andBOOTNODE_IP
to the values provided to you from the testnet coordinator. You may want to set the host ports as well, depending on your configuration and other network services you're running. - From the
ethiab/peer
repo folder, runningdocker compose up
will start the clients, showing you the union of all container logs in the terminal (attached mode). Runningdocker compose up -d
will run all containers detached. - If you run in detached mode, to see a particular container logs, run
docker logs -f <containername>
, e.g.docker logs -f ethiab-vc
, to see the validator client logs - To pass additional parameters to the EC, BN, and VC client, edit the
.env
file values. This can be useful to increase log levels, for example.
First, if you haven't read Afri's article linked above, you should. It does a good job of explaining how to get all the necessary pieces going to start up your own Ethereum network on your local machine. Reading through that article will make everything else make more sense.
The list of steps to get the network going is a great use case for Docker Compose, which is used to orchestrate multiple Docker containers as a group. We're having to deal with some apps that are already in Docker images, but we also need to clone and build GitHub repos to make some tools work. As detailed as the article is, there are a lot of steps, and using Compose can make it close to one-step. Here's an overview of each service:
- config: Runs a quick shell script in a
busybox
instance simply to synchronize the genesis start time between the ECgenesis.json
file and BNconfig.yaml
. Set to "now". - ec1: Initializes EC genesis and starts Geth, becomes bootnode for ec2.
- ec2: Queries
enode
record from ec1, updates the BoostrapNodes entries in toml file to use ec1 as bootnode, initializes EC genesis and starts Geth. - mnemonics: Builds and runs a custom
create-mnemonics.Dockerfile
which uses NodeJS to run acreate-menomonics.js
script, which iterates through theparticipants.yaml
file, and creates mnemonics for each one, to be used in genesis state and creating validator keys. - genesis: Builds and runs a custom
genesis.Dockerfile
which usesGo
to buildeth2-testnet-genesis
, then runs a shell script to use the tool to generate thegenesis.ssz
file for BN clients - staking-deposit: Builds and runs a custom
staking-deposit.Dockerfile
which uses apython
image, clones the Ethereumstaking-deposit-cli
, parses the mnemonic.yaml file, and calls thestaking-deposit-cli
with necessary parameters to create the validator keys. - bc1: Starts
lodestar beacon
, using ec1 as its execution client peer. This container uses a healthcheck, so bc2 waits to start until bc1 is fully up. - bc2: Queries bc1 for its
enr
record, then startslodestar beacon
, using bc1 as its bootnode. - vc: Starts
lodestar validator
, using bc1 as its BN client, loads the validator keys generated by the staking-deposit container. - p2p-info: Runs
nginx
to serve necessary informtion to peers, to be able to easily start their clients.
- get-bootstrap: Downloads the necessary configuration for the EL client, BN client, and the assigned mnemonic to create validator keys locally.
- staking-deposit: Builds and runs a custom
staking-deposit.Dockerfile
which uses apython
image, clones the Ethereumstaking-deposit-cli
, parses the mnemonic.yaml file, and calls thestaking-deposit-cli
with necessary parameters to create the validator keys. - ec: Initializes EC genesis and starts Geth.
- bc: Starts
lodestar beacon
, using ec as its execution client peer. - vc: Starts
lodestar validator
, using bc as its BN client, loads the validator keys generated by the staking-deposit container.
If you see something in this project that can be better, I'm happy to take PRs. If something doesn't work but you can't fix it, feel free to open an issue and I'll try to take a look. This is a side project for me, but I'm happy to help as I can.