Coinmonks
Published in

Coinmonks

Setup Ethereum 2.0 Validator Node with Lighthouse on Meddala, Goerli

Recent days have seen a lot of upwards movement in cryptocurrency prices due to increased interest in Defi. Ethereum is also leading this charge. Ethereum recently launched its phase 0 by going with its first eth2.0 multi-client medella testnet, supported with eth1 testnet Goerli. To know more about Ethereum 2.0 roadmap, read here.

The objective of this article is to cover detailed steps to set up Ethereum 2.0 Beacon Node and Validator on the Ethereum 2.0 Medalla multi-client testnet using Sigma Prime Lighthouse client. It is based on the following systems:

What is Lighthouse?

Lighthouse, backed up Sigma Prime, an information security and software engineering firm, is one among nine chosen teams building Eth2.0 client. It is written in Rust with a heavy focus on speed and security and has received funding from the Ethereum Foundation, ConsenSys, and Vitalik Buterin.

Please note

  • This setup is certainly not easy, and you need a fair understanding of advanced Linux operating systems like firewall, SSH, user accounts, configure Linux services.
  • You are also expected to know how to set up Ethereum 1.0 full-node and understand core tenets of Blockchain and Ethereum, e.g. mnemonic, private/public keys, account address, metamask wallet, solidity contracts, and transactions.
  • It will take many hours to complete this entire setup, so keep patience.

Steps

  • Set up an Ethereum1.0 test node of Goerli testnet on our server and let it synch with testnet latest block
  • Install and configure the Lighthouse Beacon Node
  • The deposit contract
  • Generate and activate validator keys
  • Configure the Lighthouse Validator Client

Step 0 — Preparation

I have used one of the commodity server hosted on Digital Ocean. Technically, this setup can be done on Raspberry pi 4 as well. If the machine is supported by private/public subnet with VPC on AWS, the server security group needs to be set up with the following ports. However, for this setup, you need to do it using Linux firewall service .

Update and upgrade the system

> sudo apt-get update -y && sudo apt-get upgrade -y

Security

By default, ufw is disabled, so before enabling it, you need to open

  • Port 22 for SSH connection,
  • Port 30303 TCP/UDP for Geth node to interact with its peer nodes,
  • Ports 9000/TCP and 9000/UDP to allow Lighthouse for P2P connections with peers for actions on the beacon node

Run the following commands

> ufw allow 22/tcp
> ufw allow 30303/tcp
> ufw allow 30303/udp
> ufw allow 9000/tcp
> ufw allow 9000/udp
> ufw enable
> ufw status numbered

The output should look like this.

> ufw status numbered
Status: active
To Action From
-- ------ ----
[ 1] 22/tcp ALLOW IN Anywhere
[ 2] 30303/tcp ALLOW IN Anywhere
[ 3] 30303/udp ALLOW IN Anywhere
[ 4] 9000/tcp ALLOW IN Anywhere
[ 5] 9000/udp ALLOW IN Anywhere
[ 6] 22/tcp (v6) ALLOW IN Anywhere (v6)
[ 7] 30303/tcp (v6) ALLOW IN Anywhere (v6)
[ 8] 30303/udp (v6) ALLOW IN Anywhere (v6)
[ 9] 9000/tcp (v6) ALLOW IN Anywhere (v6)
[10] 9000/udp (v6) ALLOW IN Anywhere (v6)

Step 1 — Install and Run Go Ethereum Node

Install Go Ethereum

> sudo add-apt-repository -y ppa:ethereum/ethereum
> sudo apt-get update
> sudo apt-get install ethereum

Since you have multiple systems to run in this server and all systems should run interruptedly, you need to set up these systems as Linux services. Any interruptions can lead to penality and slashing in the stake. Read here.

Run Go Ethereum as a Background Service

  • Create a account for the service to run under. You can’t log into the server using this account
  • Create the data directory for the Goerli chain. This is required for storing the Goerli node block data
  • Set directory permissions. The account needs permission to modify the data directory
  • Create a systemd service file to store the service config. You will use the config file to tell systemd to run the geth process
> sudo useradd --no-create-home --shell /bin/false goerli
> sudo mkdir -p /var/lib/goethereum
> sudo chown -R goerli:goerli /var/lib/goethereum
> sudo nano /etc/systemd/system/geth.service

Update the geth service configuration with the following code. Alternatively, you can pick commands from here.

[Unit]
Description=Ethereum go client
After=network.target
Wants=network.target

[Service]
User=goeth
Group=goeth
Type=simple
Restart=always
RestartSec=5
ExecStart=/usr/bin/geth --goerli --http --datadir /var/lib/goethereum --bootnodes "enode://d67359082562e4a599d0572c5a04909ca6e8650228c98f0a3a6844514f3a1ae0a8b0b6fe635a2e2f0e0e6be9f08d80f1994f4399e154134bc07080f0b0b64e42@68.183.59.172:30303,enode://95f5d03a95e7c5d0eb655b2fe3b5495b86d424b4681a200d402c30f233e1edc1846f2837b0dfe7df691fe007236ed1998d178774c9b8bc049be75a2c21038978@95.217.215.48:30303,enode://79e5d36f90ee0314293f4c1b1a4cd9ea13f1acd3d79b5a506870c70b6dbac6f9652ca86455886be854c9a1cfcc00d82cf0fa5d256bf7c40ae1fae0c21b437c7d@13.66.153.22:37912,enode://a9f7bb623c007d2b28038978dac6ebbe945c74f07cc91820c88cc95633b29468ca4708781fc99346a74ee43024b5e7cbb8b0803a988b57841b757cf975efa333@104.211.30.135:30303,enode://02200a7b5253969458e2addf6838b3f064c9c6b22288e92848a7ac5a367553d8d8c871b1af0603ac6ac2118bc15795b5aefe2d29b4729ae1e61e51a14201c8e9@18.194.247.237:30303,enode://553b679e4f84048f4340de271025fdd047869b39d419352d30cfd48dc97868263c8dc1481337946a41ef2836d2b5afece993012af982d8097de4cc062f50cda1@52.87.240.248:48584,enode://4531d2559d9707406f5132d9e9490b9ab6b1fa62ba9b10486d3f0eb7d8f6643b25f679c28ba4d4e0ac8e218d424aed8bd3a0a4ba9dd7bdec4823047adb8d0145@24.74.186.77:36804,enode://aaf930ed9bd450fe48b2f953da22393d6a0d0fdb2810ed16885d382d67fd89108d5777161c3b7401b922f34d8c416c74770f901147faf79c190de5bbbf0e3cc8@192.241.134.195:30303,enode://00e496ab9153d4dd8b88275352831fd3c75fdc255e57fdf9fe5875164672fb722889b0732f8df9aab3e16e82bef9b979840800e740bca1914252c598378ec52e@24.4.149.245:30304,enode://d26b54f391088fa3868811c643a72f42ea23be850670695c52bdd5ef6421e227c376d476e94e32de09793eec38cacaf69bd6f79f71a34e8662cc9ed0b35e7976@185.228.47.193:30303,enode://15032b1dcc97ebcbb9e060c27b775b81472653d19f932f75d0fd96a2ec1184698c7064401a01b08533783d8039c837a1dce3d69c23ef22289f02bb53a1dd70f7@202.187.155.60:30303,enode://4d03cdfa08658d6737fd18507b54e6653a236d41039d0dd8a3f9d0a3b06dff98c2af903daf99fe4cd2c6bfbb36f47554151336f42b971698c8bccf970f28c98a@51.210.9.77:40404,enode://3d4d8863396c39fa0710504dbe8803b776bef9d7fe3f732967fb8681552fd6d2dbe0c6f4642b45528060f5b168820ae93eb14d260617d29d815ffadc5c7db6f2@95.216.206.118:30303,enode://9a3f770e82a128ea27d1b73ca9819b05cf6f16275b7d9ee6151efe751966c771f7a82425447be97119743680c3bd421f024eccf24066aa46020d061aac5128dc@64.120.90.247:33656,enode://f7d7aa996c18e45efbe9b8a532f9f32bbdef027dc60a6999b6a06b97b3bd933995280b0a1390a4281edc2556ddfc46521814feb0e5839f82010dcaba1afec445@51.77.211.174:30303,enode://bfe4ae8c9638e56dc6c252d5fdf8fd7251b2ad82cbb89c56923c2e6ece2f5f71888d1fa6849a2f6aee901835876d6001bfce8aa29fa27aa4715fc2420596e399@155.93.136.72:56792,enode://10e545ef1ede27c90ef69863d50328f66de1ac806c67cf60d1bb4c72cc644fe11b6597ebd30d9e100d7ccdd05ae6b5d133d93122d81139baab03c2dd9e10c758@95.217.12.192:30303,enode://ca77b80280e607104f3997e92f1e9ea14e009cd51a471960f43c2a5c0f95405e6f669ac15a46db4f3dbdc77411551926dca0da0db32680a21b65cef80273bf5a@150.214.106.123:47524,enode://00b77e6c1f44719d48b305da24965e6c7b8af5ec614e883efb0c80617670585c4a949fe4a3fbacf6454afce7d074ecaac40213a893425522f1e941de71c007ed@155.93.196.78:58992,enode://6781b3fa91a8e5b2a89682f9307d2b66e21a4ae595d1b2dfe2662e5fbf7326f5db7a9acdcc64e8402b31a1e8fbefc6ba13fa0af4015a373a42a4de14fd6a306b@164.90.236.249:30303,enode://1d63c062e215caa90ab8348ab25bc38546d7112bf829d5e9a272e88fab0869bbef206e848acb4290448c6b6e077f312efef6075116a9bbeb0b069a95dbd7f103@86.88.214.39:30303,enode://6b5ee2f457fc091b762f9a058d35f7fc73f1c8116a1853b3db2279eba56dbd990c309084c002476a9cb1b8584ac3ee58e91184376ad22af337088ea357f0ef2e@86.154.249.228:30303,enode://c40e962b9bb3433303ea77a9d785faa4a6c43d67d813f3cbe42006412df64a74aab206c7138b90a74e4152bde99f5f94a310fe673e9c5b5b899c5c61e5c28de5@82.233.188.75:30303"

[Install]
WantedBy=default.target

The --goerli the flag is to run the Göerli test network, and the --http flag is to expose an endpoint (http://localhost:8545) that the beacon chain will connect to. --bootnodes flag to statically link chosen peer nodes to our geth node. This is to avoid any ongoing discovery for its peer. The List is taken from here. Please note that it is updated regularly.

Reload systemd to reflect the changes and start the service and check to make sure it’s running correctly.

> sudo systemctl daemon-reload
> sudo systemctl start geth
> sudo systemctl status geth
geth.service - Ethereum go client
Loaded: loaded (/etc/systemd/system/geth.service; enabled; vendor preset: enabled)
Aug 13 12:04:00 ubuntu-s-2vcpu-4gb-sgp1-eth geth[852]: INFO [08–13|12:04:00.654] Imported new chain segment blocks=1 txs=0 mgas=0.000 elapsed=”223.343µs” mgasps=0.0
Aug 13 12:04:13 ubuntu-s-2vcpu-4gb-sgp1-eth geth[852]: INFO [08–13|12:04:13.095] Chain reorg detected number=3217563 hash=”d20e45…488182" drop=1 dropfrom=”6882
Aug 13 12:04:13 ubuntu-s-2vcpu-4gb-sgp1-eth geth[852]: INFO [08–13|12:04:13.095] Imported new chain segment blocks=1 txs=3 mgas=0.796 elapsed=13.377ms mgasps=59.

Step 2 — Build Lighthouse

Install Dependencies

Lighthouse is built on Rust. Follow the prompts to install.

$ curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh

Since Rust modifies the PATH variable, you will need to log out and back in again, or you may get a command not found error when trying to compile.

To get started you need Cargo’s bin directory ($HOME/.cargo/bin) in your PATH environment variable. Next time you log in this will be done automatically.

Some packages (git, gcc, g++, make, cmake, etc.) are also required.

$ sudo apt install -y git gcc g++ make cmake pkg-config libssl-dev
$ sudo apt update

Build Lighthouse

Now dependencies are installed, you should now build Lighthouse client. The Lighthouse build produces a lighthouse binary. The same binary is used to run the Beacon node as well as validator client.

Clone the Lighthouse core repository, use ‘make’ to compile the Lighthouse binary and move the binary to the bin folder.

> git clone https://github.com/sigp/lighthouse.git
> cd lighthouse
> make
> sudo cp /$HOME/.cargo/bin/lighthouse /usr/local/bin

It will take a while to build it. So keep patience.

Step 3 — Configure the Beacon Node

You will run the beacon node as a service, so if the system restarts, the process will automatically start back up again.

Run the Beacon Node as a Background Service

  • Create a account for the service to run under
  • Create the data directory for the lighthouse beacon node to store beacon node data
  • Set directory permissions. The account needs permission to modify the data directory
  • Create/Use a fresh Ethereum1.0 Address using Metamask wallet on your favourite browser extension and copy the graffiti string by pressing Lighthouse orange icon at the left. In our case the address is ‘0xFa55bEacf4d07839e1B84B6E56f002402fe2eB94’
  • Get the POAP (Proof of Attendance Protocol) badge for your beacon node client from here. This is a graffiti which can be put up on your explorer block as proof that you participated during this test phase.
Graffiti for POAP
  • Create a systemd service file to store the service config. You will use the config file to tell systemd to run the lighthousebeacon process
> sudo useradd --no-create-home --shell /bin/false lighthousebeacon
> sudo mkdir -p /var/lib/lighthouse/beacon-node
> sudo chown -R lighthousebeacon:lighthousebeacon /var/lib/lighthouse/beacon-node
> sudo nano /etc/systemd/system/lighthousebeacon.service

Update the lighthousebeacon service configuration with the following code

[Unit]
Description=Lighthouse Beacon Node
After=network.target
Wants=network.target

[Service]
User=lighthousebeacon
Group=lighthousebeacon
Type=simple
Restart=always
RestartSec=5
ExecStart=/usr/local/bin/lighthouse beacon_node --datadir /var/lib/lighthouse/beacon-node --testnet medalla --http --eth1-endpoint http://127.0.0.1:8545 --graffiti <abcdefg12345saf>

[Install]
WantedBy=default.target

and replace copied graffiti string at ` — graffiti <abcdefg12345saf>` and save the file. Alternatively, you can pick commands from here.

Reload systemd to reflect the changes and start the service and check to make sure it’s running correctly.

> sudo systemctl daemon-reload
> sudo systemctl start lighthousebeacon
> sudo journalctl -f -u lighthousebeacon.service
Aug 12 08:09:50 ubuntu-s-2vcpu-4gb-sgp1-eth lighthouse[7237]: Aug 12 08:09:50.000 INFO Syncing est_time: 40 mins, speed: 5.33 slots/sec, distance: 12820 slots (1 days 18 hrs), peers: 51, service: slot_notifier
Aug 12 08:10:02 ubuntu-s-2vcpu-4gb-sgp1-eth lighthouse[7237]: Aug 12 08:10:02.001 INFO Syncing est_time: 39 mins, speed: 5.33 slots/sec, distance: 12693 slots (1 days 18 hrs), peers: 51, service: slot_notifier
Aug 12 08:10:14 ubuntu-s-2vcpu-4gb-sgp1-eth lighthouse[7237]: Aug 12 08:10:14.001 INFO Syncing est_time: 31 mins, speed: 6.67 slots/sec, distance: 12630 slots (1 days 18 hrs), peers: 53, service: slot_notifier
Aug 12 08:10:26 ubuntu-s-2vcpu-4gb-sgp1-eth lighthouse[7237]: Aug 12 08:10:26.001 INFO Syncing est_time: 31 mins, speed: 6.67 slots/sec, distance: 12567 slots (1 days 17 hrs), peers: 52, service: slot_notifier

Let the Beacon node sync with its latest state. `est_time` shows the ETA. Below state shows that the Beacon Node is fully synced.

> sudo journalctl -f -u lighthousebeacon.service
Aug 12 10:28:20 ubuntu-s-2vcpu-4gb-sgp1-eth lighthouse[7237]: Aug 12 10:28:20.893 INFO New block received hash: 0x7d84…95d2, slot: 56841, service: router
Aug 12 10:28:26 ubuntu-s-2vcpu-4gb-sgp1-eth lighthouse[7237]: Aug 12 10:28:26.000 INFO Synced slot: 56841, block: 0x7d84…95d2, epoch: 1776, finalized_epoch: 1774, finalized_root: 0x9bf1…f0db, peers: 55, service: slot_notifier
Aug 12 10:28:33 ubuntu-s-2vcpu-4gb-sgp1-eth lighthouse[7237]: Aug 12 10:28:33.846 INFO New block received hash: 0xcb1f…05bc, slot: 56842, service: router
Aug 12 10:28:38 ubuntu-s-2vcpu-4gb-sgp1-eth lighthouse[7237]: Aug 12 10:28:38.000 INFO Synced slot: 56842, block: 0xcb1f…05bc, epoch: 1776, finalized_epoch: 1774, finalized_root: 0x9bf1…f0db, peers: 52, service: slot_notifier

Step 4 — Put validator stake with the Medalla

Get Goerli Staking ETH

  1. Ask Goerli Testnet faucet for 32 ETH
  2. If you are planning on running multiple validators, you can ask for 32 ETH x number of validators.

Once the Goerli ETH appears in your MetaMask wallet, continue to the next step.

Staking Goerli ETH

Follow the steps given below to install ‘eth2deposit’ script and run it with the given commands

> cd ~
> curl -LO https://github.com/ethereum/eth2.0-deposit-cli/releases/download/v0.2.1/eth2deposit-cli-v0.2.1-linux-amd64.tar.gz
eth2deposit-cli-v0.2.1-linux-amd64.tar.gz 100%[========================================================================================>] 14.56M 5.47MB/s in 2.7s
2020-08-12 07:19:25 (5.47 MB/s) - 'eth2deposit-cli-v0.2.1-linux-amd64.tar.gz' saved [15271039/15271039]
-rw-r--r-- 1 root root 15M Jul 28 07:10 eth2deposit-cli-v0.2.1-linux-amd64.tar.gz

> tar -xzf eth2deposit-cli-v0.2.1-linux-amd64.tar.gz
> cd eth2deposit-cli-de03fe3-linux-amd64
-rwxr-xr-x 1 goerli lighthousebeacon 15M Jul 28 07:00 deposit

> ./deposit --num_validators 1 --chain medalla

Please choose your mnemonic language (italian, korean, spanish, chinese_traditional, chinese_simplified, english, czech) [english]: <Enter>
Type the password that secures your validator keystore(s): <Enter the password>
Repeat for confirmation: <Enter the password>

This is your seed phrase. Write it down and store it safely, it is the ONLY way to retrieve your deposit.
<Enter your mnemonics>

Press any key when you have written down your mnemonic.

Creating your keys.
Saving your keystore(s).
Creating your deposit(s).
Verifying your keystore(s).
Verifying your deposit(s).

Success!
Your keys can be found at: /root/eth2deposit-cli-de03fe3-linux-amd64/validator_keys

➜ validator_keys l
total 16K
drwxr-xr-x 2 root root 4.0K Aug 12 07:25 .
drwxrwxr-x 3 goerli lighthousebeacon 4.0K Aug 12 07:25 ..
-rw-r--r-- 1 root root 647 Aug 12 07:25 deposit_data-1597217105.json
-rw-r--r-- 1 root root 710 Aug 12 07:25 keystore-m_12381_3600_0_0_0-1597217104.json

> sudo chown -R root:root /var/lib/lighthouse/validator
> lighthouse account validator import - directory ~/eth2deposit-cli-de03fe3-linux-amd64/validator_keys - validator-dir /var/lib/lighthouse/validator
Successfully moved keystore.
Successfully updated validator_definitions.yml.
Successfully imported 1 validators.

Alternatively, you can pick commands from here.

You can check the staking transaction on goerli testnet. Whoever is coming from the background of Ethereum1.0 can easily understand that this is the Solidity contract Medella BeaconContractor which needs to be sent 32 ‘Goerli’ ETH before it can become validator for the Beacon Chain. This 32 ETHs are staking amount and probably can not be retrieved?

Generate Validator Data

Go to the official Eth2 LaunchPad and follow the instructions. If everything works correctly, validator key files (keystore-m JSON files) will be generated — once for each validator requested. Back them up!

Drop the generated deposit-data-[timestamp].json

Eventually, you should see such a screen.

Now you have reached a very interesting stage. The below image shows the 32 ETHs are already deposited; however, you may not become validator immediately even when you start the validator client process now. The picture shows that it might take 5.08 hrs max; however, it entirely depends upon the length of the validator queue. Every epoch four validators get activated. So if there are over 5000 in the queue, it might take ~ 5 days more or less.

Meddala Validator
Meddala Validator

Read this excerpts from here to understand the technicalities of it.

Step 5 — Configure the Lighthouse Validator Client

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

Run Validator Client as a Background Service

  • Create a account for the service to run under
  • Create the data directory for the lighthouse validator client to store beacon node data
  • Set directory permissions. The account needs permission to modify the data directory
  • Create a systemd service file to store the service config. You will use the config file to tell systemd to run the lighthousevalidator process
> sudo useradd --no-create-home --shell /bin/false lighthousevalidator
> sudo mkdir -p /var/lib/lighthouse/validator
> sudo chown -R lighthousevalidator:lighthousevalidator /var/lib/lighthouse/validator
> sudo nano /etc/systemd/system/lighthousevalidator.service

Update the lighthousevalidator service configuration with following code

[Unit]
Description=Lighthouse Validator
After=network.target
Wants=network.target

[Service]
User=lighthousevalidator
Group=lighthousevalidator
Type=simple
Restart=always
RestartSec=5
ExecStart=/usr/local/bin/lighthouse validator_client --datadir /var/lib/lighthouse/validator

[Install]
WantedBy=default.target

Alternatively, you can pick the text from here.

Reload systemd to reflect the changes and start the service and check to make sure it’s running correctly. For me, it showed below messages. That means, my beacon-node service is not synced yet. So I had to wait.

> sudo systemctl daemon-reload
> sudo systemctl start lighthousevalidator
> sudo journalctl -f -u lighthousevalidator.service
Aug 12 08:02:14 ubuntu-s-2vcpu-4gb-sgp1-eth lighthouse[10221]: Aug 12 08:02:14.001 ERRO Beacon node is syncing current_slot: 40800, target_slot: 56032, msg: not receiving new duties, service: notifier
Aug 12 08:02:26 ubuntu-s-2vcpu-4gb-sgp1-eth lighthouse[10221]: Aug 12 08:02:26.001 ERRO Beacon node is syncing current_slot: 40990, target_slot: 56032, msg: not receiving new duties, service: notifier
Aug 12 08:02:38 ubuntu-s-2vcpu-4gb-sgp1-eth lighthouse[10221]: Aug 12 08:02:38.002 ERRO Beacon node is syncing current_slot: 41055, target_slot: 56032, msg: not receiving new duties, service: notifier

Later, I saw these messages. At the time of writing this article, I am still getting this message. That means I am still in the queue.

Aug 12 10:16:38 ubuntu-s-2vcpu-4gb-sgp1-eth lighthouse[10221]: Aug 12 10:16:38.002 INFO Awaiting activation                     slot: 56782, epoch: 1774, validators: 1, service: notifier
Aug 12 10:16:50 ubuntu-s-2vcpu-4gb-sgp1-eth lighthouse[10221]: Aug 12 10:16:50.001 INFO Awaiting activation slot: 56783, epoch: 1774, validators: 1, service: notifier
Aug 12 10:17:02 ubuntu-s-2vcpu-4gb-sgp1-eth lighthouse[10221]: Aug 12 10:17:02.001 INFO Awaiting activation slot: 56784, epoch: 1774, validators: 1, service: notifier
Aug 12 10:17:14 ubuntu-s-2vcpu-4gb-sgp1-eth lighthouse[10221]: Aug 12 10:17:14.002 INFO Awaiting activation slot: 56785, epoch: 1774, validators: 1, service: notifier

To understand the logic of activation, read below from here

Acknowledgements

While I understand the nitty-gritty of ethereum 1.0 technologies, this is my first experiment on ethereum 2.0 tech stack.

This guide is based on information I pulled together from various online resources and some article from the medium, mentioned below. I have improved that article as per my experience. Thank you, all to come through thus far!!

Additionally,

Ethereum team recommended a specific set of metrics which every beacon node client should expose. Taking it forward, Prometheus metrics and Grafana dashboard tools can be configured to better monitor the state of the machine as well as lighthouse validator state.

Lighthouse gives a repository on how to use these tools. You can check set of dashboards here. I have configured Summary to view metrics with Graffana.

I will cover it in the next article. Till then Bye!! Happy Learning!! :-)

References:

For technical questions and error, you can connect with Lighthouse Discord server.

Also, Read

--

--

Coinmonks (http://coinmonks.io/) is a non-profit Crypto Educational Publication. Follow us on Twitter @coinmonks and Our other project —  https://coincodecap.com, Email  — gaurav@coincodecap.com

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