We will set up 1 bootnode and 2 geth nodes in 3 different servers. They will form the network for the EVM chain. All the nodes will run in containers.
I created 3 droplets on digitalocean (CentOS; shared CPU; 1GB 1Core)
install and start docker
(with the compose
plugin) in all droplets
first create boot.key
mkdir /root/devnet/ && docker run -d --rm -v /root:/root ethereum/client-go:alltools-latest bootnode --genkey=/root/devnet/boot.key
then create a compose file and run docker compose up -d
:
services:
bootnode:
image: ethereum/client-go:alltools-latest
container_name: bootnode
command:
[
'bootnode',
'--nodekey=/root/devnet/boot.key',
'-addr=:30303',
'-verbosity=5',
]
ports:
- '30303:30303/udp'
restart: always
volumes:
- /root:/root
in docker compose log
, you will see a encode URL like this:
enode://<REDACTED>@127.0.0.1:0?discport=30303
replace 127.0.0.1:0
with <the public IP>:30303
and take it down some where. We will refer it as encodeURL
later.
echo 123456 > /root/devnet/password.txt
docker run -d --rm -v /root:/root ethereum/client-go:alltools-latest geth account new --password /root/devnet/password.txt
then you can find the address by ls /root/.ethereum/keystore/
you will see a file: UTC--2022-10-28…--<address>
where you can extract the address.
you can run this command in any server to create the genesis file (Note: don’t forget to export the file to /root/devnet/devnet.json
)
docker run -it --rm -v /root:/root ethereum/client-go:alltools-latest puppeth
you should provide the two addresses generated in previous step for these questions:
Which accounts are allowed to seal?
Which accounts should be pre-funded?
then modify the "nonce" field to be a random value as recommended here
last, copy the genesis file to both droplet B and C
docker run -d --rm -v /root:/root ethereum/client-go:alltools-latest geth init /root/devnet/devnet.json
then create a compose file and run docker compose up -d
:
services:
geth:
image: ethereum/client-go
container_name: geth
command:
[
'--syncmode=full',
'--bootnodes=<encodeURL>',
'--port=30303',
'--http',
'--http.addr=0.0.0.0',
'--networkid=<read from the genesis file>',
'--mine',
'--miner.threads=1',
'--miner.gasprice=1',
'--unlock=<step2 generated address>',
'--password=/root/devnet/password.txt',
'--allow-insecure-unlock',
]
ports:
- '8545:8545'
- '30303:30303'
restart: always
volumes:
- /root:/root
in the bootnode server, run docker compose log
you should see:
bootnode | TRACE[10-29|03:28:44.657] << FINDNODE/v4 id=<REDACTED> addr=<REDACTED> err=nil
bootnode | TRACE[10-29|03:28:44.657] >> NEIGHBORS/v4 id=<REDACTED> addr=<REDACTED> err=nil
in the other servers, you should see:
geth | INFO [10-29|00:32:41.507] Looking for peers peercount=1 tried=0 static=0
geth | INFO [10-29|00:32:43.326] Successfully sealed new block number=42 sealhash=<REDACTED> hash=<REDACTED> elapsed=14.483s
geth | INFO [10-29|00:32:43.326] 🔨 mined potential block number=42 hash=<REDACTED>
geth | INFO [10-29|00:32:43.327] Commit new sealing work number=43 sealhash=<REDACTED> uncles=0 txs=0 gas=0 fees=0 elapsed="269.928µs"
you can also run:
docker run -it --rm -v /root:/root ethereum/client-go:alltools-latest geth attach
> eth.blockNumber
and you will see the blockNumber
increasing.
congrats on spinning up your own EVM chain!