I'll have a go at answering this by producing a response that has a different structure to the question but should tick-off all the necessary points along the way. Hopefully I didn't miss any.
Background: I am a lead developer on Lighthouse, one of the eth2 clients that will launch at genesis. I have built most of the Lighthouse testnet tooling and launched each of the Lighthouse testnets.
What is required to start a beacon chain?
There are three main values required to start a beacon chain (listed below). The eth2-testnets repo contains a set of somewhat-standardised directories that contain these values.
1. DEPOSIT_CONTRACT_ADDRESS
The address of a "deposit contract" on the eth1 chain.
For beacon mainnet, this will be a contract that the Ethereum Foundation (EF) have deployed on eth1 mainnet in some public ceremony.
For current beacon testnets, it's generally a contract that one of the developers have deployed on Goerli without any significant ceremony.
2. config.yaml
This is a file that defines all the "constants" in the eth2 spec. It includes basic things such as the minimum number of validators
required to trigger genesis and how many seconds there are per slot.
For beacon testnets, it's common to reduce MAX_EFFECTIVE_BALANCE
by a factor of 10
so that only 3.2 ETH is required to deposit (instead of 32 ETH, which is more difficult to obtain for Goerli). Also, MIN_GENESIS_ACTIVE_VALIDATOR_COUNT
is modified to determine how many deposits are required to bootstrap the beacon chain.
Examples:
3. Boot Nodes
This is a list of IP addresses and libp2p identities of some running nodes that can be used to seed the p2p network (same concept as in eth1).
In our testnets, we have four nodes that are dedicated to being boot nodes. We have some static, well-known IP addresses that we use for
this purpose.
Ceremony: What does it entail?
When it comes to ceremony that the users participate in, it comes in two stages:
- Deploying the deposit contract
- Validators making deposits to the deposit contract.
The ceremony around 1 is about gaining a social consensus that (a) the "right" deposit contract code was deployed and (b) the address of that contract is well known. With regards to who can participate, only one entity can really deploy the contract, but anyone can verify it. A very simple example would be that Vitalik Buterin deploys the contract and posts the address on his website, then Bokky tweets that he agrees that Vitalik's address has the right bytecode.
Since step (2) is conducted on the eth1 block chain, its behavior is well-defined by the deposit contract code and we can use our existing trust in eth1 to produce an ordered list of validators. Anyone with MIN_DEPOSIT_AMOUNT
(1 ETH) can participate and become a validator.
You'll notice that the ceremony I've mentioned only determines DEPOSIT_CONTRACT_ADDRESS
but fails to find config.yaml
or the boot nodes. I think that social consensus on the config.yaml
is a long-term thing that's decided over months of back-and-forth instead of in a "ceremony". Regarding the boot nodes, I think they will just be chosen by client developers and overridden by anyone who disagrees. Clients teams have an incentive to use good bootnodes and it's not really important that all users agree on the same boot nodes.
Ceremony: How to start it?
First, you need to agree upon a config.yaml
. For a testnet, you are probably concerned with choosing two things:
MIN_GENESIS_ACTIVE_VALIDATOR_COUNT
: how many validators need to deposit successfully on the eth1 chain before the beacon chain starts?
MAX_EFFECTIVE_BALANCE
(+ others): how much do validators need to deposit in order to become an eth2 validator (mainnet sets this to 32 ETH, most testnets use 3.2 ETH).
Then, you need to deploy your deposit contract on eth1 (testnets generally use Goerli). The source code for this contract is defined here. If you're using mainnet specifications (e.g., 32 eth deposits) then you can just deploy that as-is. However, if you're using a testnet you probably want to alter it to (a) allow for a different deposit amount and (b) perhaps add a centralized method for "stealing back" all the eth once you're finished with the testnet. For Lighthouse testnets we use the contract code at sigp/unsafe-eth2-deposit-contract.
Once you've finished the deployment ceremony/process, eth1 accounts can begin depositing and committing to being a validator. Users can begin starting up their beacon nodes (Nimbus, Lighthouse, Prysm, etc.) which will start watching the eth1 chain. The deposit ceremony is underway.
Deposit Ceremony: How to conclude it?
As soon as the deposit contract is deployed, beacon nodes can start "watching" the eth1 chain by connecting to an eth1 node (e.g., parity-ethereum, geth, etc) and reading the logs from the deposit contract.
Beacon nodes will, automatically and without user input, watch the contract until MIN_GENESIS_ACTIVE_VALIDATOR_COUNT
is reached (or exceeded). Once this happens, the nodes will wait 1-2 days (MIN_GENESIS_DELAY
) until UTC midnight and then the beacon chain will produce its first block. Yay!
At this point, eth2 is now running and additional post-genesis validators can deposit the same was as before (using the deposit contract).