Anyblock Analytics is now Blockdaemon Germany! Read the news under our blog!
Jan 28, 2021

Setting up a Validator in the Celo baklava testnet with faucet funds – optimized sequence from Anyblock experience


Icon article header
Celo Logo

Dear Celo community,

in the following article we would like to share with you our experience from setting up a Validator in the baklava testnet during the Celo Foundation Voting Program for Cohort 6.

Since we could not find a documentation on the registration of a Validator with faucet funds instead of ReleaseGold smart contracts that was official, up-to-date and complete, we would like to present to you our approach and hope that with this report we are able to give back a little as well as make things easier for those interested in the Celo Platform and supporting this extraordinary project by registering their own Validator in the future.

By and large, we will follow the structure of the official documentation, deviating from it only where it has posed us with challenges that we believe can be avoided by slight adaptations to commands and sequence.

Many thanks go out to the Celo Discord Channel, Yaz Khoury and Ponti | cLabs for their untiring commitment and especially Jeff Haferman, whose unofficial documentation has been a great source of inspiration and for the most part required only selective updates to its commands to make our installation succeed.

But enough rambling, let’s begin!


Despite its large amount of commands, to keep this article as short and crisp as possible, we will limit this section to additions to the existing documentations mentioned above.

Hardware requirements

To start off, please note that beyond the required machines listed as Validator, (Validator) Proxy and Attestation nodes, you will also intensively use a “local machine” as Accounts node, i.e. to create and manage the multitude of accounts that are involved in the setup.

Why do we specifically highlight this and set the local machine between quotation marks?

Firstly because the Accounts node does not necessarily have to reside on a machine in your physical location and secondly you need to be aware that your Accounts node will have to sync with the testnet during setup. Depending on the performance and network connection of your machine this process can take up large parts of the resources of e.g. your business laptop for hours. Also, keep in mind that by default, the credentials of almost all the accounts created during this setup are stored on the Accounts node, which means that they might not be available when your local machine is busy or shut down.

Finally, please consider that during the Walkthrough of the Security Self Assessment required from you for the Foundation Voting Program you will be awarded with additional points in case your Validator setup signs transactions using a Ledger Nano S or X as well as for keeping an additional up-to-date Validator machine ready for means of Validator Signer Key Rotation and the event your Validator node needs to be upgraded. The points potentially gained from the additional hardware arrangements can become the deciding factor between the acceptance or rejection of your application and therefore should not be taken lightly.

Software requirements

Our setup was executed and tested on machines running Ubuntu 20.04.1 LTS and the following software versions:

  • nvm v0.37.2
  • node v10.23.0 LTS
  • npm 6.14.8
  • docker 5:20.10.2~3-0~ubuntu-focal
  • celocli 0.0.60

All but the celocli commands were performed as root user and the /root directory of the respective machine thus represents the assumed start directory of each node’s setup according to our sequence.

In case you are interested in managing your machines not only from your Accounts node but directly from each individual machine, you have to install celocli on them.
During installation you might be presented with two challenges:

  1. If nvm was set up in an interactive login shell (e.g. sudo -i, or sudo su -) the installation of the celocli npm package might fail due to a permission conflict with node-gyp. To fix this, you can try adding --unsafe-perm to your command:
    npm install -g @celo/celocli --unsafe-perm
  2. For us, during the above mentioned step an error was reported while processing the libsecret package – it was simply not part of our machines yet. In case this is true for your setup as well, the following command will make sure all required resources are available and celocli can be installed without errors:
    apt-get install libsecret-1-0

Please note, that in order to properly use the celocli on a machine, you must first transfer the credentials of each account you wish to manage to the respective node, and since in the vast majority of cases these have been created on and their keys been stored to the Accounts node, we honestly have refrained from doing so.

Accounts node (“local machine”) setup

While the following instructions do not necessarily deviate from the original and those not necessarily are incomplete or incorrect, for an easier flow of this article we from here on will list all commands required to set up a Validator, Proxy and Attestation node in full, only shortened to references where commands can be adopted one to one.

Differing from the official documentation of running a Validator in the baklava testnet using ReleaseGold contracts and instead similar to the sequence of Haferman’s approach to The Great Celo Stake Off (TGCSO), we recommend to you to first set up the Accounts node.
This way you can create your Validator Group and Validator accounts early on and a DevRel manager can transfer faucet funds to them way before things get heated, e.g. close to a deadline, and we all know they eventually will ;-). During the process of this article, the funds will be needed for your setup to be allowed to register and run for election as Celo Validator.

We began the Accounts node setup with defining the baklava environment variable:

# On the Accounts machine

following pulled the Celo image:

# On the Accounts machine
docker pull $CELO_IMAGE

made and changed into the celo-accounts-node directory:

# On the Accounts machine
mkdir celo-accounts-node
cd celo-accounts-node

over there generated two passwords (e.g. as follows):

# On the Accounts machine
pwgen -c -n 24 2

and used those to create the Validator Group as well as Validator account, twice running the following command:

# On the Accounts machine
docker run -v $PWD:/root/.celo --rm -it $CELO_IMAGE account new

and after storing their credentials to our password vault, set up their addresses:

export CELO_VALIDATOR_ADDRESS=<YOUR_CELO_VALIDATOR_ADDRESS><your_celo_validator_address></your_celo_validator_address></your_celo_validator_group_address>

enabling us to run the celo-accounts container:

# On the Accounts machine
docker run --name celo-accounts -it --restart always -p -v $PWD:/root/.celo $CELO_IMAGE --verbosity 3 --syncmode full --rpc --rpcaddr --rpcapi eth,net,web3,debug,admin,personal --baklava --light.serve 0 --datadir /root/.celo

At this point the Accounts node synced with baklava for several hours, which at the time of our setup claimed around 3.5 GB of disk space.
Like for us, this could be the perfect moment for you to request the faucet funds to be transferred to your Validator Group and Validator account from a DevRel manager.

Note: Not relevant at this moment, but initialising the celo-accounts container in the above mentioned way will lead to a conflict with the security mechanisms of celocli when trying to unlock accounts, which simply is not possible in conjunction with the insecure --rpcaddr flag. To allow the necessary unlocking anyway, either --allow-insecure-unlock can already be added to the command here, or the celo-accounts container can be stopped, deleted and replaced by a new one with the relevant adaptation right before unlocking accounts later on.

Validator node setup

Naturally, Validator and Proxy nodes are closely interwoven with one another. Taking into account the dependencies of the upcoming setup steps, we suggest continuing from here on with the Validator, then moving on to the Proxy and finally completing the Validator node.

Defining the baklava environment and pulling the Celo docker image were performed analogously to the Account node procedure, with the obvious exception that they were performed on the Validator instead of the Accounts node.

Further on we made and changed into the celo-validator-node directory:

# On the Validator machine
mkdir celo-validator-node
cd celo-validator-node

then generated and directly wrote a password to .password (e.g. as follows):

# On the Validator machine
pwgen -c -n 24 > .password

created the Validator Signer account associated with the .password file (see Accounts node setup), secured the account’s credentials and defined its address as variable:

# On the Validator machine
export CELO_VALIDATOR_SIGNER_ADDRESS=<YOUR_CELO_VALIDATOR_SIGNER_ADDRESS><your_celo_validator_signer_address></your_celo_validator_signer_address>

before proceeding to the:

(Validator) Proxy node setup

In addition to the renewed export of the baklava environment variable and pulling the Celo image (see Accounts node setup) we started off the Proxy setup by defining our freshly created Validator Signer address:

# On the Proxy machine
export CELO_VALIDATOR_SIGNER_ADDRESS=<YOUR_CELO_VALIDATOR_SIGNER_ADDRESS><your_celo_validator_signer_address></your_celo_validator_signer_address>

made and changed into the celo-proxy-node directory:

# On the Proxy machine
mkdir celo-proxy-node
cd celo-proxy-node

generated and wrote a password to .password (see Validator node setup) as well as created the corresponding Proxy account:

# On the Proxy machine
docker run --name celo-proxy-password -it --rm  -v $PWD:/root/.celo $CELO_IMAGE account new --password /root/.celo/.password

before storing the password and resulting key pair as well as defining a new variable:

# On the Proxy machine
export PROXY_ADDRESS=<YOUR_PROXY_ADDRESS><your_proxy_address></your_proxy_address>

to finally run the celo-proxy container including the unlocking of the Proxy address:

# On the Proxy machine
docker run --name celo-proxy -it --restart unless-stopped -p 30303:30303 -p 30303:30303/udp -p 30503:30503 -p 30503:30503/udp -v $PWD:/root/.celo $CELO_IMAGE --verbosity 3 --nousb --syncmode full --proxy.proxy --proxy.proxiedvalidatoraddress $CELO_VALIDATOR_SIGNER_ADDRESS --proxy.internalendpoint :30503 --etherbase $PROXY_ADDRESS --unlock $PROXY_ADDRESS --password /root/.celo/.password --allow-insecure-unlock --baklava --datadir /root/.celo <span>--celostats=<YOUR_VALIDATOR_NAME>@</span><your_validator_name></your_validator_name>

Please note that even though we did not experience any negative side effects from them in the first place, the addition of the --nousb flag to aforementioned command (in contrast to the one of the celo-accounts container) might eliminate the reoccurrence of some of the warnings we encountered during startup of the former.
Also, even if the --celostats flag is set correctly for both the Proxy and Validator machines, the status of your setup might not permanently be displayed as online on Celostats.
Do not worry though, it must not mean that your setup is corrupt, but could be caused by problems of Celostats which have been reported and discussed on both Discord and GitHub before, but seem to remain without definite solutions so far. Therefore prior to, in fear of a problem with your setup, restarting your containers to make your Validator appear online again – like we did – first check if you are indeed not signing blocks and do not risk a potential hit to your Validator score due to pointless restarts and preventable downtime.
The following command will only be functional once the setup of your Validator is completed, but will give you a rapid disclosure on the current signature rate of your Validator and thus might save you a headache:

# On any of your machines with fully configured celocli and a completed Validator setup
celocli validator:status

Back to the Proxy node setup though.
With the celo-proxy container running, we could then retrieve our Proxy enode information:

# On the Proxy machine
docker exec celo-proxy geth --exec "admin.nodeInfo['enode'].split('//')[1].split('@')[0]" attach | tr -d '"'

and our Proxy’s IP addresses (which of course we knew beforehands):

# On the Proxy machine
dig +short

To confirm the networking requirements of our Proxy were configured correctly, we – on the Accounts node – then set up the Proxy’s external IP address as variable:

# On the Accounts machine
export PROXY_EXTERNAL_IP=<YOUR_PROXY_EXTERNAL_IP><your_proxy_machine_external_ip_address></your_proxy_machine_external_ip_address>

and tested if the Proxy was accepting our TCP connections over port 30303:

# On the Accounts machine
nc -vz $PROXY_EXTERNAL_IP 30303

as well as 30503:

# On the Accounts machine
nc -vz $PROXY_EXTERNAL_IP 30503

Hopefully as unnecessary for you as for us, problems with the reachability of your nodes can usually be solved quickly with the help of ufw.

Completion of Validator node setup

As both the celo-accounts and celo-proxy containers were up and running as intended, we could focus on the completion of the Validator node.

First, we exported the entire set of new variables from the Accounts and Proxy nodes:

# On the Validator machine
export CELO_VALIDATOR_ADDRESS=<YOUR_CELO_VALIDATOR_ADDRESS><your_celo_validator_address>
export PROXY_ENODE=<span style="font-weight: 400;"><YOUR_PROXY_ENODE></span><your_proxy_enode>
export PROXY_EXTERNAL_IP=<YOUR_PROXY_EXTERNAL_IP><your_proxy_machine_external_ip>
export PROXY_INTERNAL_IP=<meta http-equiv="content-type" content="text/html; charset=utf-8" /><your_celo_validator_group_address><your_celo_validator_address><your_proxy_enode><YOUR_PROXY_INTERNAL_IP></your_proxy_enode></your_celo_validator_address></your_celo_validator_group_address><your_proxy_machine_internal_ip></your_proxy_machine_internal_ip></your_proxy_machine_external_ip></your_proxy_enode></your_celo_validator_address></your_celo_validator_group_address>

and could then run the celo-validator container:

# On the Validator machine
docker run --name celo-validator -it --restart unless-stopped -p 30303:30303 -p 30303:30303/udp -v $PWD:/root/.celo $CELO_IMAGE --verbosity 3 --syncmode full --mine --istanbul.blockperiod=5 --istanbul.requesttimeout=3000 --etherbase $CELO_VALIDATOR_SIGNER_ADDRESS --nodiscover --nousb --proxy.proxied --proxy.proxyenodeurlpairs=enode://$PROXY_ENODE@$PROXY_INTERNAL_IP:30503\;enode://$PROXY_ENODE@$PROXY_EXTERNAL_IP:30303 --unlock=$CELO_VALIDATOR_SIGNER_ADDRESS --password /root/.celo/.password <span>--celostats=<YOUR_VALIDATOR_NAME></span>=<your_validator_name> --baklava --datadir /root/.celo</your_validator_name>

to have all three – the Accounts, Proxy and Validator node – syncing with baklava, which lead us to the following step.

Registration of Accounts as Validator

The registration of accounts as Validator asked for the proper configuration of the Validator Signer’s signatures and keys, beginning with the provision of a proof of possession of the Validator Signer private key by signing a message consisting of the Validator address:

# On the Validator machine
docker run -v $PWD:/root/.celo --rm -it $CELO_IMAGE --password /root/.celo/.password account proof-of-possession $CELO_VALIDATOR_SIGNER_ADDRESS $CELO_VALIDATOR_ADDRESS

Please note that we had to add --password /root/.celo/.password to the command since the interactive input of the Validator Signer password did not lead to the desired outcome.
The same was done for the proof of possession of our Validator Signer derived BLS key pair and signature:

# On the Validator machine
docker run -v $PWD:/root/.celo --rm -it $CELO_IMAGE --password /root/.celo/.password account proof-of-possession $CELO_VALIDATOR_SIGNER_ADDRESS $CELO_VALIDATOR_ADDRESS --bls

Once we had all of the credentials securely stored in our password vault, we could then return to our Accounts node and feed it with the new variables:

# On the Accounts machine
export CELO_VALIDATOR_SIGNER_BLS_PUBLIC_KEY=<YOUR_CELO_VALIDATOR_SIGNER_BLS_PUBLIC_KEY><your_celo_validator_signer_bls_public_key></your_celo_validator_signer_bls_public_key></your_celo_validator_signer_bls_signature></your_celo_validator_signer_public_key></your_celo_validator_signer_signature></your_celo_validator_signer_address>

This was the moment our note regarding the security conflict of the celo-accounts container came into play. Since we had not adjusted the initial command, we had to carefully stop:

# On the Accounts machine
docker stop celo-accounts -t 60


# On the Accounts machine
docker rm celo-accounts

and replace our existing container with a new one:

# On the Accounts machine
docker run --name celo-accounts -it --restart always -p -v $PWD:/root/.celo $CELO_IMAGE --verbosity 3 --syncmode full --rpc --rpcaddr --rpcapi eth,net,web3,debug,admin,personal --baklava --light.serve 0 --datadir /root/.celo --allow-insecure-unlock

in order to subsequently be able to unlock our Validator Group:

# On the Accounts machine
celocli account:unlock $CELO_VALIDATOR_GROUP_ADDRESS

and Validator:

# On the Accounts machine
celocli account:unlock $CELO_VALIDATOR_ADDRESS

as well as to register our Validator Group:

# On the Accounts machine
celocli account:register --from $CELO_VALIDATOR_GROUP_ADDRESS --name <span><YOUR_VALIDATOR_GROUP_NAME></span><your_validator_group_name></your_validator_group_name>

and Validator accounts:

# On the Accounts machine
celocli account:register --from $CELO_VALIDATOR_ADDRESS --name <span><YOUR_VALIDATOR_NAME></span><your_validator_name></your_validator_name>

Please bear in mind that both registering your accounts as well as fixing the setName error we encountered meanwhile (and which, looking at the amount of elected baklava validators on Celostats lacking a clear name, seems to be quite common) costs a small amount of CELO. Therefore, make sure that at least by now you have received your faucet funds, or else you will not be able to perform the actions described.

Since we believe that a clear recognizability of one’s setup is important, we retrospectively used celocli to adjust the names of our nodes that were not set properly during registration:

# On the Accounts machine
celocli account:set-name --account <<span style="font-weight: 400;">YOUR_VALIDATOR_OR_VALIDATOR_GROUP_ADDRESS> --name <YOUR_VALIDATOR_OR_VALIDATOR_GROUP_NAME></span><your_validator_or_validator_group_address><your_validator_or_validator_group_name></your_validator_or_validator_group_name></your_validator_or_validator_group_address>

and once configured as desired, locked up the 10000e18 CELO required of Validator Group:

# On the Accounts machine
celocli lockedgold:lock --from $CELO_VALIDATOR_GROUP_ADDRESS --value 10000e18

and Validator to secure their right to collaboratively become an elected Validator:

# On the Accounts machine
celocli lockedgold:lock --from $CELO_VALIDATOR_ADDRESS --value 10000e18

When Validator Group:

# On the Accounts machine
celocli lockedgold:show $CELO_VALIDATOR_GROUP_ADDRESS

and Validator showed that the required amounts of CELO had been successfully locked in:

# On the Accounts machine
celocli lockedgold:show $CELO_VALIDATOR_ADDRESS

we next could register our Validator Group, specifying its commission rate:

# On the Accounts machine
celocli validatorgroup:register --from $CELO_VALIDATOR_GROUP_ADDRESS --commission 0.1

and subsequently – in order not to be exposed to the risk of signing every transaction with the Validator Key as well as to be able to rotate keys in sense of best practice – authorized a Validator Signer Key:

# On the Accounts machine
celocli account:authorize --from $CELO_VALIDATOR_ADDRESS --role validator --signature $CELO_VALIDATOR_SIGNER_SIGNATURE --signer $CELO_VALIDATOR_SIGNER_ADDRESS

as well as registered our Validator using the BLS key of our freshly authorized Validator Signer:

# On the Accounts machine

Now we were able to affiliate our Validator with the Validator Group:

# On the Accounts machine

and accepted its membership to complete the affiliation:

# On the Accounts machine
celocli validatorgroup:member --accept $CELO_VALIDATOR_ADDRESS --from $CELO_VALIDATOR_GROUP_ADDRESS

the success of which we checked with:

# On the Accounts machine
celocli validator:show $CELO_VALIDATOR_ADDRESS
celocli validatorgroup:show $CELO_VALIDATOR_GROUP_ADDRESS

Vote in Election

Though, to be elected as Validator you do not only have to lock up the sufficient amount of CELO, but also cast the votes of your nodes on your own Validator Group.
To accomplish this, we again navigated between the approaches of the well-known documentations and analogous to the Validator Signer, set up a Vote as well as Group Vote Signer account. For the very same security reasons as for the Validator Signer we recommend this procedure to you too.
The steps of generating passwords as well as creating and storing the credentials of additional accounts to a password vault can be adopted entirely from the Accounts node setup. Just be careful and make sure you are located in the celo-accounts-node directory so that all keys are saved properly into the same keystore.

So once we had performed those steps, we exported the resulting variables:

# On the Accounts machine
export CELO_VALIDATOR_VOTE_SIGNER_ADDRESS=<meta http-equiv="content-type" content="text/html; charset=utf-8" /><YOUR_VALIDATOR_VOTE_SIGNER_ADDRESS><your_validator_vote_signer_address></your_validator_vote_signer_address></your_validator_group_vote_signer_address>

provided the proof of possession of our Validator Group Vote Signer:

# On the Accounts machine
docker run -v $PWD:/root/.celo --rm -it $CELO_IMAGE --nousb account proof-of-possession $CELO_VALIDATOR_GROUP_VOTE_SIGNER_ADDRESS $CELO_VALIDATOR_GROUP_ADDRESS

as well as our Validator Vote Signer private keys:

# On the Accounts machine
docker run -v $PWD:/root/.celo --rm -it $CELO_IMAGE --nousb account proof-of-possession $CELO_VALIDATOR_VOTE_SIGNER_ADDRESS $CELO_VALIDATOR_ADDRESS

and defined the accompanying variables:

# On the Accounts machine
export CELO_VALIDATOR_VOTE_SIGNER_PUBLIC_KEY=<YOUR_VALIDATOR_VOTE_SIGNER_PUBLIC_KEY><your_validator_vote_signer_public_key></your_validator_vote_signer_public_key></your_validator_vote_signer_signature></your_validator_group_vote_signer_public_key></your_validator_group_vote_signer_signature>

With all that in place it was now possible to authorize our Validator Group Vote Signer:

# On the Accounts machine

and Validator Vote Signer keys:

# On the Accounts machine

transfer a small amount of CELO to our Validator Group Vote Signer:

# On the Accounts machine

and Validator Vote Signer accounts to cover the fees of the upcoming operations:

# On the Accounts machine
celocli transfer:celo --from $CELO_VALIDATOR_ADDRESS --to $CELO_VALIDATOR_VOTE_SIGNER_ADDRESS --value 1e18

as well as to unlock both, the Validator Group Vote Signer:

# On the Accounts machine

and Validator Vote Signer accounts:

# On the Accounts machine

To finalize the registration of our Validator, we then cast the votes of our Validator Group:

# On the Accounts machine
celocli election:vote --from $CELO_VALIDATOR_GROUP_VOTE_SIGNER_ADDRESS --for $CELO_VALIDATOR_GROUP_ADDRESS --value 10000e18

and Validator on our own Validator Group:

# On the Accounts machine
celocli election:vote --from $CELO_VALIDATOR_VOTE_SIGNER_ADDRESS --for $CELO_VALIDATOR_GROUP_ADDRESS --value 10000e18

as well as activated the votes of both Validator Group and Validator to therefore make them eligible to receive epoch rewards:

# On the Accounts machine
celocli election:activate --from $CELO_VALIDATOR_GROUP_ADDRESS --wait<span> && celocli election:activate --from $CELO_VALIDATOR_ADDRESS --wait</span>

You can check if the cast of votes worked out with the following commands:

# On the Accounts machine
celocli election:show $CELO_VALIDATOR_GROUP_ADDRESS --group
celocli election:show $CELO_VALIDATOR_GROUP_ADDRESS --voter
celocli election:show $CELO_VALIDATOR_ADDRESS --voter

monitor your epoch rewards gained as follows:

# On the Accounts machine
celocli lockedgold:show $CELO_VALIDATOR_GROUP_ADDRESS
celocli lockedgold:show $CELO_VALIDATOR_ADDRESS

and check the status of your own as well as a list of your fellow elected Validators with:

# On the Accounts machine
celocli validator:status --validator $CELO_VALIDATOR_ADDRESS
celocli election:list

Attestation node setup

Having worked through the scope of the official documentation with our adapted sequence and being listed as an elected Validator on Celostats, we had now taken a big step towards completing our setup, missing only the Attestation Service.
Apart from the rebranding of Nexmo to Vonage – which does not impact how one has to specify the service in the Attestation Service config file – and the lack of MessageBird availability at the time of our setup, there is nothing worth mentioning about the configuration of the SMS Providers, as everything else worked out exactly as described.
Luckily, the same was true for most of the Attestation node setup itself.

For the fourth time we started with defining the baklava environment and pulling the Celo image (see Accounts node setup) before making and changing into the machine’s celo-attestations-node directory:

# On the Attestation machine
mkdir celo-attestations-node
cd celo-attestations-node

there generating a password for and creating the Attestation Signer account (see Accounts node setup) as well as after storing its credentials, exporting its address as variable:

# On the Attestation machine
export CELO_ATTESTATION_SIGNER_ADDRESS=<YOUR_CELO_ATTESTATION_SIGNER_ADDRESS><your_celo_attestation_signer_address></your_celo_attestation_signer_address>

before being able to provide the proof of possession of the Attestation Signer private key:

# On the Attestation machine
docker run -v $PWD:/root/.celo --rm -it $CELO_IMAGE --nousb account proof-of-possession $CELO_ATTESTATION_SIGNER_ADDRESS $CELO_VALIDATOR_ADDRESS

and subsequently exporting – to the Accounts node – the Attestation Signer address as well as signature:

# On the Accounts machine
export CELO_ATTESTATION_SIGNER_SIGNATURE=<YOUR_CELO_ATTESTATION_SIGNER_SIGNATURE><your_celo_attestation_signer_signature></your_celo_attestation_signer_signature></your_celo_attestation_signer_address>

to there authorize the Attestation Signer for its role as attestator:

# On the Accounts machine
celocli account:authorize --from $CELO_VALIDATOR_ADDRESS --role attestation --signature $CELO_ATTESTATION_SIGNER_SIGNATURE --signer $CELO_ATTESTATION_SIGNER_ADDRESS

Back on the Attestation machine and in preparation of running the celo-attestation container, we experienced what essentially was the only hiccup during the Attestation node setup.
Since the container does not accept interactive password input, we wrote the Attestation Signer password we had already created to generate the account to .password:

# On the Attestation machine
echo <YOUR_CELO_ATTESTATION_SIGNER_PASSWORD><your_celo_attestation_signer_password> > .password</your_celo_attestation_signer_password>

and tried to start the container we had equipped with the --baklava flag:

# On the Attestation machine
docker run --name celo-attestations -it --restart always -p -v $PWD:/root/.celo $CELO_IMAGE --verbosity 3 --syncmode full --rpc --rpcaddr --rpcapi eth,net,web3,debug,admin --unlock $CELO_ATTESTATION_SIGNER_ADDRESS --password /root/.celo/.password --allow-insecure-unlock --baklava

only to be greeted with “no key for given address or file”.
Irritated by the error message that was issued despite the fact the Attestation Signer key had been correctly created and stored in ./keystore, we found out that during the attempted container initialization a baklava subdirectory had been created and as the Discord history confirmed, the command therefore was looking for the key in ./baklava/keystore instead, where consequently we copied the keystore to:

# On the Attestation machine
cp -r ./keystore baklava

and then expectedly could run the container without problems.
We subsequently decided to use postgres:

# On the Attestation machine
apt install postgresql

generated a password (see Accounts node setup) and created a database with an individual user:

# On the Attestation machine
su - postgres
createuser --superuser <YOUR_POSTGRES_USER><your_postgres_user>
createdb -O <your_postgres_user><YOUR_POSTGRES_USER> attestation-service
psql -c "ALTER USER <YOUR_POSTGRES_USER><your_postgres_user> PASSWORD '<YOUR_POSTGRES_PASSWORD><your_postgres_password>';"</your_postgres_password></your_postgres_user></your_postgres_user></your_postgres_user>

that we fed into the variables:

# On the Attestation machine
export DATABASE_URL="postgres://<your_postgres_user><your_postgres_user><YOUR_POSTGRES_USER></your_postgres_user></your_postgres_user><your_postgres_user>:<YOUR_POSTGRES_PASSWORD><your_postgres_password>@localhost:5432/attestation-service"</your_postgres_password></your_postgres_user>

before selecting a location for the Attestation Service config and setting its variable:

# On the Attestation machine
export CONFIG=/root/celo-attestations-node/config

as well as fetching its defaults from GitHub:

# On the Attestation machine
curl > $CONFIG

Our dual SMS provider setup asked for only a few basic entries:

Required options:

CELO_VALIDATOR_ADDRESS=<span style="font-weight: 400;"><YOUR_VALIDATOR_ADDRESS></span><your_validator_address>
CELO_ATTESTATION_SIGNER_ADDRESS=<span style="font-weight: 400;"><YOUR_ATTESTATION_SIGNER_ADDRESS></span><your_attestation_signer_address>

Nexmo configuration options:
NEXMO_KEY=<span style="font-weight: 400;"><YOUR_NEXMO_KEY></span><your_nexmo_key>
NEXMO_SECRET=<span style="font-weight: 400;"><YOUR_NEXMO_SECRET></span><your_nexmo_secret>

Twilio configuration options:
TWILIO_ACCOUNT_SID=<span style="font-weight: 400;"><YOUR_TWILIO_ACCOUNT_SID></span><your_twilio_account_sid>
TWILIO_MESSAGING_SERVICE_SID=<span style="font-weight: 400;"><YOUR_TWILIO_MESSAGING_SERVICE_SID></span><your_twilio_messaging_service_sid>
TWILIO_AUTH_TOKEN=<span style="font-weight: 400;"><YOUR_TWILIO_AUTH_TOKEN></span><your_twilio_auth_token></your_twilio_auth_token></your_twilio_messaging_service_sid></your_twilio_account_sid></your_nexmo_secret></your_nexmo_key></your_attestation_signer_address></your_validator_address></your_postgres_password></your_postgres_user>

so – on the Accounts node – we could focus on defining our Attestation Service URL:

# On the Accounts machine
export CELO_ATTESTATION_SERVICE_URL=<span style="font-weight: 400;"><YOUR_ATTESTATION_SERVICE_URL></span><your_attestation_service_url></your_attestation_service_url>

and eventually claim it:

# On the Accounts machine
celocli account:claim-attestation-service-url ./metadata.json --url $CELO_ATTESTATION_SERVICE_URL --from $CELO_VALIDATOR_VOTE_SIGNER_ADDRESS

Please pay attention to two things though:
First of all, if you want to claim a HTTP instead of a HTTPS URL, you need to add the --force flag to your command. Secondly, in order to be able to claim the URL using the Accounts node without first having to move the credentials of the Attestation Signer account from the Attestation to the Accounts node, we changed --from $CELO_ATTESTATION_SIGNER_ADDRESS to --from $CELO_VALIDATOR_VOTE_SIGNER_ADDRESS.

From here on we continued by creating the metadata of both the Validator:

# On the Accounts machine
celocli account:create-metadata ./metadata.json --from $CELO_VALIDATOR_ADDRESS

and Validator Group:

# On the Accounts machine
celocli account:create-metadata ./group-metadata.json --from $CELO_VALIDATOR_GROUP_ADDRESS

as well as claimed both the Validator:

# On the Accounts machine
celocli account:claim-account ./group-metadata.json --address $CELO_VALIDATOR_ADDRESS --from $CELO_VALIDATOR_GROUP_ADDRESS

and Validator Group address:

# On the Accounts machine
celocli account:claim-account ./metadata.json --address $CELO_VALIDATOR_GROUP_ADDRESS --from $CELO_VALIDATOR_ADDRESS

before hosting (e.g. on Github) and registering both our metadata:

# On the Accounts machine
celocli account:register-metadata --url <your_metadata_url> --from $CELO_VALIDATOR_ADDRESS</your_metadata_url>

and group-metadata:

# On the Accounts machine
celocli account:register-metadata --url <your_group_metadata_url> --from $CELO_VALIDATOR_GROUP_ADDRESS</your_group_metadata_url>

the success of which we verified with:

# On the Accounts machine
celocli account:get-metadata $CELO_VALIDATOR_ADDRESS

The moment all our nodes were fully synced with baklava, we – on the Attestation node – set up the TAG variable:

# On the Attestation machine
export TAG=attestation-service-baklava

as well as did run the celo-attestation-service container:

# On the Attestation machine
docker run --name celo-attestation-service -it --restart always --entrypoint /bin/bash --network host --env-file $CONFIG -e PORT=80 -p 80:80$TAG -c " cd /celo-monorepo/packages/attestation-service && yarn run db:migrate && yarn start "

Aaaaand that was it!
Not only the Attestation Service, but the entire Validator setup had been completed.
To confirm everything is working properly, you can now send yourself a SMS and upon its retrieval, celebrate 🙂

# On the Accounts machine
celocli identity:test-attestation-service --from $CELO_VALIDATOR_ADDRESS --phoneNumber <your_phone_number_e164_format> --message conCELOations!!!</your_phone_number_e164_format>

Final words

If you have read up to this point, we would first like to thank you for your attention and furthermore hope that even though documentation type texts are seldom a pleasure to read, it at least was relatively easy to follow. As the faucet funds approach seems somewhat unusual, we hope that by giving an insight into our experience and sharing our setup sequence, we could provide the Celo community with another source of information, just in case something does not go as planned with someone’s Validator setup.
If any of our descriptions is incorrect or incomplete, and of course even more so if there is no urgent reason at all but you simply want to exchange ideas, we would be very happy to hear from you.

Interested or questions?


Freddy Zwanzger
(Co-Founder & Chief Data Officer)
+49 6131 3272372


Looking to create an Anyblock account?

Takes seconds and it's free!

Recent Posts

Anyblock Multi-Chain REST API for RPC & Data

Anyblock Multi-Chain REST API for RPC & Data

Anyblock REST API endpoints for RPC & data are a fast and reliable solution, which is available for more than 20 blockchains and does not require running your own node. You can view the list and description of all our endpoints in the Anyblock REST API docs.

In this article, you will find general information on Anyblock API and examples showing how to interact with it.

November Twitter Summary

November Twitter Summary

Hey there, developers! Anyblock Twitter Summary for the month of November is here.  Read it here or check out our Twitter account.Enjoy it!  Or just follow us directly if it's easier for you. Happy tweet-reading! :)? Most people believe they need to operate a...

This is the beginning of a new chapter…

This is the beginning of a new chapter…

We are super excited to announce that Anyblock Analytics GmbH will be spearheading the expansion of Blockdaemon Inc. in Germany! The corresponding contracts have been signed last week and closing is expected shortly as well.

Pin It on Pinterest