This is the guide one should follow to setup a container with vault that can hold the mnemonic seed for the wallet that the contracts are deployed with.
git clone [email protected]:godsflaw/vault.git crucible-vault
cd crucible-vault
grep mlock config.hcl
Note that the config.hcl
file in this repo has a line for
disable_mlock = true
. This is because mlock requires that the container be
run in privileged mode. Some container hosting providers don't allow this.
If your provider allows this, then you should remove this line as it make the
vault more secure by preventing memory from getting swapped to disk. Otherwise
know that your vault is less secure, but that you won't get errors on providers
that don't allow privileged mode.
docker build -t godsflaw/vault:sealed .
docker run -p 8200:8200 godsflaw/vault:sealed
From yet another terminal, change directory into the crucible repo. We need to generate a mnemonic. All you need to do is run the following script and keep the resulting words in a safe palce. You can also use one you alreay have, but if this is for a staging environment, I would not use the same mnemonic you've used for any other sensitive project.
cd $CRUCIBLE_HOME
./scripts/create_mnemonic.js
This should generate something like: cupboard swallow cruel repeat female biology blood wrist people theory bicycle egg
. This is an example, and you
should not use this mnemonic. Save the newly generated mnemonic somewhere safe
or import it into your MetaMask wallet (or both). To import into MetaMask, you
will need the bx
tool and the private key derived from the mnemonic. You can
get the private key used for import by running:
echo "<MNEMONIC WORDS>" | \
bx mnemonic-to-seed | \
bx hd-new -v 76066276 | \
bx hd-private -d -i 44 | \
bx hd-private -d -i 60 | \
bx hd-private -d -i 0 | \
bx hd-private -i 0 | \
bx hd-private -i 0 | \
bx hd-to-ec
Again, keep private key result of this secret. For the example mnemonic above
this command would produce a private key of the format:
ad25c782f541b8866478ad1df4eb6bcf57c1ee9bb9a895aaa2acef169ad22f7c
From yet another terminal, you need to start a shell in the vault container.
docker ps
docker exec -it <CONTAINER ID> /bin/sh
export VAULT_ADDR=http://localhost:8200
vault init
Copy all 5 keys and the root key off to a safe place. Three of these keys are needed to unseal a sealed vault. It's best, in a production environment, that these keys are never held all in the same place. For staging, it is relatively harmless to put these three keys in a configuration file; however, DO NOT use the same mnemonic that you use for production or any other sensitive project.
back to terminal #2
add three of the vault keys (as UNSEAL_KEY1, UNSEAL_KEY2,
UNSEAL_KEY3) and the root token (as SEED_TOKEN) from vault init
to the
./env-staging
script. Run that and unseal the vault.
./scripts/plumb-env
vi env-staging
. ./env-staging
export VAULT_ADDR=http://localhost:8200
./scripts/vault_unseal.js
Use the mnemonic words we generated and saved earlier to be stored in the vault.
You also need to make a file named key
and put the ssh deploy key for the
crucible repo in it.
You must run vault auth
and provide the root token.
vi ./key
vault auth
vault write secret/network/staging/seed key="<MNEMONIC WORDS>"
cat ./key | vault write secret/network/staging/deploykey key=-
rm ./key
vault seal
The last command sealed the vault. Next we will attempt to unseal it again.
Now that your environment has all the variables needed to think it is staging,
and unseal the vault. At this point, you can run the unseal script
(./scripts/vault_unseal.js
) and the script to extract the nmemonic
(./scripts/vault_get_mnemonic.js
) to make sure our vault container works as
expected.
./scripts/vault_unseal.js
./scripts/vault_get_mnemonic.js
./scripts/vault_get_deploy_key.js
In terminal #1
you should see log messages.
Since your shell history in the container contains the mnemonic, we want to clean it up with the following commands:
vault seal
cat /dev/null > ~/.bash_history
cat /dev/null > ~/.ash_history
exit
If you start a shell in the container again, you can confirm that exit
is the
only command in your history. You should now have a sealed vault container.
Now that we have a sealed vault container with a nmemonic and a clean shell history. We can snapshot this state and push the container to a hosted location.
docker ps
docker commit <CONTAINER ID> r.cfcr.io/godsflaw/vault:crucible-staging-sealed
docker push r.cfcr.io/godsflaw/vault:crucible-staging-sealed
To develop integration tests, you need only run npm run deploy && npm test
from your terminal
that has all the settings as though it is the staging environment.
npm test
NOTE: After you run tests, it will unseal the vault. You will need to re-seal
it or restart from the earlier commit. When you are finished you can exit out
of terminal #1
, and terminal #2
.
Under the RunningIntegrationTests
section, you will notice this sub-section:
composition:
version: '2'
services:
vault:
image: r.cfcr.io/godsflaw/vault:crucible-staging-sealed
This defines the vault service. When privileged mode was allowed on CodeFresh
there was an additional line below image that read privileged: true
. This
service can now be referenced as a dependancy in the composition_candidates
section. Where we also set the staging environment. The environment variables
in ./env-staging are also set in the crucible repository config on codefresh
for all but CRUCIBLE_ENV
.
composition_candidates:
test_service:
depends_on:
- vault
image: '${{BuildingDockerImage}}'
env_file: ./env-staging
command: sh -c 'npm run deploy && npm test'
-
Every now and then, integration tests will fail with something like
nonce too low
. This is becasue the address we use for the staging network is likely a pool of servers that are not all up-to-date on the last transaction. Click therestart
button in the codefresh build interface and this should retry the build, perhaps repairing the problem. Luckily, this only needs to happen when we push to the dev branch. -
To send your new wallet ETH on Rinkeby, you need to get the public key from MetaMask and follow the instructions at: https://www.rinkeby.io/#faucet