Wallet keymanagers

Deprecated

This wallet keymanager is now deprecated and no longer the recommended way to manage accounts in Prysm. Read wallet and accounts for the latest information and usage.

A wallet keymanager is a way of storing and accessing wallet keys on a local filesystem. The below guide outlines the configuration and operation of ethdo, a third-party software package that is used to perform several common tasks on Ethereum 2.0, including keystore functionality. It follows the Ethereum 2.0 specification and provides cross-client support (interoperability) as well as advanced features suitable for multi-node deployments.

IMPORTANT NOTICE: As Prysmatic Labs cannot endorse third party tools used to manage keys in a production environment, the guide on this page is no longer maintained and, if followed, there is a risk that your deposit will experience issues. It is highly recommended to compliment this guide with the latest ethdo installation and usage instructions found in this guide on Github.

Installing ethdo

  1. To install ethdo, issue the following command:
GO111MODULE=on go get github.com/wealdtech/ethdo@latest
  1. Ensure ethdo is installed properly by issuing the command:
ethdo version

Ensure the output matches the most recent version listed on the repository's release history.

Typical validating setups

This section outlines the process of setting up a configuration with two validators and a single withdrawal account using ethdo.

Generating a wallet

To create a non-deterministic wallet (keys generated from random data), issue the command:

ethdo wallet create --wallet=Validators

If you prefer to have a hierarchical deterministic wallet, where keys are generated from a seed, issue the command:

ethdo wallet create --wallet=Validators --type=hd --walletpassphrase=walletsecret`

This creates a wallet called "Validators" in your current directory which contains the newly generated seed data.

The --walletpassphrase flag and input is required to protect the seed. It is critical that you keep it private and secure.

Once the wallet is created, fetch its data to ensure it exists by issuing the following command:

ethdo wallet info --wallet=Validators

This command will produce output like so:

Type: non-deterministic
Accounts: 0

Generating multiple wallets

To create two separate wallets with different passphrases, issue the command:

ethdo account create --account=Validators/1 --passphrase=validator1secret
ethdo account create --account=Validators/2 --passphrase=validator2secret

The two validators are given different passphrases in the above example. This is not required but is recommended, as it will prevent both validators from being compromised should an attacker acquire the passphrase for one of them.

Creating a withdrawal wallet and account

It is recommended to set up separate wallets for withdrawals and validator nodes. This allows users to have a validator wallet actively running on the node, while a second wallet key can be kept securely offline in cold storage.

Creating a withdrawal wallet and account is very similar to the process above to generate validator accounts. For example:

ethdo wallet create --wallet=Withdrawal
ethdo account create --account=Withdrawal/Primary --passphrase=withdrawalsecret

This creates a wallet called "Withdrawal" and within it an account called "Primary". It is also possible to apply additional protection to the Withdrawal wallet if desired; see the ethdo documentation for details.

Depositing funds for a validator

The validator now requires deposited funds. If you do not have any Göerli Ether, the best approach is to follow the steps at https://prylabs.net/participate to use the faucet and make a deposit -- however, for step 3, do not run the commands provided. Instead, run the following command to generate the deposit data requested:

ethdo validator depositdata \
--validatoraccount=Validators/1 \
--withdrawalaccount=Withdrawal/Primary \
--depositvalue=32Ether \
--passphrase=validator1secret \
--raw

The raw data output of this command can be pasted in to the webpage above to generate the required transaction for validator 1 (and can be repeated for validator 2, or as many validators as you wish).

Alternatively, if you have your own Göerli ETH, you can send deposit transactions directly to the Göerli testnet. You can create JSON output containing the deposit data:

ethdo validator depositdata \
--validatoraccount=Validators/1 \
--withdrawalaccount=Withdrawal/Primary \
--depositvalue=32Ether \
--passphrase=validator1secret
{"account":"Validators/1","pubkey":"a9ca9cf7fa2d0ab1d5d52d2d8f79f68c50c5296bfce81546c254df68eaac0418717b2f9fc6655cbbddb145daeb282c00","withdrawal_credentials":"0059a28dc2db987d59bdfc4ab20b9ad4c83888bcd32456a629aece07de6895aa","signature":"9335b872253fdab328678bd3636115681d52b42fe826c6acb7f1cd1327c6bba48e3231d054e4f274cc7c1c184f28263b13083e01db8c08c17b59f22277dff341f7c96e7a0407a0a31c8563bcf479d31136c833712ae3bfd93ee9ea6abdfa52d4","value":3200000000,"deposit_data_root":"14278c9345eeeb7b2d5307a36ed1c72eea5ed09a30cf7c47525e34f39f564ef5"}

This can be passed to ethereal to send the deposit:

DEPOSITDATA=`ethdo validator depositdata \
--validatoraccount=Validators/1 \
--withdrawalaccount=Withdrawal/Primary \
--depositvalue=32Ether \
--passphrase=validator1secret`
ethereal beacon deposit \
--network=goerli \
--data="${DEPOSITDATA}" \
--from=0x21A1A52aba41DB18F9F1D2625e1b19A251F3e0A9 \
--passphrase=eth1secret

The ethereal command can either take a passphrase, if the from address is a local account (confirm with ethereal --network=goerli account list) or a privatekey if not.

Validating

The next step is to start the validator using the validating keys that have been created.

Keymanager options

Although options for the wallet keymanager can be supplied directly on the command-line this is not considered best practice, as it can expose sensitive information such as passphrases. It is better to create a file that contains this information and reference that file. For the purposes of this example we will create the keymanager options file at ${HOME}/prysm/validator/keymanager.json

To create the relevant directory run the following:

mkdir -p "${HOME}/prysm/validator"

and then use your favourite text editor to create a file in this directory called keymanager.json with the following contents:

{
"accounts": [
"Validators/1",
"Validators/2"
],
"passphrases": [
"validator1secret",
"validator2secret"
]
}

Starting the validator with Bazel

To start the validator you must supply the desired keymanager and the location of the keymanager options file. Run the following command:

bazel run //validator:validator -- --keymanager=wallet --keymanageropts="${HOME}/prysm/validator/keymanager.json"

The below commands use the ${HOME} environment variable, which is standard on GNU/Linux and macOS. For Windows users, replace it with %LOCALAPPDATA% e.g. %LOCALAPPDATA%\ethereum2\wallets. This may also require you to remove the double quotes around the keymanageropts value, especially on Windows.

Starting the validator with Docker

Docker will not have direct access to the wallet created above, and requires the keymanager to be informed of the mapped location of the wallet. Edit the keymanager.json file to include a location entry, as follows:

{
"location": "/wallets",
"accounts": [
"Validators/1",
"Validators/2"
],
"passphrases": [
"validator1secret",
"validator2secret"
]
}

Then run the validator by issuing the following command:

docker run -v "${HOME}/prysm/validator:/data" \
-v "${HOME}/.config/ethereum2/wallets:/wallets" \
gcr.io/prysmaticlabs/prysm/validator:latest \
--keymanager=wallet \
--keymanageropts=/data/keymanager.json

Confirming validation

When the validator is operational, you should see output similar to:

[2020-02-07 10:00:59] INFO node: Found validator keys validators=2
[2020-02-07 10:00:59] INFO node: Validating for public key pubKey=0x85016bd4ca67e57e1438308fdb3d98b74b81428fb09e6d16d2dcbc72f240be090d5faebb63f84d6f35a950fdbb36f910
[2020-02-07 10:00:59] INFO node: Validating for public key pubKey=0x8de04b4cd3f0947f4e76fa2f86fa1cfd33cc2500688f2757e406448c36f0f1255758874b46d72002ad206ed560975d39

The first line states how many keys the validator is validating with, and subsequent lines state the specific public keys. Confirm that these values match your expectations.

Migrating keys from keystore

To migrate keys from the keystore keymanager, extract the private keys and then import them into a wallet.

Extracting private keys from keystore

To extract the private keys you must run the validator accounts keys command with the path and passphrase for the local keystore.

Extracting with Bazel

Issue the following command:

bazel run //validator:validator -- accounts keys --keystore-path="${HOME}/.eth2validators" --password=secret

Extracting with Docker

Issue the following command:

docker run -v "${HOME}/prysm/validator:/data" \
-v "${HOME}/.eth2validators:/validators" \
gcr.io/prysmaticlabs/prysm/validator:latest \
accounts keys \
--keystore-path=/validators \
--password=secret

Importing private keys to wallet

The output from the prior extraction piece should include lines similar to:

Public key: 0xa551e2558c839162b5df961ceb27cd10e9cf711ac15ff7866143cbf6df5fe523e5c3c91fdfa95f47e20b9499ee5766fc private key: 0x3e89ad55d05fa8e412045c4187417e6a480a82203bd85779e673a43761dcbcb1

You want to use the information after private key. Each private key can be imported using the command:

ethdo account import --account=Validators/newname --passphrase=newvalidatorsecret --key=0x3e89ad55d05fa8e412045c4187417e6a480a82203bd85779e673a43761dcbcb1

You will need a different account for each new account you add. For example, repeating these steps could add another named Validators/3, then Validators/4 and so on. It is recommended to set the passphrase accordingly.

Exiting a validator

To exit a validator, run the following command:

ethdo validator exit --account=Validators/1 --passphrase=validator1secret

NOTICE: This assumes you have a beacon chain node running locally with gRPC on port 4000. If the beacon chain node is elsewhere use the --connection option to allow ethdo to connect to it.