Guide to Staking on Ethereum 2.0 (Ubuntu/Medalla/Prysm)

Image for post
Image for post

***
NOTE: This guide is now deprecated. Please use the newer version targeting the Pyrmont testnet.

*** located here.

  • Configure and run an Ethereum 1.0 node as a service.
  • Compile and configure the Prysmatic Labs beacon chain and validator client software for Ethereum 2.0, Phase 0 (Medalla testnet) and run them as a service.
  • Install and configure Prometheus metrics and set up a Grafana dashboard to view and alert.

WARNING

This guide is for the Medalla testnet. DO NOT, under any circumstances, send real ETH to this testnet. You will lose it.

Acknowledgements and Disclaimer

This guide is based on information I pulled together from various on-line resources and this guide wouldn’t exist without them. Thank you, all!

Prerequisites

This guide is not intended for absolute beginners. It assumes some knowledge of Ethereum, ETH, staking, Linux, and MetaMask. Before you get started you will need to have your Ubuntu server instance up and running. It will help to have the MetaMask browser extension installed and configured somewhere. The rest we will do along the way.

Note for Raspberry Pi Users

I haven’t tested this guide on a Rpi. If you want to try, just swap out the software listed below for the ARM version, where available. No guarantee it will work!

Requirements

  • Ubuntu server instance. I used v20.04 (LTS) amd64 server VM.
  • MetaMask crypto wallet browser extension, installed and configured.
  • Hardware minimum requirements to run Prysm software:
    — Operating System: 64-bit Linux
    — Processor: Intel Core i5–760 or AMD FX-8100 or better
    — Memory: 4GB RAM (8GB recommended)
    — Storage: 20GB available space SSD
    — Internet: Stable broadband connection

Overview

This is a long and detailed guide. Here’s a super-simplified diagram to help you conceptualize what we are going to do. The yellow boxes are the parts this guide mostly covers.

Image for post
Image for post
  • Configure Beacon Node and sync it with the Eth1 Node
  • Generate and activate validator keys
  • Configure the Validator Client
  • The Beacon Node makes the magic happen (blocks, attestations, slashings) with the help of the validator (signing).

***
NOTE: This guide is now deprecated. Please use the newer version targeting the Pyrmont testnet.

*** located here.

Step 0 — Connect to the Server

Using a SSH client, connect to your Ubuntu server. The root user account on Ubuntu server is normally disabled by default, however some cloud providers enable it. If you are logged in as root then let’s create a user-level account with admin privileges instead, because using the root user to log in is risky.

# adduser <yourusername>
# usermod -aG sudo <yourusername>
# rsync --archive --chown=<yourusername>:<yourusername> ~/.ssh /home/<yourusername>

Step 1 — Update Your System

Make sure your system is up to date with the latest software and security updates.

$ sudo apt update && sudo apt upgrade
$ sudo apt dist-upgrade && sudo apt autoremove

Step 2— Secure Your System

Security is important. This is not a comprehensive security guide, just some basic settings: a firewall and a user account.

Configure the firewall

Ubuntu 20.04 servers can use the default UFW firewall to restrict inbound traffic to the server. Before we enable it we need to allow inbound traffic for SSH, Go Ethereum, Grafana, and Prysm.

$ sudo ss -tulpn | grep ':<yourSSHportnumber>'
$ sudo ufw allow <yourSSHportnumber>/tcp
$ sudo nano /etc/ssh/sshd_config
Image for post
Image for post
$ sudo systemctl restart ssh
$ sudo ufw deny 22/tcp
$ sudo ufw allow 30303
$ sudo ufw allow 13000/tcp
$ sudo ufw allow 12000/udp
$ sudo ufw allow 3000/tcp
$ sudo ufw allow 9090/tcp
$ sudo ufw enable
$ sudo ufw status numbered
Image for post
Image for post

Step 3 — Configure ntpd Timekeeping (Optional)

Ubuntu has time synchronization built in and activated by default using systemd’s timesyncd service. However, for applications that require more precise timekeeping (like a blockchain) we will use ntpd.

$ sudo timedatectl set-ntp no
$ timedatectl
$ sudo apt install ntp
$ ntpq -p
Image for post
Image for post
$ ntpq -c rv
ethstaker@ETH-STAKER-001:~$ ntpq -c rv
associd=0 status=0615 leap_none, sync_ntp, 1 event, clock_sync,
version="ntpd 4.2.8p12@1.3728-o (1)", processor="x86_64",
system="Linux/5.4.0-48-generic", leap=00, stratum=2, precision=-24,
rootdelay=1.453, rootdisp=8.653, refid=209.51.161.238,
reftime=e315548b.d020811b Wed, Sep 23 2020 4:58:51.812,
clock=e31554cf.99ddcf68 Wed, Sep 23 2020 4:59:59.601, peer=5978, tc=6,
mintc=3, offset=3.040122, frequency=6.453, sys_jitter=2.164815,
clk_jitter=2.062, clk_wander=0.539, tai=37, leapsec=201701010000,
expire=202012280000

***
NOTE: This guide is now deprecated. Please use the newer version targeting the Pyrmont testnet.

*** located here.

Step 4— Install and Run Go Ethereum Node

Install and configure an Ethereum 1.0 node that your beacon-chain will connect to. If you’d rather use a node hosted by a 3rd party (Infura, etc.) then skip this step.

Install Go Ethereum

Go Ethereum recommends using PPA’s (Personal Package Archives).

$ sudo add-apt-repository -y ppa:ethereum/ethereum
$ sudo apt update
$ sudo apt install geth

Run Go Ethereum as a Background Service

Create an account for the service to run under. This type of account can’t log into the server.

$ sudo useradd --no-create-home --shell /bin/false goeth
$ sudo mkdir -p /var/lib/goethereum
$ sudo chown -R goeth:goeth /var/lib/goethereum
$ sudo nano /etc/systemd/system/geth.service
[Unit]
Description=Ethereum go client
After=network.target
Wants=network.target
[Service]
User=goeth
Group=goeth
Type=simple
Restart=always
RestartSec=5
ExecStart=geth --goerli --http --datadir /var/lib/goethereum

[Install]
WantedBy=default.target
Image for post
Image for post
$ sudo systemctl daemon-reload
$ sudo systemctl start geth
$ sudo systemctl status geth
Image for post
Image for post
$ sudo systemctl enable geth
$ sudo journalctl -f -u geth.service
$ sudo systemctl stop geth
$ sudo nano /etc/systemd/system/geth.service
ExecStart=geth --goerli --http --datadir /var/lib/goethereum --bootnodes "enode://46add44b9f13965f7b9875ac6b85f016f341012d84f975377573800a863526f4da19ae2c620ec73d11591fa9510e992ecc03ad0751f53cc02f7c7ed6d55c7291@94.237.54.114:30313,enode://119f66b04772e8d2e9d352b81a15aa49d565590bfc9a80fe732706919f8ccd00a471cf8433e398c55c4862aadb4aadf3a010201483b87e8358951698aa0b6f07@13.250.50.139:30303"
$ sudo systemctl daemon-reload
$ sudo systemctl start geth
$ sudo journalctl -f -u geth.service
Image for post
Image for post
Image for post
Image for post

Step 5— Install Bazel

Bazel is an open-source build tool. We will use it to compile the Prysm software.

$ sudo apt install curl gnupg
$ curl -fsSL https://bazel.build/bazel-release.pub.gpg | gpg --dearmor > bazel.gpg
$ sudo mv bazel.gpg /etc/apt/trusted.gpg.d/
$ echo "deb [arch=amd64] https://storage.googleapis.com/bazel-apt stable jdk1.8" | sudo tee /etc/apt/sources.list.d/bazel.list
$ sudo apt update && sudo apt install bazel
$ sudo apt update && sudo apt full-upgrade
$ sudo apt update && sudo apt install bazel-3.2.0
$ sudo apt install -y libtinfo5 # Terminal handling
$ sudo apt-get install -y libssl-dev # OpenSSL
$ sudo apt-get install -y libgmp-dev # GMP source to build BLS

***
NOTE: This guide is now deprecated. Please use the newer version targeting the Pyrmont testnet.

*** located here.

Step 6— Install and Build Prysm

The Prysm client is made up of two binaries: the beacon-chain and the validator. We will build both here.

$ git clone -b v1.0.0-beta.2 --single-branch https://github.com/prysmaticlabs/prysm.git
$ cd prysm
$ bazel build //beacon-chain:beacon-chain --config=release
$ bazel build //validator:validator --config=release

Step 7— Configure the Beacon Chain

We will run the beacon chain as a service so if the system restarts the process will automatically start back up again.

Setup Accounts and Directories

Create an account for the service to run under. This type of account can’t log into the server.

$ sudo useradd --no-create-home --shell /bin/false prysm-beaconchain
$ sudo mkdir -p /var/lib/prysm/beaconchain
$ sudo chown -R prysm-beaconchain:prysm-beaconchain /var/lib/prysm/beaconchain

Copy the Beacon Chain Binary

Next, copy the newly compiled beacon-chain binary to the /usr/local/bin directory. We will run it from there.

$ cd ~
$ sudo cp prysm/bazel-bin/beacon-chain/beacon-chain_/beacon-chain /usr/local/bin

Create and Configure the Service

Create a systemd service file to store the service config.

$ sudo nano /etc/systemd/system/prysm-beaconchain.service
[Unit]
Description=Prysm Beaconchain
Wants=network-online.target
After=network-online.target
[Service]
Type=simple
User=prysm-beaconchain
Group=prysm-beaconchain
Restart=always
RestartSec=5
Environment="ClientIP=$(curl -s v4.ident.me)"
ExecStart=/bin/bash -c '/usr/local/bin/beacon-chain --medalla --p2p-host-ip=${ClientIP} --datadir=/var/lib/prysm/beaconchain --http-web3provider=http://127.0.0.1:8545 --accept-terms-of-use'
[Install]
WantedBy=multi-user.target
Image for post
Image for post
$ sudo systemctl daemon-reload
$ sudo systemctl start prysm-beaconchain
$ sudo systemctl status prysm-beaconchain
Image for post
Image for post
$ sudo systemctl enable prysm-beaconchain
$ sudo journalctl -f -u prysm-beaconchain.service
Image for post
Image for post

***
NOTE: This guide is now deprecated. Please use the newer version targeting the Pyrmont testnet.

*** located here.

Step 8— Complete the Medalla On-boarding Process

In order to run a validator on the Eth2.0 Medalla testnet we will need to sign up for one or more validator accounts.

  • Generate the validator keys. Each key is a validator account
  • Fund the validator account(s) with 32 Göerli ETH per account
  • Wait for your validator account(s) to become active

Get Goerli ETH

  1. Go to a computer with the MetaMask browser extension installed.
  2. Click on MetaMask and log in.
  3. Using the drop-down at the top, select the Göerli Test Network.
  4. Click on the account name to copy your Göerli Test Network wallet address.
  5. Using your address, get Göerli ETH from the authenticated faucet or via the #request-goerli-eth channel on the ethstaker Discord using the bot command: !goerliEth <yourwalletaddress>.

Generate Validator Keys

Next we will generate the validator keys. The validator client supports multiple validator keys. Each validator key is basically a “validator account” on the Medalla testnet.

$ cd ~
$ git clone https://github.com/ethereum/eth2.0-deposit-cli.git
$ cd eth2.0-deposit-cli
$ python3 -V
$ sudo apt install software-properties-common
$ sudo add-apt-repository ppa:deadsnakes/ppa
$ sudo apt update
$ sudo apt install python3.7
$ sudo apt install python3-pip
$ sudo ./deposit.sh install
$ ./deposit.sh new-mnemonic --num_validators <numberofvalidators> --mnemonic_language=english --chain medalla
Success!
Your keys can be found at: /home/<yourusername>/eth2.0-deposit-cli/validator_keys

Copy Deposit Data File

In the validator_keys directory there will be a deposit_data-[timestamp].json file. You will need to upload this via a website in the next step. Since we are on a server we don’t have a web browser so secure FTP (SFTP) the file to a desktop computer that does.

Fund the Validator Keys

This step involves depositing the required amount of Göerli ETH to the Medalla testnet staking contract. This is done on the Eth2.0 Lauchpad website.

Image for post
Image for post
Image for post
Image for post
Image for post
Image for post
Image for post
Image for post
Image for post
Image for post
Image for post
Image for post
Image for post
Image for post

Check the Status of Your Validators

Newly added validators can take a while (hours to days) to activate. You can check the status of your keys with these steps:

  1. Go here: https://medalla.beaconcha.in/
  2. Search your wallet address. Your keys will be shown.
Image for post
Image for post

Step 9— Create the Validator Wallet

First create a directory to store the validator wallet and give the current user permissions to access it. Change <yourusername> to your logged in username.

$ sudo mkdir -p /var/lib/prysm/validator
$ sudo chown -R <yourusername>:<yourusername> /var/lib/prysm/validator
$ cd prysm
$ bazel run //validator:validator -- accounts import --keys-dir=$HOME/eth2.0-deposit-cli/validator_keys --accept-terms-of-use --medalla
Enter a wallet directory (default: /home/ethstaker/.eth2validators/prysm-wallet-v2):
/var/lib/prysm/validator
[2020-10-21 07:02:15]  WARN flags: Running on Medalla Testnet
Enter a wallet directory (default: /home/ethstaker/.eth2validators/prysm-wallet-v2):
/var/lib/prysm/validator
New wallet password:
Confirm password:
[2020-10-21 07:02:37] INFO accounts: Successfully created new wallet wallet-path=/var/lib/prysm/validator
Enter the password for your imported accounts:
Importing accounts, this may take a while...
Importing accounts... 100% [=========================================] [36s:0s]
Successfully imported 40 accounts, view all of them by running accounts list
$ bazel run //validator:validator -- accounts list --medalla --wallet-dir /var/lib/prysm/validator --accept-terms-of-use
$ touch /var/lib/prysm/validator/password.txt
$ sudo nano /var/lib/prysm/validator/password.txt
Image for post
Image for post
$ sudo chmod go-rw /var/lib/prysm/validator/password.txt

***
NOTE: This guide is now deprecated. Please use the newer version targeting the Pyrmont testnet.

*** located here.

Step 10— Configure the Validator

Setup Accounts and Directories

We will run the validator as a service so if the system restarts the process will automatically start back up again.

$ sudo useradd --no-create-home --shell /bin/false prysm-validator
$ sudo chown -R prysm-validator:prysm-validator /var/lib/prysm/validator
$ cd ~
$ sudo cp prysm/bazel-bin/validator/validator_/validator /usr/local/bin

Create and Configure the Service

Create a systemd service file to store the service config.

$ sudo nano /etc/systemd/system/prysm-validator.service
[Unit]
Description=Validator
Wants=network-online.target
After=network-online.target
[Service]
Type=simple
User=prysm-validator
Group=prysm-validator
Restart=always
RestartSec=5
ExecStart=/usr/local/bin/validator --medalla --datadir /var/lib/prysm/validator --wallet-dir /var/lib/prysm/validator --wallet-password-file /var/lib/prysm/validator/password.txt --graffiti "<POAPString>" --accept-terms-of-use
[Install]
WantedBy=multi-user.target
Image for post
Image for post
$ sudo systemctl daemon-reload
$ sudo systemctl start prysm-validator
$ sudo systemctl status prysm-validator
Image for post
Image for post
$ sudo systemctl enable prysm-validator
$ sudo journalctl -f -u prysm-validator.service
Oct 21 07:12:24 ETH-STAKER-001 validator[86456]: time="2020-10-21 07:12:24" level=info msg="Waiting for beacon node to sync to latest chain head" prefix=validator

***
NOTE: This guide is now deprecated. Please use the newer version targeting the Pyrmont testnet.

*** located here.

Step 11 — Install Prometheus

Prometheus is an open-source systems monitoring and alerting toolkit. It runs as a service on your Ubuntu server and its job is to capture metrics. More information here.

Create User Accounts

Accounts for the services to run under. These accounts can’t log into the server.

$ sudo useradd --no-create-home --shell /bin/false prometheus
$ sudo useradd --no-create-home --shell /bin/false node_exporter

Create Directories

Program and data directories.

$ sudo mkdir /etc/prometheus
$ sudo mkdir /var/lib/prometheus
$ sudo chown -R prometheus:prometheus /etc/prometheus
$ sudo chown -R prometheus:prometheus /var/lib/prometheus

Download Prometheus software

Adjust the version number to the latest version from the Prometheus download page. Rpi users be sure to get the ARM binary.

$ cd ~
$ curl -LO https://github.com/prometheus/prometheus/releases/download/v2.22.0/prometheus-2.22.0.linux-amd64.tar.gz
$ tar xvf prometheus-2.22.0.linux-amd64.tar.gz
$ sudo cp prometheus-2.22.0.linux-amd64/prometheus /usr/local/bin/
$ sudo cp prometheus-2.22.0.linux-amd64/promtool /usr/local/bin/
$ sudo chown -R prometheus:prometheus /usr/local/bin/prometheus
$ sudo chown -R prometheus:prometheus /usr/local/bin/promtool
$ sudo cp -r prometheus-2.22.0.linux-amd64/consoles /etc/prometheus
$ sudo cp -r prometheus-2.22.0.linux-amd64/console_libraries /etc/prometheus
$ sudo chown -R prometheus:prometheus /etc/prometheus/consoles
$ sudo chown -R prometheus:prometheus /etc/prometheus/console_libraries
$ rm -rf prometheus-2.22.0.linux-amd64.tar.gz prometheus-2.22.0.linux-amd64

Edit the Configuration File

Prometheus uses a configuration file so it knows where to scrape the data from. We will set this up here.

$ sudo nano /etc/prometheus/prometheus.yml
global:
scrape_interval: 15s # Set the scrape interval to every 15 seconds. Default is every 1 minute.
evaluation_interval: 15s # Evaluate rules every 15 seconds. The default is every 1 minute.
# scrape_timeout is set to the global default (10s).
# Alertmanager configuration
alerting:
alertmanagers:
- static_configs:
- targets:
# - alertmanager:9093
# Load rules once and periodically evaluate them according to the global 'evaluation_interval'.
rule_files:
# - "first_rules.yml"
# - "second_rules.yml"
# A scrape configuration containing exactly one endpoint to scrape:
# Here it's Prometheus itself.
scrape_configs:
- job_name: 'validator'
static_configs:
- targets: ['localhost:8081']
- job_name: 'beacon node'
static_configs:
- targets: ['localhost:8080']
- job_name: 'node_exporter'
static_configs:
- targets: ['localhost:9100']
$ sudo chown -R prometheus:prometheus /etc/prometheus/prometheus.yml
$ sudo -u prometheus /usr/local/bin/prometheus \
--config.file /etc/prometheus/prometheus.yml \
--storage.tsdb.path /var/lib/prometheus/ \
--web.console.templates=/etc/prometheus/consoles \
--web.console.libraries=/etc/prometheus/console_libraries
level=info ts=2020-10-21T07:18:00.434Z caller=main.go:684 msg="Server is ready to receive web requests."

Set Prometheus to Auto-Start as a Service

Create a systemd service file to store the service config which tells systemd to run Prometheus as the prometheus user, with the configuration file located in the /etc/prometheus/prometheus.yml directory, and to store its data in the /var/lib/prometheus directory.

$ sudo nano /etc/systemd/system/prometheus.service
[Unit]
Description=Prometheus
Wants=network-online.target
After=network-online.target
[Service]
Type=simple
User=prometheus
Group=prometheus
Restart=always
RestartSec=5
ExecStart=/usr/local/bin/prometheus \
--config.file /etc/prometheus/prometheus.yml \
--storage.tsdb.path /var/lib/prometheus/ \
--web.console.templates=/etc/prometheus/consoles \
--web.console.libraries=/etc/prometheus/console_libraries
[Install]
WantedBy=multi-user.target
$ sudo systemctl daemon-reload
$ sudo systemctl start prometheus
$ sudo systemctl status prometheus
Image for post
Image for post
$ sudo systemctl enable prometheus

Step 12 — Install Node Exporter

Prometheus will provide metrics about the beacon chain and validators. If we want metrics about our Ubuntu instance, we’ll need an extension called Node_Exporter. You can find the latest stable version here if you want to specify a different version below. Rpi users remember to get the ARM binary.

$ cd ~
$ curl -LO https://github.com/prometheus/node_exporter/releases/download/v1.0.1/node_exporter-1.0.1.linux-amd64.tar.gz
$ tar xvf node_exporter-1.0.1.linux-amd64.tar.gz
$ sudo cp node_exporter-1.0.1.linux-amd64/node_exporter /usr/local/bin
$ sudo chown -R node_exporter:node_exporter /usr/local/bin/node_exporter
$ rm -rf node_exporter-1.0.1.linux-amd64.tar.gz node_exporter-1.0.1.linux-amd64

Set Node Exporter to Auto-Start as a Service

Create a systemd service file to store the service config which tells systemd to run Node_Exporter as the node_exporter user.

$ sudo nano /etc/systemd/system/node_exporter.service
[Unit]
Description=Node Exporter
Wants=network-online.target
After=network-online.target
[Service]
User=node_exporter
Group=node_exporter
Type=simple
ExecStart=/usr/local/bin/node_exporter
[Install]
WantedBy=multi-user.target
$ sudo systemctl daemon-reload
$ sudo systemctl start node_exporter
$ sudo systemctl status node_exporter
Image for post
Image for post
$ sudo systemctl enable node_exporter

Test Prometheus and Node Exporter

Everything should be ready to go. You may optionally test the functionality by opening a port in the firewall (see Step 2) and browsing to http://<yourserverip>:9090. From there you can run queries to view different metrics. For example try this query to see how much memory is free in bytes:

http://<yourserverip>:9090/new/graph?g0.expr=node_memory_MemFree_bytes&g0.tab=1&g0.stacked=0&g0.range_input=1h
http://<yourserverip>:9090/graph?g0.range_input=1h&g0.expr=validator_balance&g0.tab=1

Step 13 — Install Grafana

While Prometheus is our data source, Grafana is going provide our reporting dashboard capability. Let’s install it and configure a dashboard.

$ wget -q -O - https://packages.grafana.com/gpg.key | sudo apt-key add -
$ sudo add-apt-repository "deb https://packages.grafana.com/oss/deb stable main"
$ sudo apt update
$ apt-cache policy grafana
grafana:
Installed: (none)
Candidate: 7.2.1
Version table:
7.2.1 500
500 https://packages.grafana.com/oss/deb stable/main amd64 Packages
7.2.0 500
500 https://packages.grafana.com/oss/deb stable/main amd64 Packages
7.1.5 500
500 https://packages.grafana.com/oss/deb stable/main amd64
...
$ sudo apt install grafana
$ sudo systemctl start grafana-server
$ sudo systemctl status grafana-server
Image for post
Image for post
$ sudo systemctl enable grafana-server

Configure Grafana Login

Great job on getting this far! Now that you have everything up and running you can go to http://<yourserverip>:3000/ in a browser and the Grafana login screen should come up.

Configure the Grafana Data Source

Let’s configure a datasource. Move your mouse over the gear icon on the left menu bar. A menu will pop-up — choose Data Sources.

Add data source screen.
Add data source screen.
Data source configuration.
Data source configuration.
Data source is confirmed working.
Data source is confirmed working.

Import a Grafana Dashboard

Now let’s import a dashboard. Move your mouse over the + icon on the left menu bar. A menu will pop-up - choose Import.

Ethereum staking dashboard in Grafana.
Ethereum staking dashboard in Grafana.

***
NOTE: This guide is now deprecated. Please use the newer version targeting the Pyrmont testnet.

*** located here.

Final Remarks

Okay… That’s it! We are done! I hope you enjoyed this guide.

  • If you have feedback you can reach me on Twitter or Reddit.
  • If you liked this guide and think others would benefit from it then please share it using the friends link!
  • Tips appreciated: somer.eth

Passionate about Ethereum and decentralized technology.

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store