Add scripts and readme to deploy and verify terra contracts
This commit is contained in:
parent
879670c0e5
commit
e1f4b8e10b
|
@ -11,3 +11,6 @@ venv
|
||||||
bigtable-admin.json
|
bigtable-admin.json
|
||||||
bigtable-writer.json
|
bigtable-writer.json
|
||||||
**/cert.pem
|
**/cert.pem
|
||||||
|
**/payer-mainnet.json
|
||||||
|
**/payer-testnet.json
|
||||||
|
**/payer-devnet.json
|
||||||
|
|
|
@ -0,0 +1,15 @@
|
||||||
|
## This help screen
|
||||||
|
help:
|
||||||
|
@printf "Available targets:\n\n"
|
||||||
|
@awk '/^[a-zA-Z\-\_0-9%:\\]+/ { \
|
||||||
|
helpMessage = match(lastLine, /^## (.*)/); \
|
||||||
|
if (helpMessage) { \
|
||||||
|
helpCommand = $$1; \
|
||||||
|
helpMessage = substr(lastLine, RSTART + 3, RLENGTH); \
|
||||||
|
gsub("\\\\", "", helpCommand); \
|
||||||
|
gsub(":+$$", "", helpCommand); \
|
||||||
|
printf " \x1b[32;01m%-35s\x1b[0m %s\n", helpCommand, helpMessage; \
|
||||||
|
} \
|
||||||
|
} \
|
||||||
|
{ lastLine = $$0 }' $(MAKEFILE_LIST)
|
||||||
|
@printf "\n"
|
|
@ -1,5 +1,7 @@
|
||||||
# This is a multi-stage docker file, first stage builds contracts
|
# This is a multi-stage docker file:
|
||||||
# And the second one creates node.js environment to deploy them
|
# 1. The first stage builds the contracts
|
||||||
|
# 2. The second is an empty image with only the wasm files (useful for exporting)
|
||||||
|
# 3. The third creates a node.js environment to deploy the contracts to devnet
|
||||||
FROM cosmwasm/workspace-optimizer:0.12.1@sha256:1508cf7545f4b656ecafa34e29c1acf200cdab47fced85c2bc076c0c158b1338 AS builder
|
FROM cosmwasm/workspace-optimizer:0.12.1@sha256:1508cf7545f4b656ecafa34e29c1acf200cdab47fced85c2bc076c0c158b1338 AS builder
|
||||||
COPY Cargo.lock /code/
|
COPY Cargo.lock /code/
|
||||||
COPY Cargo.toml /code/
|
COPY Cargo.toml /code/
|
||||||
|
@ -13,6 +15,9 @@ RUN if [ -e /certs/cert.pem ]; then cp /certs/cert.pem /etc/ssl/cert.pem; fi
|
||||||
|
|
||||||
RUN optimize_workspace.sh
|
RUN optimize_workspace.sh
|
||||||
|
|
||||||
|
FROM scratch as artifacts
|
||||||
|
COPY --from=builder /code/artifacts /
|
||||||
|
|
||||||
# Contract deployment stage
|
# Contract deployment stage
|
||||||
FROM node:16-buster-slim@sha256:93c9fc3550f5f7d159f282027228e90e3a7f8bf38544758024f005e82607f546
|
FROM node:16-buster-slim@sha256:93c9fc3550f5f7d159f282027228e90e3a7f8bf38544758024f005e82607f546
|
||||||
|
|
||||||
|
@ -28,7 +33,7 @@ RUN apt update && apt install netcat curl jq -y
|
||||||
|
|
||||||
WORKDIR /app/tools
|
WORKDIR /app/tools
|
||||||
|
|
||||||
COPY --from=builder /code/artifacts /app/artifacts
|
COPY --from=artifacts / /app/artifacts
|
||||||
COPY ./artifacts/cw20_base.wasm /app/artifacts/
|
COPY ./artifacts/cw20_base.wasm /app/artifacts/
|
||||||
|
|
||||||
COPY ./tools/package.json ./tools/package-lock.json /app/tools/
|
COPY ./tools/package.json ./tools/package-lock.json /app/tools/
|
||||||
|
|
|
@ -1,11 +0,0 @@
|
||||||
# Run with:
|
|
||||||
# docker build -f Dockerfile.build -o artifacts .
|
|
||||||
FROM cosmwasm/workspace-optimizer:0.12.1@sha256:1508cf7545f4b656ecafa34e29c1acf200cdab47fced85c2bc076c0c158b1338 AS builder
|
|
||||||
ADD Cargo.lock /code/
|
|
||||||
ADD Cargo.toml /code/
|
|
||||||
ADD contracts /code/contracts
|
|
||||||
ADD packages /code/packages
|
|
||||||
RUN optimize_workspace.sh
|
|
||||||
|
|
||||||
FROM scratch AS export-stage
|
|
||||||
COPY --from=builder /code/artifacts /
|
|
|
@ -0,0 +1,59 @@
|
||||||
|
bridge_SOURCE=wormhole
|
||||||
|
token_bridge_SOURCE=token_bridge
|
||||||
|
nft_bridge_SOURCE=nft_bridge
|
||||||
|
|
||||||
|
SOURCE_FILES=$(shell find . -name "*.rs" -or -name "*.lock" -or -name "*.toml" | grep -v target)
|
||||||
|
|
||||||
|
PACKAGES=$(shell find . -name "Cargo.toml" | grep -E 'packages|contracts' | cut -d/ -f3 | sed s/-/_/g)
|
||||||
|
WASMS=$(patsubst %, artifacts/%.wasm, $(PACKAGES))
|
||||||
|
|
||||||
|
-include ../Makefile.help
|
||||||
|
|
||||||
|
.PHONY: artifacts
|
||||||
|
## Build contracts.
|
||||||
|
artifacts: artifacts/checksums.txt
|
||||||
|
|
||||||
|
VALID_mainnet=1
|
||||||
|
VALID_testnet=1
|
||||||
|
VALID_devnet=1
|
||||||
|
.PHONY: check-network
|
||||||
|
check-network:
|
||||||
|
ifndef VALID_$(NETWORK)
|
||||||
|
$(error Invalid or missing NETWORK. Please call with `$(MAKE) $(MAKECMDGOALS) NETWORK=[mainnet | testnet | devnet]`)
|
||||||
|
endif
|
||||||
|
|
||||||
|
$(WASMS) artifacts/checksums.txt: $(SOURCE_FILES)
|
||||||
|
DOCKER_BUILDKIT=1 docker build --target artifacts -o artifacts .
|
||||||
|
|
||||||
|
payer-$(NETWORK).json:
|
||||||
|
$(error Missing private key in payer-$(NETWORK).json)
|
||||||
|
|
||||||
|
.PHONY: deploy/bridge
|
||||||
|
## Deploy core bridge
|
||||||
|
deploy/bridge: bridge-code-id-$(NETWORK).txt
|
||||||
|
|
||||||
|
.PHONY: deploy/token_bridge
|
||||||
|
## Deploy token bridge
|
||||||
|
deploy/token_bridge: token_bridge-code-id-$(NETWORK).txt
|
||||||
|
|
||||||
|
.PHONY: deploy/nft_bridge
|
||||||
|
## Deploy NFT bridge
|
||||||
|
deploy/nft_bridge: nft_bridge-code-id-$(NETWORK).txt
|
||||||
|
|
||||||
|
%-code-id-$(NETWORK).txt: check-network tools/node_modules payer-$(NETWORK).json
|
||||||
|
@echo "Deploying artifacts/$($*_SOURCE).wasm on $(NETWORK)"
|
||||||
|
@node tools/deploy_single.js \
|
||||||
|
--network $(NETWORK) \
|
||||||
|
--artifact artifacts/$($*_SOURCE).wasm \
|
||||||
|
--mnemonic "$$(cat payer-$(NETWORK).json)" \
|
||||||
|
| grep -i "code id" | sed s/[^0-9]//g \
|
||||||
|
> $@
|
||||||
|
@echo "Deployed at code id $$(cat $@) (stored in $@)"
|
||||||
|
|
||||||
|
tools/node_modules: tools/package-lock.json
|
||||||
|
cd tools && npm ci
|
||||||
|
|
||||||
|
.PHONY: clean
|
||||||
|
clean:
|
||||||
|
rm -f $(WASMS)
|
||||||
|
rm -f artifacts/checksums.txt
|
121
terra/README.md
121
terra/README.md
|
@ -1,45 +1,122 @@
|
||||||
# Deploy
|
# Terra Wormhole Contract Deployment
|
||||||
|
|
||||||
First build the contracts
|
This readme describes the steps for building, verifying, and deploying Terra smart contracts for Wormhole.
|
||||||
|
|
||||||
|
**WARNING**: *This process is only Linux host compatible at this time.*
|
||||||
|
|
||||||
``` sh
|
## Verify Tilt
|
||||||
docker build -f Dockerfile.build -o artifacts .
|
|
||||||
|
Before building Terra contracts, ensure that the specific commit you will be
|
||||||
|
building from passes in tilt. This that ensures basic functionality of the
|
||||||
|
Terra smart contracts that you are about to build and deploy.
|
||||||
|
|
||||||
|
## Build Contracts
|
||||||
|
|
||||||
|
The following command can be used to build Terra contracts via Docker.
|
||||||
|
|
||||||
|
Build Target Options: [`mainnet`|`testnet`|`devnet`|
|
||||||
|
|
||||||
|
These network names correspond to the naming convention used by wormhole
|
||||||
|
elsewhere. This means that `mainnet` corresponds to Terra `mainnet`,
|
||||||
|
`testnet` corresponds to Terra `testnet`, and `devnet` is `localterra`.
|
||||||
|
|
||||||
|
```console
|
||||||
|
wormhole/terra $ make artifacts
|
||||||
```
|
```
|
||||||
|
|
||||||
Then, for example, to deploy `token_bridge.wasm`, run in the `tools` directory
|
Upon completion, the compiled bytecode for the Terra contracts will be placed
|
||||||
|
into the `artifacts` directory.
|
||||||
|
|
||||||
``` sh
|
## Verify Checksums
|
||||||
npm ci
|
|
||||||
node deploy_single.js --network mainnet --artifact ../artifacts/token_bridge.wasm --mnemonic "..."
|
Now that you have built the Terra contracts, you should ask a peer to build
|
||||||
|
using the same process and compare the equivalent checksums.txt files to make
|
||||||
|
sure the contract bytecode(s) are deterministic.
|
||||||
|
|
||||||
|
```console
|
||||||
|
wormhole/terra $ cat artifacts/checksums.txt
|
||||||
```
|
```
|
||||||
|
|
||||||
which will print something along the lines of
|
Once you have verified the Terra contracts are deterministic with a peer, you can now move to the deploy step.
|
||||||
|
|
||||||
``` sh
|
## Deploy Contracts
|
||||||
Storing WASM: ../artifacts/token_bridge.wasm (367689 bytes)
|
|
||||||
Deploy fee: 88446uluna
|
Now that you have built and verified checksums, you can now deploy one or more relevant contracts to the Terra blockchain.
|
||||||
Code ID: 2435
|
|
||||||
|
Deploy Target Options: [`mainnet`|`testnet`|`devnet`]
|
||||||
|
|
||||||
|
You will need to define a `payer-DEPLOY_TARGET.json` for the relevant deploy
|
||||||
|
target (eg. `payer-testnet.json`). This will contain the relevant wallet
|
||||||
|
private key that you will be using to deploy the contracts.
|
||||||
|
|
||||||
|
```console
|
||||||
|
wormhole/terra $ make deploy/bridge
|
||||||
|
wormhole/terra $ make deploy/token_bridge
|
||||||
|
wormhole/terra $ make deploy/nft_bridge
|
||||||
```
|
```
|
||||||
|
|
||||||
# Migrate
|
For each deployed contract, you will get a code id for that relevant
|
||||||
|
contract for the deployment, make note of these so you can use them in
|
||||||
|
the next step for on-chain verification.
|
||||||
|
|
||||||
## Mainnet
|
## Verify On-Chain
|
||||||
|
|
||||||
Migrations on mainnet have to go through governance. Once the guardians sign the
|
Now that you have deployed one or more contracts on-chain, you can verify the
|
||||||
upgrade VAA, the contract can be upgraded by submitting the signed VAA to the
|
onchain bytecode and make sure it matches the same checksums you identified
|
||||||
appropriate contract. For example, to upgrade the token bridge on mainnet,
|
above.
|
||||||
in `wormhole/clients/token_bridge/`:
|
|
||||||
|
For each contract you wish to verify on-chain, you will need the following elements:
|
||||||
|
|
||||||
|
- Path to the contracts bytecode (eg. `artifacts-testnet/token_bridge.wasm`)
|
||||||
|
- Terra code id for the relevant contract (eg. `59614`)
|
||||||
|
- A network to verify on (`mainnet`, `testnet`, or `devnet`)
|
||||||
|
|
||||||
|
Below is how to verify all three contracts:
|
||||||
|
|
||||||
|
```console
|
||||||
|
wormhole/terra $ ./verify artifacts/wormhole.wasm NEW_BRIDGE_CODE_ID
|
||||||
|
wormhole/terra $ ./verify artifacts/token_bridge.wasm NEW_TOKEN_BRIDGE_CODE_ID
|
||||||
|
wormhole/terra $ ./verify artifacts/nft_bridge.wasm NEW_NFT_BRIDGE_CODE_ID
|
||||||
|
```
|
||||||
|
Example: `./verify artifacts/token_bridge.wasm 59614`
|
||||||
|
|
||||||
|
For each contract, you should expect a `Successfully verified` output message.
|
||||||
|
If all contracts can be successfully verified, you can engage in Wormhole
|
||||||
|
protocol governance to obtain an authorized VAA for the contract upgrade(s).
|
||||||
|
|
||||||
|
A verification failure should never happen, and is a sign of some error in the
|
||||||
|
deployment process. Do not proceed with governance until you can verify the
|
||||||
|
on-chain bytecode with the locally compiled bytecode.
|
||||||
|
|
||||||
|
|
||||||
|
## Governance
|
||||||
|
|
||||||
|
### Mainnet
|
||||||
|
|
||||||
|
Upgrades on mainnet have to go through governance. Once the code is deployed in
|
||||||
|
the previous step, an unsigned governance VAA can be generated
|
||||||
|
|
||||||
|
```sh
|
||||||
|
./generate_governance -m token_bridge -c 59614 > token-bridge-upgrade-59614.prototxt
|
||||||
|
```
|
||||||
|
|
||||||
|
This will write to the `token-bridge-upgrade-59614.prototxt` file, which can
|
||||||
|
now be shared with the guardians to vote on.
|
||||||
|
|
||||||
|
Once the guardians have reached quorum, the VAA may be submitted from any
|
||||||
|
funded wallet: TODO - make this easier and more unified
|
||||||
|
|
||||||
``` sh
|
``` sh
|
||||||
node main.js terra execute_governance_vaa <signed VAA (hex)> --rpc "https://lcd.terra.dev" --chain_id "columbus-5" --mnemonic "..." --token_bridge "terra10nmmwe8r3g99a9newtqa7a75xfgs2e8z87r2sf"
|
node main.js terra execute_governance_vaa <signed VAA (hex)> --rpc "https://lcd.terra.dev" --chain_id "columbus-5" --mnemonic "..." --token_bridge "terra10nmmwe8r3g99a9newtqa7a75xfgs2e8z87r2sf"
|
||||||
```
|
```
|
||||||
|
|
||||||
## Testnet
|
### Testnet
|
||||||
|
|
||||||
|
For the contracts on testnet, the deployer wallet retains the upgrade
|
||||||
|
authority, so these don't have to go through governance.
|
||||||
|
|
||||||
For example, to migrate the token bridge to 37262, run in `tools/`:
|
For example, to migrate the token bridge to 59614, run in `tools/`:
|
||||||
|
|
||||||
``` sh
|
``` sh
|
||||||
node migrate_testnet.js --code_id 37262 --contract terra1pseddrv0yfsn76u4zxrjmtf45kdlmalswdv39a --mnemonic "..."
|
node migrate_testnet.js --code_id 59614 --contract terra1pseddrv0yfsn76u4zxrjmtf45kdlmalswdv39a --mnemonic "..."
|
||||||
```
|
```
|
||||||
|
|
|
@ -1,6 +0,0 @@
|
||||||
#!/usr/bin/env bash
|
|
||||||
|
|
||||||
docker run --rm -v "$(pwd)":/code \
|
|
||||||
--mount type=volume,source="$(basename "$(pwd)")_cache",target=/code/target \
|
|
||||||
--mount type=volume,source=registry_cache,target=/usr/local/cargo/registry \
|
|
||||||
cosmwasm/workspace-optimizer:0.12.1
|
|
|
@ -0,0 +1,69 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
usage="Usage:
|
||||||
|
$(basename "$0") [-h] [-m s] [-c n] -- Generate governance prototxt for a given module to be upgraded to a given code id
|
||||||
|
|
||||||
|
where:
|
||||||
|
-h show this help text
|
||||||
|
-m module (bridge, token_bridge, nft_bridge)
|
||||||
|
-c code id (e.g. 4018)"
|
||||||
|
|
||||||
|
code_id=""
|
||||||
|
module=""
|
||||||
|
while getopts ':hm:c:' option; do
|
||||||
|
case "$option" in
|
||||||
|
h) echo "$usage"
|
||||||
|
exit
|
||||||
|
;;
|
||||||
|
m) module=$OPTARG
|
||||||
|
;;
|
||||||
|
c) code_id=$OPTARG
|
||||||
|
;;
|
||||||
|
:) printf "missing argument for -%s\n" "$OPTARG" >&2
|
||||||
|
echo "$usage" >&2
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
\?) printf "illegal option: -%s\n" "$OPTARG" >&2
|
||||||
|
echo "$usage" >&2
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
shift $((OPTIND - 1))
|
||||||
|
|
||||||
|
[ -z "$code_id" ] && { echo "$usage" >&2; exit 1; }
|
||||||
|
[ -z "$module" ] && { echo "$usage" >&2; exit 1; }
|
||||||
|
|
||||||
|
address=$(printf "%064x" "$code_id")
|
||||||
|
TERRA_ID=3
|
||||||
|
GUARDIAND=guardiand
|
||||||
|
|
||||||
|
case "$module" in
|
||||||
|
bridge)
|
||||||
|
"$GUARDIAND" template contract-upgrade \
|
||||||
|
--chain-id $TERRA_ID \
|
||||||
|
--new-address "$address" \
|
||||||
|
> /tmp/gov.prototxt
|
||||||
|
;;
|
||||||
|
token_bridge)
|
||||||
|
"$GUARDIAND" template token-bridge-upgrade-contract \
|
||||||
|
--chain-id $TERRA_ID --module "TokenBridge" \
|
||||||
|
--new-address "$address" \
|
||||||
|
> /tmp/gov.prototxt
|
||||||
|
;;
|
||||||
|
nft_bridge)
|
||||||
|
"$GUARDIAND" template token-bridge-upgrade-contract \
|
||||||
|
--chain-id $TERRA_ID --module "NFTBridge" \
|
||||||
|
--new-address "$address" \
|
||||||
|
> /tmp/gov.prototxt
|
||||||
|
;;
|
||||||
|
*) echo "illegal module $module"
|
||||||
|
echo "$usage" >&2
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
cat /tmp/gov.prototxt
|
||||||
|
"$GUARDIAND" admin governance-vaa-verify /tmp/gov.prototxt >&2
|
|
@ -0,0 +1,63 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
usage="Usage:
|
||||||
|
$(basename "$0") [-h] [-n network] <.wasm file> <code id> -- Verify that the deployed on-chain bytecode matches the local object file
|
||||||
|
|
||||||
|
where:
|
||||||
|
-h show this help text
|
||||||
|
-n set the network (mainnet, testnet, devnet. defaults to \$NETWORK if set)"
|
||||||
|
|
||||||
|
network=$NETWORK
|
||||||
|
while getopts ':hn:' option; do
|
||||||
|
case "$option" in
|
||||||
|
h) echo "$usage"
|
||||||
|
exit
|
||||||
|
;;
|
||||||
|
n) network=$OPTARG
|
||||||
|
;;
|
||||||
|
:) printf "missing argument for -%s\n" "$OPTARG" >&2
|
||||||
|
echo "$usage" >&2
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
\?) printf "illegal option: -%s\n" "$OPTARG" >&2
|
||||||
|
echo "$usage" >&2
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
shift $((OPTIND - 1))
|
||||||
|
|
||||||
|
|
||||||
|
case "$network" in
|
||||||
|
mainnet) url="https://lcd.terra.dev";;
|
||||||
|
testnet) url="https://bombay-lcd.terra.dev";;
|
||||||
|
devnet) url="http://localhost:1317";;
|
||||||
|
*) printf "Network not set. Specify with -n\n" >&2
|
||||||
|
echo "$usage" >&2
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
[ $# -ne 2 ] && { echo "$usage" >&2; exit 1; }
|
||||||
|
obj_file=$1
|
||||||
|
code_id=$2
|
||||||
|
|
||||||
|
|
||||||
|
hash1=`curl "$url"/terra/wasm/v1beta1/codes/"$code_id" --silent | jq '.code_info.code_hash' -r | base64 -d | hexdump -v -e '/1 "%02x" '`
|
||||||
|
hash2=`sha256sum $obj_file | cut -f1 -d' '`
|
||||||
|
|
||||||
|
echo "Deployed bytecode hash (on $network):"
|
||||||
|
echo $hash1
|
||||||
|
echo "$obj_file hash:"
|
||||||
|
echo $hash2
|
||||||
|
|
||||||
|
if [ "$hash1" == "$hash2" ]; then
|
||||||
|
printf "\033[0;32mSuccessfully verified\033[0m\n";
|
||||||
|
exit 0;
|
||||||
|
else
|
||||||
|
printf "\033[0;31mFailed to verify\033[0m\n";
|
||||||
|
exit 1;
|
||||||
|
fi
|
||||||
|
|
Loading…
Reference in New Issue