Skip to content

Commit e1f4b8e

Browse files
Csongor Kisskcsongor
Csongor Kiss
authored andcommitted
Add scripts and readme to deploy and verify terra contracts
1 parent 879670c commit e1f4b8e

9 files changed

+316
-42
lines changed

.gitignore

+3
Original file line numberDiff line numberDiff line change
@@ -11,3 +11,6 @@ venv
1111
bigtable-admin.json
1212
bigtable-writer.json
1313
**/cert.pem
14+
**/payer-mainnet.json
15+
**/payer-testnet.json
16+
**/payer-devnet.json

Makefile.help

+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
## This help screen
2+
help:
3+
@printf "Available targets:\n\n"
4+
@awk '/^[a-zA-Z\-\_0-9%:\\]+/ { \
5+
helpMessage = match(lastLine, /^## (.*)/); \
6+
if (helpMessage) { \
7+
helpCommand = $$1; \
8+
helpMessage = substr(lastLine, RSTART + 3, RLENGTH); \
9+
gsub("\\\\", "", helpCommand); \
10+
gsub(":+$$", "", helpCommand); \
11+
printf " \x1b[32;01m%-35s\x1b[0m %s\n", helpCommand, helpMessage; \
12+
} \
13+
} \
14+
{ lastLine = $$0 }' $(MAKEFILE_LIST)
15+
@printf "\n"

terra/Dockerfile

+8-3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
1-
# This is a multi-stage docker file, first stage builds contracts
2-
# And the second one creates node.js environment to deploy them
1+
# This is a multi-stage docker file:
2+
# 1. The first stage builds the contracts
3+
# 2. The second is an empty image with only the wasm files (useful for exporting)
4+
# 3. The third creates a node.js environment to deploy the contracts to devnet
35
FROM cosmwasm/workspace-optimizer:0.12.1@sha256:1508cf7545f4b656ecafa34e29c1acf200cdab47fced85c2bc076c0c158b1338 AS builder
46
COPY Cargo.lock /code/
57
COPY Cargo.toml /code/
@@ -13,6 +15,9 @@ RUN if [ -e /certs/cert.pem ]; then cp /certs/cert.pem /etc/ssl/cert.pem; fi
1315

1416
RUN optimize_workspace.sh
1517

18+
FROM scratch as artifacts
19+
COPY --from=builder /code/artifacts /
20+
1621
# Contract deployment stage
1722
FROM node:16-buster-slim@sha256:93c9fc3550f5f7d159f282027228e90e3a7f8bf38544758024f005e82607f546
1823

@@ -28,7 +33,7 @@ RUN apt update && apt install netcat curl jq -y
2833

2934
WORKDIR /app/tools
3035

31-
COPY --from=builder /code/artifacts /app/artifacts
36+
COPY --from=artifacts / /app/artifacts
3237
COPY ./artifacts/cw20_base.wasm /app/artifacts/
3338

3439
COPY ./tools/package.json ./tools/package-lock.json /app/tools/

terra/Dockerfile.build

-11
This file was deleted.

terra/Makefile

+59
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
bridge_SOURCE=wormhole
2+
token_bridge_SOURCE=token_bridge
3+
nft_bridge_SOURCE=nft_bridge
4+
5+
SOURCE_FILES=$(shell find . -name "*.rs" -or -name "*.lock" -or -name "*.toml" | grep -v target)
6+
7+
PACKAGES=$(shell find . -name "Cargo.toml" | grep -E 'packages|contracts' | cut -d/ -f3 | sed s/-/_/g)
8+
WASMS=$(patsubst %, artifacts/%.wasm, $(PACKAGES))
9+
10+
-include ../Makefile.help
11+
12+
.PHONY: artifacts
13+
## Build contracts.
14+
artifacts: artifacts/checksums.txt
15+
16+
VALID_mainnet=1
17+
VALID_testnet=1
18+
VALID_devnet=1
19+
.PHONY: check-network
20+
check-network:
21+
ifndef VALID_$(NETWORK)
22+
$(error Invalid or missing NETWORK. Please call with `$(MAKE) $(MAKECMDGOALS) NETWORK=[mainnet | testnet | devnet]`)
23+
endif
24+
25+
$(WASMS) artifacts/checksums.txt: $(SOURCE_FILES)
26+
DOCKER_BUILDKIT=1 docker build --target artifacts -o artifacts .
27+
28+
payer-$(NETWORK).json:
29+
$(error Missing private key in payer-$(NETWORK).json)
30+
31+
.PHONY: deploy/bridge
32+
## Deploy core bridge
33+
deploy/bridge: bridge-code-id-$(NETWORK).txt
34+
35+
.PHONY: deploy/token_bridge
36+
## Deploy token bridge
37+
deploy/token_bridge: token_bridge-code-id-$(NETWORK).txt
38+
39+
.PHONY: deploy/nft_bridge
40+
## Deploy NFT bridge
41+
deploy/nft_bridge: nft_bridge-code-id-$(NETWORK).txt
42+
43+
%-code-id-$(NETWORK).txt: check-network tools/node_modules payer-$(NETWORK).json
44+
@echo "Deploying artifacts/$($*_SOURCE).wasm on $(NETWORK)"
45+
@node tools/deploy_single.js \
46+
--network $(NETWORK) \
47+
--artifact artifacts/$($*_SOURCE).wasm \
48+
--mnemonic "$$(cat payer-$(NETWORK).json)" \
49+
| grep -i "code id" | sed s/[^0-9]//g \
50+
> $@
51+
@echo "Deployed at code id $$(cat $@) (stored in $@)"
52+
53+
tools/node_modules: tools/package-lock.json
54+
cd tools && npm ci
55+
56+
.PHONY: clean
57+
clean:
58+
rm -f $(WASMS)
59+
rm -f artifacts/checksums.txt

terra/README.md

+99-22
Original file line numberDiff line numberDiff line change
@@ -1,45 +1,122 @@
1-
# Deploy
1+
# Terra Wormhole Contract Deployment
22

3-
First build the contracts
3+
This readme describes the steps for building, verifying, and deploying Terra smart contracts for Wormhole.
44

5+
**WARNING**: *This process is only Linux host compatible at this time.*
56

6-
``` sh
7-
docker build -f Dockerfile.build -o artifacts .
7+
## Verify Tilt
8+
9+
Before building Terra contracts, ensure that the specific commit you will be
10+
building from passes in tilt. This that ensures basic functionality of the
11+
Terra smart contracts that you are about to build and deploy.
12+
13+
## Build Contracts
14+
15+
The following command can be used to build Terra contracts via Docker.
16+
17+
Build Target Options: [`mainnet`|`testnet`|`devnet`|
18+
19+
These network names correspond to the naming convention used by wormhole
20+
elsewhere. This means that `mainnet` corresponds to Terra `mainnet`,
21+
`testnet` corresponds to Terra `testnet`, and `devnet` is `localterra`.
22+
23+
```console
24+
wormhole/terra $ make artifacts
825
```
926

10-
Then, for example, to deploy `token_bridge.wasm`, run in the `tools` directory
27+
Upon completion, the compiled bytecode for the Terra contracts will be placed
28+
into the `artifacts` directory.
1129

12-
``` sh
13-
npm ci
14-
node deploy_single.js --network mainnet --artifact ../artifacts/token_bridge.wasm --mnemonic "..."
30+
## Verify Checksums
31+
32+
Now that you have built the Terra contracts, you should ask a peer to build
33+
using the same process and compare the equivalent checksums.txt files to make
34+
sure the contract bytecode(s) are deterministic.
35+
36+
```console
37+
wormhole/terra $ cat artifacts/checksums.txt
1538
```
1639

17-
which will print something along the lines of
40+
Once you have verified the Terra contracts are deterministic with a peer, you can now move to the deploy step.
1841

19-
``` sh
20-
Storing WASM: ../artifacts/token_bridge.wasm (367689 bytes)
21-
Deploy fee: 88446uluna
22-
Code ID: 2435
42+
## Deploy Contracts
43+
44+
Now that you have built and verified checksums, you can now deploy one or more relevant contracts to the Terra blockchain.
45+
46+
Deploy Target Options: [`mainnet`|`testnet`|`devnet`]
47+
48+
You will need to define a `payer-DEPLOY_TARGET.json` for the relevant deploy
49+
target (eg. `payer-testnet.json`). This will contain the relevant wallet
50+
private key that you will be using to deploy the contracts.
51+
52+
```console
53+
wormhole/terra $ make deploy/bridge
54+
wormhole/terra $ make deploy/token_bridge
55+
wormhole/terra $ make deploy/nft_bridge
2356
```
2457

25-
# Migrate
58+
For each deployed contract, you will get a code id for that relevant
59+
contract for the deployment, make note of these so you can use them in
60+
the next step for on-chain verification.
61+
62+
## Verify On-Chain
63+
64+
Now that you have deployed one or more contracts on-chain, you can verify the
65+
onchain bytecode and make sure it matches the same checksums you identified
66+
above.
67+
68+
For each contract you wish to verify on-chain, you will need the following elements:
69+
70+
- Path to the contracts bytecode (eg. `artifacts-testnet/token_bridge.wasm`)
71+
- Terra code id for the relevant contract (eg. `59614`)
72+
- A network to verify on (`mainnet`, `testnet`, or `devnet`)
73+
74+
Below is how to verify all three contracts:
75+
76+
```console
77+
wormhole/terra $ ./verify artifacts/wormhole.wasm NEW_BRIDGE_CODE_ID
78+
wormhole/terra $ ./verify artifacts/token_bridge.wasm NEW_TOKEN_BRIDGE_CODE_ID
79+
wormhole/terra $ ./verify artifacts/nft_bridge.wasm NEW_NFT_BRIDGE_CODE_ID
80+
```
81+
Example: `./verify artifacts/token_bridge.wasm 59614`
82+
83+
For each contract, you should expect a `Successfully verified` output message.
84+
If all contracts can be successfully verified, you can engage in Wormhole
85+
protocol governance to obtain an authorized VAA for the contract upgrade(s).
86+
87+
A verification failure should never happen, and is a sign of some error in the
88+
deployment process. Do not proceed with governance until you can verify the
89+
on-chain bytecode with the locally compiled bytecode.
90+
91+
92+
## Governance
93+
94+
### Mainnet
95+
96+
Upgrades on mainnet have to go through governance. Once the code is deployed in
97+
the previous step, an unsigned governance VAA can be generated
98+
99+
```sh
100+
./generate_governance -m token_bridge -c 59614 > token-bridge-upgrade-59614.prototxt
101+
```
26102

27-
## Mainnet
103+
This will write to the `token-bridge-upgrade-59614.prototxt` file, which can
104+
now be shared with the guardians to vote on.
28105

29-
Migrations on mainnet have to go through governance. Once the guardians sign the
30-
upgrade VAA, the contract can be upgraded by submitting the signed VAA to the
31-
appropriate contract. For example, to upgrade the token bridge on mainnet,
32-
in `wormhole/clients/token_bridge/`:
106+
Once the guardians have reached quorum, the VAA may be submitted from any
107+
funded wallet: TODO - make this easier and more unified
33108

34109
``` sh
35110
node main.js terra execute_governance_vaa <signed VAA (hex)> --rpc "https://lcd.terra.dev" --chain_id "columbus-5" --mnemonic "..." --token_bridge "terra10nmmwe8r3g99a9newtqa7a75xfgs2e8z87r2sf"
36111
```
37112

38-
## Testnet
113+
### Testnet
39114

115+
For the contracts on testnet, the deployer wallet retains the upgrade
116+
authority, so these don't have to go through governance.
40117

41-
For example, to migrate the token bridge to 37262, run in `tools/`:
118+
For example, to migrate the token bridge to 59614, run in `tools/`:
42119

43120
``` sh
44-
node migrate_testnet.js --code_id 37262 --contract terra1pseddrv0yfsn76u4zxrjmtf45kdlmalswdv39a --mnemonic "..."
121+
node migrate_testnet.js --code_id 59614 --contract terra1pseddrv0yfsn76u4zxrjmtf45kdlmalswdv39a --mnemonic "..."
45122
```

terra/build.sh

-6
This file was deleted.

terra/generate_governance

+69
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
#!/bin/bash
2+
3+
set -euo pipefail
4+
5+
usage="Usage:
6+
$(basename "$0") [-h] [-m s] [-c n] -- Generate governance prototxt for a given module to be upgraded to a given code id
7+
8+
where:
9+
-h show this help text
10+
-m module (bridge, token_bridge, nft_bridge)
11+
-c code id (e.g. 4018)"
12+
13+
code_id=""
14+
module=""
15+
while getopts ':hm:c:' option; do
16+
case "$option" in
17+
h) echo "$usage"
18+
exit
19+
;;
20+
m) module=$OPTARG
21+
;;
22+
c) code_id=$OPTARG
23+
;;
24+
:) printf "missing argument for -%s\n" "$OPTARG" >&2
25+
echo "$usage" >&2
26+
exit 1
27+
;;
28+
\?) printf "illegal option: -%s\n" "$OPTARG" >&2
29+
echo "$usage" >&2
30+
exit 1
31+
;;
32+
esac
33+
done
34+
shift $((OPTIND - 1))
35+
36+
[ -z "$code_id" ] && { echo "$usage" >&2; exit 1; }
37+
[ -z "$module" ] && { echo "$usage" >&2; exit 1; }
38+
39+
address=$(printf "%064x" "$code_id")
40+
TERRA_ID=3
41+
GUARDIAND=guardiand
42+
43+
case "$module" in
44+
bridge)
45+
"$GUARDIAND" template contract-upgrade \
46+
--chain-id $TERRA_ID \
47+
--new-address "$address" \
48+
> /tmp/gov.prototxt
49+
;;
50+
token_bridge)
51+
"$GUARDIAND" template token-bridge-upgrade-contract \
52+
--chain-id $TERRA_ID --module "TokenBridge" \
53+
--new-address "$address" \
54+
> /tmp/gov.prototxt
55+
;;
56+
nft_bridge)
57+
"$GUARDIAND" template token-bridge-upgrade-contract \
58+
--chain-id $TERRA_ID --module "NFTBridge" \
59+
--new-address "$address" \
60+
> /tmp/gov.prototxt
61+
;;
62+
*) echo "illegal module $module"
63+
echo "$usage" >&2
64+
exit 1
65+
;;
66+
esac
67+
68+
cat /tmp/gov.prototxt
69+
"$GUARDIAND" admin governance-vaa-verify /tmp/gov.prototxt >&2

0 commit comments

Comments
 (0)