The nim-beacon-chain book

Documentation for Nimbus beacon chain users and developers.

The Nimbus beacon chain is a research implementation of the Beacon Chain – the core system level chain at the heart of Ethereum 2.0.


In this book, we will cover:

  1. An introduction to the beacon chain and Nimbus to equip you with some basic knowledge.
  2. Installation steps outlining the prerequisites to get started.
  3. Become a Medalla validator: If you generated your signing key using the eth2 launchpad, and wish to import it into the Nimbus client, this page is for you.
  4. How to run the beacon node software to sync the beacon chain.
  5. How to generate keys, deposit, and become a validator in eth2.
  6. The API for monitoring your node through http.
  7. Advanced usage for developers.
  8. Common questions and answers to satisfy your curiosity.
  9. How to contribute to this book.

Feel free to give us feedback on how to improve :)

Get in touch

Need help with anything? Join us using Status or Discord!


This documentation assumes Nimbus is in its ideal state. The project is still under active development. Please submit a Github issue if you come across a problem.


The Beacon chain can run on Linux, macOS, Windows, and Android. At the moment, Nimbus has to be built from source.


The beacon chain relies on your computer having the correct time set, down to at most 0.5 seconds.

We recommended you run a high quality time service on your computer such as:

  • GPS
  • NTS (network time security, IETF draft)
  • Roughtime (google)

As a minimum, you should run an NTP client on the server.

If that makes no sense to you, don't worry. For testnets, just making sure your computer is set at the correct time should be fine.

External Dependencies

  • Developer tools (C compiler, Make, Bash, Git)
  • PCRE

Nim is not an external dependency, Nimbus will build its own local copy.


On common Linux distributions the dependencies can be installed with:

# Debian and Ubuntu
sudo apt-get install build-essential git libpcre3-dev

# Fedora
dnf install @development-tools pcre

# Archlinux, using an AUR manager for pcre-static
yourAURmanager -S base-devel pcre-static


Assuming you use Homebrew to manage packages

brew install pcre cmake


You can install the developer tools by following the instruction in our Windows dev environment section. It also provides a downloading script for prebuilt PCRE.


  • Install the Termux app from FDroid or the Google Play store
  • Install a PRoot of your choice following the instructions for your preferred distribution. Note, the Ubuntu PRoot is known to contain all Nimbus prerequisites compiled on Arm64 architecture (common architecture for Android devices).

Assuming Ubuntu PRoot is used

apt install build-essential git libpcre3-dev

Next steps

Once you've installed the prerequisites, you're ready to move on to running a validator on Medalla.

Become a Medalla validator

This page will take you through how to become a validator on the eth2 testnet Medalla.

If you generated your signing key using the eth2 launchpad, and wish to import it into the Nimbus client, this page is for you.

If you haven't created your validator key yet, we recommend you go through the launchpad first. If you're not sure what the eth2 launchpad is, we recommend reading this introductory post.


If this is your first time playing with Nimbus, make sure you install our external dependencies first.

This tutorial assumes basic knowledge of the command line.


To start validating on the medalla network:

1. Clone the nim beacon chain repository

git clone
cd nim-beacon-chain
git checkout devel

2. Build the beacon node

make beacon_node

Patience... this may take a few minutes.

3. Import keystore(s)

build/beacon_node deposits import  --data-dir=build/data/shared_medalla_0 <YOUR VALIDATOR KEYS DIRECTORY>

Replacing <YOUR VALIDATOR KEYS DIRECTORY> with the full pathname of your validator_keys directory.

Tip: run pwd in your validator_keys directory to print the full pathname to the console.

You'll be asked to enter the password you created to encrypt your keystore(s) in the Generate Keys section of the Launchpad process. Don't worry, this is entirely normal. Your validator client needs both your keystore(s) and the password encrypting it to import your keys (since it needs to decrypt the keystore in order to be able to use it to sign on your behalf).

4. Connect to Medalla

make medalla

This will build Nimbus and its dependencies, and connect you to Medalla. You should see that the beacon node has launched with your validator attached and is waiting for genesis to start:

WRN 2020-08-03 16:24:17.950+02:00 Validator not in registry (yet?)           topics="beacval" tid=11677993 file=validator_duties.nim:53 pubKey=a9c4df36
INF 2020-08-03 16:24:17.951+02:00 Local validator attached                   tid=11677993 file=validator_pool.nim:21 pubKey=a9c4df36 validator=a9c4df36
INF 2020-08-03 16:24:17.951+02:00 Local validators attached                  topics="beacval" tid=11677993 file=validator_duties.nim:61 count=1
INF 2020-08-03 16:24:17.958+02:00 Starting beacon node                       topics="beacnde" tid=11677993 file=beacon_node.nim:875 version="0.5.0 (31b33907)" nim="Nim Compiler Version 1.2.6 [MacOSX: amd64] (bf320ed1)" timeSinceFinalization=81350 head=ebe49843:0 finalizedHead=ebe49843:0 SLOTS_PER_EPOCH=32 SECONDS_PER_SLOT=12 SPEC_VERSION=0.12.2 dataDir=build/data/shared_medalla_0 pcs=start_beacon_node
NOT 2020-08-03 16:24:17.958+02:00 Waiting for genesis                        topics="beacnde" tid=11677993 file=beacon_node.nim:890 genesisIn=22h35m50s0ns
Tips on how to graffiti and run multiple clients

To draw on the graffitwall, pass the graffiti parameter like this:

make NODE_PARAMS="--graffiti='<YOUR_GRAFFITI>'" medalla

If you are running another client, you may need to use a different port. To change port, run:


5. Keep an eye on your validator

If you deposited after the genesis state was decided (August 2nd 1300 UTC), your validators will have been put in a queue based on deposit time, and will slowly be inducted into the validator set after genesis. Getting through the queue may take a few hours or days.

The best way to keep track of your validator's status is (click on the orange magnifying glass at the very top and paste in its public key).

You can even create an account to add alerts and keep track it its performance.

6. Keep your validator updated

Finally, makes sure you stay on the lookout for any critical updates to Nimbus. This best way to do so is through the medalla-announcements channel on our discord.

To update to the latest version, disconnect from medalla and run:

git pull && make update

Once the update is complete, run make medalla to reconnect to the network.

Looking forward to seeing you on Medalla! 💛

A note on keys

The Nimbus client will only ever import your signing key -- in any case, if you used the deposit launchpad, this is the only key you should have (you can generate the withdrawal key from your mnemonic when you wish to withdraw). The keys your Nimbus client has access to are stored in the build/data/shared_medalla_0/ folder, under secrets and validators.

The secrets folder contains the common secret that gives you access to all your validator keys. And the validators folder contains your keystores.

For more on keys in eth2, see here.

The beacon node

The beacon node application connects to the eth2 network, manages the blockchain, and provides API's to interact with the beacon chain.

You can run the beacon node without being a validator - doing so allows you to sync the network and access its latest state.


Before compiling and running the application, make sure you've gone through the installation guidelines.

Running the node

When running the beacon node, you connect to a specific ethereum 2 network - this may be a private network or a public testnet like Medalla.

When running the node for the first time, you need to specify network parameters, boot nodes and genesis information. This information can typically be found in the eth2 testnets repository. This information is automatically downloaded when using the simplified startup.

Once the beacon node is running, it will first connect to the boot nodes in the network, look for more peers and start syncing the chain. Once the sync is complete, it will keep following the head of the chain (you can interact with it through the API.

Before running the beacon node, it's important that your computer is set to the correct time - preferably using a trusted time source (this can be an NTP server you trust, GPS time or another precise source of time) -- however don't worry if you're unsure of how to do this, it isn't essential for testnet purposes.


To start syncing the medalla network:

1. Clone the nim beacon chain repository

git clone
cd nim-beacon-chain

2. Run the build process

make medalla

# Build output...

This will build Nimbus and its dependencies, and connect you to Medalla. You should see that the beacon node has launched and started syncing.

INF 2020-07-03 15:28:15+02:00 Starting beacon node                       topics="beacnde" tid=176865 file=beacon_node.nim:866 SECONDS_PER_SLOT=12 SLOTS_PER_EPOCH=32 SPEC_VERSION=0.12.1 cat=init dataDir=/home/arnetheduck/status/nim-beacon-chain/build/data/shared_medalla_0 finalizedRoot=72e7b21c finalizedSlot=20064 headRoot=f92bf720 headSlot=20142 nim="Nim Compiler Version 1.2.2 [Linux: amd64] (be34b5ab)" pcs=start_beacon_node timeSinceFinalization=-108322 version="0.5.0 (c64737e)"

 peers: 7 ❯ finalized: 3a806c9f:634 ❯ head: b364f8e9:636:29 ❯ time: 909:7 (29095)              ETH: 0.0

Status bar

The status bar shows important health information about your node:

  • peers - The number of peers you're connected to
  • finalized - The block root and epoch of the latest finalized checkpoint - when the network is healthy, this value will stay at 2-3 epochs from the wall clock
  • head - The block root and time of the head block - as blocks are produced and processed, this will be updated to the latest head block as chosen by the consensus algorithm.
  • time - The current wall time according to your computer - when the node is synced, the head block will closely follow this time.
  • ETH: the total ETH validators attached to the node have accumulated. When there are no validators attached, this number will be 0.

Time is shown as epoch:subslot, starting from the block chain genesis time - one epoch is typically 32 slots but this may vary between networks.

The status bar content may be updated using command line flags.


Nimbus includes metrics support using the Prometheus format. To enable it, you need to enable insecure feature when compiling the application. The http server that exports Prometheus metrics should not be exposed to external parties.

# Compile with insecure features enabled
make NIMFLAGS="-d:insecure" medalla

Command line options

$ ./beacon_node --help
Nimbus beacon node v0.3.0 (877a358)


beacon_node [OPTIONS]... command

The following options are available:

     --log-level               Sets the log level.
     --eth1-network            The Eth1 network tracked by the beacon node.
 -d, --data-dir                The directory where nimbus will store all blockchain data.
     --web3-url                URL of the Web3 server to observe Eth1.
     --deposit-contract        Address of the deposit contract.
     --deposit-contract-block  The Eth1 block hash where the deposit contract has been deployed.
     --non-interactive         Do not display interative prompts. Quit on missing configuration.
 -b, --bootstrap-node          Specifies one or more bootstrap nodes to use when connecting to the network.
     --bootstrap-file          Specifies a line-delimited file of bootstrap Ethereum network addresses.
     --listen-address          Listening address for the Ethereum LibP2P traffic.
     --tcp-port                Listening TCP port for Ethereum LibP2P traffic.
     --udp-port                Listening UDP port for node discovery.
     --max-peers               The maximum number of peers to connect to.
     --nat                     Specify method to use for determining public address. Must be one of: any, none,
                               upnp, pmp, extip:<IP>.
 -v, --validator               Path to a validator keystore.
     --validators-dir          A directory containing validator keystores.
     --secrets-dir             A directory containing validator keystore passwords.
     --wallets-dir             A directory containing wallet files.
 -s, --state-snapshot          Json file specifying a recent state snapshot.
     --node-name               A name for this node that will appear in the logs. If you set this to 'auto', a
                               persistent automatically generated ID will be selected for each --data-dir
     --verify-finalization     Specify whether to verify finalization occurs on schedule, for testing.
     --stop-at-epoch           A positive epoch selects the epoch at which to stop.
     --metrics                 Enable the metrics server.
     --metrics-address         Listening address of the metrics server.
     --metrics-port            Listening HTTP port of the metrics server.
     --status-bar              Display a status bar at the bottom of the terminal screen.
     --status-bar-contents     Textual template for the contents of the status bar.
     --rpc                     Enable the JSON-RPC server.
     --rpc-port                HTTP port for the JSON-RPC service.
     --rpc-address             Listening address of the RPC server.
     --dump                    Write SSZ dumps of blocks, attestations and states to data dir.

Available sub-commands:

beacon_node_shared_medalla_0 createTestnet [OPTIONS]...

The following options are available:

     --validators-dir          Directory containing validator keystores.
     --total-validators        The number of validator deposits in the newly created chain.
     --first-validator         Index of first validator to add to validator list.
     --last-user-validator     The last validator index that will free for taking from a testnet participant.
     --bootstrap-address       The public IP address that will be advertised as a bootstrap node for the
     --bootstrap-port          The TCP/UDP port that will be used by the bootstrap node.
     --genesis-offset          Seconds from now to add to genesis time.
     --output-genesis          Output file where to write the initial state snapshot.
     --with-genesis-root       Include a genesis root in 'network.json'.
     --output-bootstrap-file   Output file with list of bootstrap nodes for the network.

beacon_node_shared_medalla_0 deposits [OPTIONS]... command

The following options are available:

     --deposit-private-key     Private key of the controlling (sending) account.

Available sub-commands:

beacon_node_shared_medalla_0 deposits create [OPTIONS]...

Creates validator keystores and deposits.

The following options are available:

     --count                   Number of deposits to generate.
     --wallet                  An existing wallet ID. If not specified, a new wallet will be created.
     --out-validatorss-dir     Output folder for validator keystores and deposits.
     --out-secrets-dir         Output folder for randomly generated keystore passphrases.
     --dont-send               By default, all created deposits are also immediately sent to the validator
                               deposit contract. You can use this option to prevent this behavior. Use the
                               `deposits send` command to send the deposit transactions at your convenience

beacon_node_shared_medalla_0 deposits send [OPTIONS]...

Sends prepared deposits to the validator deposit contract.

The following options are available:

     --validators-dir          A folder with validator metadata created by the `deposits create` command.
     --min-delay               Minimum possible delay between making two deposits (in seconds).
     --max-delay               Maximum possible delay between making two deposits (in seconds).

beacon_node_shared_medalla_0 deposits status

Displays status information about all deposits.

beacon_node_shared_medalla_0 wallets command

Available sub-commands:

beacon_node_shared_medalla_0 wallets create [OPTIONS]...

Creates a new EIP-2386 wallet.

The following options are available:

     --name                    An easy-to-remember name for the wallet of your choice.
     --next-account            Initial value for the 'nextaccount' property of the wallet.
     --out                     Output wallet file.

beacon_node_shared_medalla_0 wallets restore [OPTIONS]...

Restores a wallet from cold storage.

The following options are available:

     --name                    An easy-to-remember name for the wallet of your choice.
     --deposits                Expected number of deposits to recover. If not specified, Nimbus will try to
                               guess the number by inspecting the latest beacon state.
     --out                     Output wallet file.

beacon_node_shared_medalla_0 wallets list

Lists details about all wallets.

Next steps

Once you're synced, you can move on to become a validator.

Become a Validator

Note, the instructions below currently apply to Altona. They will be updated shortly to explain how you can use Nimbus to create your validator keys and interact with the Medalla deposit contract.

To become a validator on Medalla using the eth2 launchpad, see here.

To become a validator, you need to install the beacon chain software, acquire 32 ETH, set up your validator account, and register with the deposit contract on ethereum. There is currently no eth2 mainnet - all networks are testnets.

Recommended Testnets

Though Nimbus can connect to any of the testnets published in the eth2-clients/eth2-testnets repo, below are the recommended ones:

  • Multi-client Testnet: altona (explorer)
  • Nimbus Testnet: testnet0 (experimental, not always active)


Initial setup

Before we start, we have to obtain 32 ETH on the Goerli testnet (later on, we'll need to send this ETH to the deposit contract in order to become a validator).

  1. Open your MetaMask wallet, switch to the Goerli Test Network option from the top right corner.
  2. Copy your account address by clicking on one of your accounts.
  3. Post your account address on a social media platform (Twitter or Facebook). Copy the url to the post.
  4. Paste your post url on the Goerli faucet and select Give me Ether > 37.5 Ethers from the top right corner of the page.
  5. Wait for a few seconds and return to your MetaMask wallet to check if you have successfully received the ETH.
  6. Once the prerequisites are installed, you can connect to the altona testnet with the following commands:
  • Remember to replace make with mingw32-make if using Windows.
git clone
cd nim-beacon-chain
git checkout devel
git pull
make update
make altona        # This will build Nimbus and all other dependencies
                   # and connect you to altona

Once Nimbus has finished building, you will be prompted to enter the private key of the account you want to deposit the 32 ETH from.

  1. Copy your private key from MetaMask (click on the three dots in the top right, followed by Account Details and Export Private Key).
  1. Paste your private key into the console.
  1. Press enter and wait for a few seconds until you see Deposit sent.
INF 2020-07-05 12:58:25+02:00 Generating deposits ... validatorsDir=/Users/sssaintleger/nim-beacon-chain/build/data/shared_altona_0/validators ...
INF 2020-07-05 12:58:25+02:00 Sending deposits ... DepositContract=0x16e82D77882A663454Ef92806b7DeCa1D394810f ...
INF 2020-07-05 12:58:26+02:00 Deposit sent ... status=0x5455b1faf773a535668bdd4ade6b03f6cfd52f88414a5ad74bbdfdfd89f28b86

Deposit sent, wait for confirmation then press enter to continue
  1. Check the status of your deposit by copying and pasting the transaction hash into (where the transacton hash is the text displayed after status= in your console). For example, in the output displayed after step 9, we have status=0x5455... so the transaction hash is 0x5455.... If you see a green Success box (see the image below) you can go ahead and press enter to continue.

Note: it should take approximately 8 hours for your deposit to be processed by the beacon chain. To keep track of the status of your validator you should go to[Validator PubKey], replacing [Validator PubKey] with your actual Validator PubKey -- you can find this in the etherscan transaction details (for example, in the image above the Validator PubKey is 0x95aa...).

And voila! That's all there is to it :)

The beacon chain client will start syncing the network while your deposit is being processed. As soon as it has synced, and your validator has been confirmed as active, the client will start performing validation duties.

P.S. at the bottom of the console, you should see something like:

peers: 18 > finalized: 710631d5:283 > head: 98204d1:285:10 > time: 1405:2 (44982)
ETH: 0

You can get a brief estimate of the time remaining until you've synced to the network by comparing head with time (time gives the current epoch, whereas head tells you how many epochs you've synced so far). From the above output, we see that the number of epochs synced so far is 285, and the current epoch is 1405.


When you restart the beacon node, the software will resume from where it left off, using your previous deposits.

cd nim-beacon-chain
git pull
make update # Update dependencies
make altona # Restart using same keys as last run

Key management

Keys are stored in the build/data/[testnet_name]/ folder, under secrets and validators - make sure you keep these folders backed up.

The secrets folder contains the common secret that gives you access to all your validator keys.

The validators folder contains your keystores. Keystores are used by validators as a method for exchanging keys.

For more on keys in eth2, see here.


Metrics are not included in the binary by default - to enable them, use the following options when starting the client:

make NIMFLAGS="-d:insecure" altona

You can then browse the metrics by connecting to:


Make sure this port is protected as the http server used is not considered secure (it should not be used by untrusted peers).


  1. The directory that stores the blockchain data of the testnet is build/data/shared_altona_0 (if you're connecting to another testnet, replace altona with that testnet's name). Delete this folder if you want to start over (for example, if you entered a wrong private key).

  2. Currently, you have to switch to the devel branch in order to run the validator node successfully.

  3. Everytime you want to update your node to the latest version, run git pull, make update, and then make altona.

  4. If make update causes the console to hang for too long, try running make update V=1 or make update V=2 instead (these will print a more verbose output to the console which may make it easier to diagnose the problem).

NBC exposes API:s for querying the state of the application at runtime.

:note: Where applicable, this API mimics with the exception that JSON-RPC is used instead of http rest - method names, parameters and results are equivalent except for the encoding / access method.


The NBC API is implemented using JSON-RPC 2.0. To query it, you can use a JSON-RPC library in the language of your choice, or a tool like curl to access it from the command line. A tool like jq is helpful to pretty-print the responses.

curl -d '{"jsonrpc":"2.0","id":"id","method":"peers","params":[] }' -H 'Content-Type: application/json' localhost:9190 -s | jq

Before you can access the API, make sure it's enabled using the RPC flag (beacon_node --rpc):

     --rpc                     Enable the JSON-RPC server.
     --rpc-port                HTTP port for the JSON-RPC service.
     --rpc-address             Listening address of the RPC server.

One difference is that currently endpoints that correspond to specific ones from the spec are named weirdly - for example an endpoint such as getGenesis is currently named get_v1_beacon_genesis which would map 1:1 to the actual REST path in the future - verbose but unambiguous.

Beacon Node API


The latest head slot, as chosen by the latest fork choice.

curl -d '{"jsonrpc":"2.0","id":"id","method":"getBeaconHead","params":[] }' -H 'Content-Type: application/json' localhost:9190 -s | jq


Show chain head information, including head, justified and finalized checkpoints.

curl -d '{"jsonrpc":"2.0","id":"id","method":"getChainHead","params":[] }' -H 'Content-Type: application/json' localhost:9190 -s | jq







curl -d '{"jsonrpc":"2.0","id":"id","method":"getNetworkEnr","params":[] }' -H 'Content-Type: application/json' localhost:9190 -s | jq


curl -d '{"jsonrpc":"2.0","method":"get_v1_beacon_genesis","params":[],"id":1}' -H 'Content-Type: application/json' localhost:9190 -s | jq


curl -d '{"jsonrpc":"2.0","method":"get_v1_beacon_states_root","params":["finalized"],"id":1}' -H 'Content-Type: application/json' localhost:9190 -s | jq


curl -d '{"jsonrpc":"2.0","method":"get_v1_beacon_states_fork","params":["finalized"],"id":1}' -H 'Content-Type: application/json' localhost:9190 -s | jq


curl -d '{"jsonrpc":"2.0","method":"get_v1_beacon_states_finality_checkpoints","params":["finalized"],"id":1}' -H 'Content-Type: application/json' localhost:9190 -s | jq






curl -d '{"jsonrpc":"2.0","method":"get_v1_beacon_headers_blockId","params":["finalized"],"id":1}' -H 'Content-Type: application/json' localhost:9190 -s | jq


curl -d '{"jsonrpc":"2.0","method":"get_v1_beacon_blocks_blockId","params":["finalized"],"id":1}' -H 'Content-Type: application/json' localhost:9190 -s | jq


curl -d '{"jsonrpc":"2.0","method":"get_v1_beacon_blocks_blockId_root","params":["finalized"],"id":1}' -H 'Content-Type: application/json' localhost:9190 -s | jq


curl -d '{"jsonrpc":"2.0","method":"get_v1_beacon_blocks_blockId_attestations","params":["finalized"],"id":1}' -H 'Content-Type: application/json' localhost:9190 -s | jq


Valdiator API




curl -d '{"jsonrpc":"2.0","method":"get_v1_validator_attestation_data","params":[0,3],"id":1}' -H 'Content-Type: application/json' localhost:9190 -s | jq




curl -d '{"jsonrpc":"2.0","method":"post_v1_validator_duties_attester","params":[1,["a7a0502eae26043d1ac39a39457a6cdf68fae2055d89c7dc59092c25911e4ee55c4e7a31ade61c39480110a393be28e8","a1826dd94cd96c48a81102d316a2af4960d19ca0b574ae5695f2d39a88685a43997cef9a5c26ad911847674d20c46b75"]],"id":1}' -H 'Content-Type: application/json' localhost:9190 -s | jq


curl -d '{"jsonrpc":"2.0","id":"id","method":"get_v1_validator_duties_proposer","params":[1] }' -H 'Content-Type: application/json' localhost:9190 -s | jq



Administrative / Debug API

get_v1_debug_beacon_states_stateId - returns an entire BeaconState object for the specified stateId

curl -d '{"jsonrpc":"2.0","method":"get_v1_debug_beacon_states_stateId","params":["head"],"id":1}' -H 'Content-Type: application/json' localhost:9190 -s | jq


Show version of the software

curl -d '{"jsonrpc":"2.0","id":"id","method":"getNodeVersion","params":[] }' -H 'Content-Type: application/json' localhost:9190 -s | jq


Show spec constants in use.

curl -d '{"jsonrpc":"2.0","id":"id","method":"getSpecPreset","params":[] }' -H 'Content-Type: application/json' localhost:9190 -s | jq


Show a list of peers that the beacon node is connected to.

curl -d '{"jsonrpc":"2.0","id":"id","method":"peers","params":[] }' -H 'Content-Type: application/json' localhost:9190 -s | jq

Advanced Usage for Developers

Latest updates happen in the devel branch which is merged into master every week on Tuesday before deploying a new testnets The following sections explain how to setup your build environment on your platform.

Windows dev environment

Install Mingw-w64 for your architecture using the "MinGW-W64 Online Installer" (first link under the directory listing). Run it and select your architecture in the setup menu (i686 on 32-bit, x86_64 on 64-bit), set the threads to win32 and the exceptions to "dwarf" on 32-bit and "seh" on 64-bit. Change the installation directory to "C:\mingw-w64" and add it to your system PATH in "My Computer"/"This PC" -> Properties -> Advanced system settings -> Environment Variables -> Path -> Edit -> New -> C:\mingw-w64\mingw64\bin (it's "C:\mingw-w64\mingw32\bin" on 32-bit)

Install Git for Windows and use a "Git Bash" shell to clone and build nim-beacon-chain.

If you don't want to compile PCRE separately, you can fetch pre-compiled DLLs with:

mingw32-make # this first invocation will update the Git submodules
mingw32-make fetch-dlls # this will place the right DLLs for your architecture in the "build/" directory

If you were following the Windows testnet instructions, you can jump back to Connecting to testnets now

You can now follow those instructions in the previous section by replacing make with mingw32-make (regardless of your 32-bit or 64-bit architecture):

mingw32-make test # run the test suite

Linux, macOS

After cloning the repo:

# Build beacon_node and all the tools, using 4 parallel Make jobs
make -j4

# Run tests
make test

# Update to latest version
git pull
make update

To run a command that might use binaries from the Status Nim fork:

./ bash # start a new interactive shell with the right env vars set
which nim
nim --version # Nimbus is tested and supported on 1.0.2 at the moment

# or without starting a new interactive shell:
./ which nim
./ nim --version

Raspberry Pi

We recommend you remove any cover or use a fan; the Raspberry Pi will get hot (85°C) and throttle.

  • Raspberry PI 3b+ or Raspberry Pi 4b.
  • 64gb SD Card (less might work too, but the default recommended 4-8GB will probably be too small)
  • Raspbian Buster Lite - Lite version is enough to get going and will save some disk space!

Assuming you're working with a freshly written image:

# Start by increasing swap size to 2gb:
sudo vi /etc/dphys-swapfile
# :wq
sudo reboot

# Install prerequisites
sudo apt-get install git libgflags-dev libsnappy-dev libpcre3-dev

# Then you can follow instructions for Linux.

Makefile tips and tricks for developers

  • build all those tools known to the Makefile:
# $(nproc) corresponds to the number of cores you have
make -j$(nproc)
  • build a specific tool:
make state_sim
  • you can control the Makefile's verbosity with the V variable (defaults to 0):
make V=1 # verbose
make V=2 test # even more verbose
make LOG_LEVEL=DEBUG bench_bls_sig_agggregation # this is the default
make LOG_LEVEL=TRACE beacon_node # log everything
  • pass arbitrary parameters to the Nim compiler:
make NIMFLAGS="-d:release"
  • you can freely combine those variables on the make command line:
make -j$(nproc) NIMFLAGS="-d:release" USE_MULTITAIL=yes eth2_network_simulation
make USE_LIBBACKTRACE=0 # expect the resulting binaries to be 2-3 times slower

Setting up a systemd service

This guide will take you through how to set up a systemd service for your beacon node.

systemd is a service manager designed specifically for Linux. There is no port to Mac OS.


NBC's external dependencies and a working Go installation (v1.11 or later).

1. Clone repositories

Clone the nim-beacon-chain and eth2stats repositories in the same directory (so that both repositories are adjacent to each other).

git clone
git clone

2. Build repositories

Build both repositories by following their respective build instructions.


cd nim-beacon-chain
make beacon_node


cd eth2stats-client
make build

The resulting binaries should appear in nim-beacon-chain/build/beacon_node and eth2stats-client/eth2stats-client, respectively.

3. Create an executable script

Create an executable script,, and place it adjacent to the repositories you cloned in step 1 (same directory level).


set +e

trap "trap - SIGTERM && kill -- -$$" SIGINT SIGTERM EXIT

cd $(dirname "$0")
cd nim-beacon-chain


if [[ "$2" == "" ]]; then

let RPC_PORT=9190+${NODE_ID}

# add your node to eth2stats and run a data collector app that connects to your beacon chain client
mkdir -p /tmp/e2s-$ID
../eth2stats-client/eth2stats-client run \
  --data.folder=/tmp/${NODE_NAME} \
  --eth2stats.node-name="${NODE_NAME}" \
  --eth2stats.addr="grpc.${NETWORK}" --eth2stats.tls=true \
  --beacon.type="nimbus" \
  --beacon.addr="http://localhost:$RPC_PORT" \
  --beacon.metrics-addr="http://localhost:$METRICS_PORT/metrics" > /tmp/ethstats.$NODE_NAME.log 2>&1 &

# build and run the beacon node
make NIMFLAGS="-d:insecure" NODE_ID=$NODE_ID ${NETWORK}

Tip: don't forget to mark the script as executable by running chmod +x on it.

4. Create a systemd service unit file

Create a systemd service unit file, nbc.service, and save it in /etc/systemd/system/.

Description=Nimbus beacon node

ExecStart=<BASE-DIRECTORY>/ medalla



<BASE-DIRECTORY> with the location of the repository in which you performed the git clone command in step 1.

<USERNAME> with the username of the system user responsible for running the launched processes.

5. Notify systemd of the newly added service

sudo systemctl daemon-reload

6. Start the nim beacon chain service

sudo systemctl enable nbc --now

Frequently Asked Questions

What is Beacon Chain?

A complete introduction about the beacon chain can be found in the Ethereum 2.0 blog series.

In short, the beacon chain is a new type of blockchain to help the Ethereum blockchain to smoothly transfer its consensus algorithm from PoW (Proof of Work) to PoS (Proof of Stake), aka Ethereum 2.0.

Differences Between Beacon Chain and Ethereum 1.0

In traditional PoW, those that propose new blocks are called miners, whereas in PoS, they are called validators. In essence, miners rely on actual hardware (such as some specifically manufactured mining machines), while validators rely on just software and a good network connection.

What it is Like to Be a Validator?

It is obvious that you must have enough computing power or dedicated hardware in order to be a miner, but how about being a validator? Here is a brief overview:

  1. A special smart contract named deposit contract is deployed on the original Ethereum blockchain. Note that in this case, the new beacon chain and the original blockchain co-exists.
  2. To "register" as a validator, you have to first deposit 32 Ether from your account to this smart contract.
  3. Run the beacon node and wait for the network to sync before your validator is activated.
  4. That's all! Remember to stay connected to the network, or you may lose some of your deposit, as punishment, depending on how long you're offline. :P

What is Nimbus?

In a sentence, Nimbus is an Ethereum 1.0 & 2.0 Client for Resource-Restricted Devices.

It is open sourced at Development progress and updates can be viewed at the Nimbus blog.

Why are metrics not working?

Metrics are currently implemented using a HTTP server that hasn't been hardened sufficiently that it can be exposed as a public endpoint - it must thus be enabled specifically during build:

make NIMFLAGS="-d:insecure"
beacon_node --metrics ...


Follow these steps to contribute to this book!

We use an utility tool called mdBook to create online books from Markdown files.

Before You Start

  1. Install mdBook from here.
  2. Clone the repository by git clone
  3. Go to where the Markdown files are located by cd docs.

Real-Time Update and Preview Changes

  1. Run mdbook serve in the terminal.
  2. Preview the book at http://localhost:3000.

Build and Deploy

The first step is to submit a pull request to the devel branch. Then, after it is merged, do the following under our main repository:

  1. cd nim-beacon-chain
  2. git checkout devel
  3. git pull
  4. make update (This is to update the submodules to the latest version)
  5. make publish-book

Trouble Shooting

If you see file conflicts in the pull request, this may due to that you have created your new branch from an old version of the devel branch. Update your new branch using the following commands:

git checkout devel
git pull
make update
git checkout readme
git merge devel
# use something like `git mergetool` to resolve conflicts, then read the instructions for completing the merge (usually just a `git commit`)
# check the output of `git diff devel`

Thank you so much for your help to the decentralized and open source community. :)