فهرست منبع

Add terra build & deploy instructions

Csongor Kiss 3 سال پیش
والد
کامیت
99e2d4ac09
4فایلهای تغییر یافته به همراه198 افزوده شده و 1 حذف شده
  1. 11 0
      terra/Dockerfile.build
  2. 23 0
      terra/README.md
  3. 162 0
      terra/tools/deploy_single.js
  4. 2 1
      terra/tools/package.json

+ 11 - 0
terra/Dockerfile.build

@@ -0,0 +1,11 @@
+# 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 /

+ 23 - 0
terra/README.md

@@ -0,0 +1,23 @@
+# Deploy
+
+First build the contracts
+
+
+``` sh
+docker build -f Dockerfile.build -o artifacts .
+```
+
+Then, for example, to deploy `token_bridge.wasm`, run in the `tools` directory
+
+``` sh
+npm ci
+node deploy_single.js --network mainnet --artifact ../artifacts/token_bridge.wasm --mnemonic "..."
+```
+
+which will print something along the lines of
+
+``` sh
+Storing WASM: ../artifacts/token_bridge.wasm (367689 bytes)
+Deploy fee:  88446uluna
+Code ID:  2435
+```

+ 162 - 0
terra/tools/deploy_single.js

@@ -0,0 +1,162 @@
+import { LCDClient, MnemonicKey } from "@terra-money/terra.js";
+import {
+  MsgInstantiateContract,
+  MsgStoreCode,
+} from "@terra-money/terra.js";
+import { readFileSync } from "fs";
+import { Bech32, toHex } from "@cosmjs/encoding";
+import { zeroPad } from "ethers/lib/utils.js";
+import axios from "axios";
+import yargs from "yargs";
+import {hideBin} from "yargs/helpers";
+
+export const TERRA_GAS_PRICES_URL = "https://fcd.terra.dev/v1/txs/gas_prices";
+
+const argv = yargs(hideBin(process.argv))
+  .option('network', {
+    description: 'Which network to deploy to',
+    choices: ['mainnet', 'testnet', 'localterra'],
+    required: true
+  })
+  .option('artifact', {
+    description: 'Which WASM file to deploy',
+    type: 'string',
+    required: true
+  })
+  .option('mnemonic', {
+    description: 'Mnemonic (private key)',
+    type: 'string',
+    required: true
+  })
+  .help()
+  .alias('help', 'h').argv;
+
+const artifact = argv.artifact;
+
+/* Set up terra client & wallet */
+
+const terra_host =
+      argv.network === "mainnet"
+    ? {
+        URL: "https://lcd.terra.dev",
+        chainID: "columbus-5",
+        name: "mainnet",
+      }
+    : argv.network === "testnet"
+    ? {
+        URL: "https://bombay-lcd.terra.dev",
+        chainID: "bombay-12",
+        name: "testnet",
+      }
+    : {
+        URL: "http://localhost:1317",
+        chainID: "columbus-5",
+        name: "localterra",
+      };
+
+const lcd = new LCDClient(terra_host);
+
+const feeDenoms = ["uluna"];
+
+const gasPrices = await axios
+  .get(TERRA_GAS_PRICES_URL)
+  .then((result) => result.data);
+
+const wallet = lcd.wallet(
+  new MnemonicKey({
+    mnemonic: argv.mnemonic
+  })
+);
+
+await wallet.sequence();
+
+/* Deploy artifacts */
+
+let codeId;
+const contract_bytes = readFileSync(artifact);
+console.log(`Storing WASM: ${artifact} (${contract_bytes.length} bytes)`);
+
+const store_code = new MsgStoreCode(
+  wallet.key.accAddress,
+  contract_bytes.toString("base64")
+);
+
+const feeEstimate = await lcd.tx.estimateFee(
+  wallet.key.accAddress,
+  [store_code],
+  {
+    memo: "",
+    feeDenoms,
+    gasPrices,
+  }
+);
+
+console.log("Deploy fee: ", feeEstimate.amount.toString());
+
+const tx = await wallet.createAndSignTx({
+  msgs: [store_code],
+  memo: "",
+  feeDenoms,
+  gasPrices,
+  fee: feeEstimate,
+});
+
+const rs = await lcd.tx.broadcast(tx);
+const ci = /"code_id","value":"([^"]+)/gm.exec(rs.raw_log)[1];
+codeId = parseInt(ci);
+
+console.log("Code ID: ", codeId);
+
+/* Instantiate contracts.
+ *
+ * We instantiate the core contracts here (i.e. wormhole itself and the bridge contracts).
+ * The wrapped asset contracts don't need to be instantiated here, because those
+ * will be instantiated by the on-chain bridge contracts on demand.
+ * */
+async function instantiate(codeId, inst_msg) {
+  var address;
+  await wallet
+    .createAndSignTx({
+      msgs: [
+        new MsgInstantiateContract(
+          wallet.key.accAddress,
+          wallet.key.accAddress,
+          codeId,
+          inst_msg
+        ),
+      ],
+      memo: "",
+    })
+    .then((tx) => lcd.tx.broadcast(tx))
+    .then((rs) => {
+      address = /"contract_address","value":"([^"]+)/gm.exec(rs.raw_log)[1];
+    });
+  console.log(`Instantiated ${contract} at ${address} (${convert_terra_address_to_hex(address)})`);
+  return address;
+}
+
+// example usage of instantiate:
+
+// const contractAddress = await instantiate("wormhole.wasm", {
+//   gov_chain: govChain,
+//   gov_address: Buffer.from(govAddress, "hex").toString("base64"),
+//   guardian_set_expirity: 86400,
+//   initial_guardian_set: {
+//     addresses: [
+//       {
+//         bytes: Buffer.from(
+//           "beFA429d57cD18b7F8A4d91A2da9AB4AF05d0FBe",
+//           "hex"
+//         ).toString("base64"),
+//       },
+//     ],
+//     expiration_time: 0,
+//   },
+// });
+
+
+// Terra addresses are "human-readable", but for cross-chain registrations, we
+// want the "canonical" version
+function convert_terra_address_to_hex(human_addr) {
+  return "0x" + toHex(zeroPad(Bech32.decode(human_addr).data, 32));
+}

+ 2 - 1
terra/tools/package.json

@@ -12,6 +12,7 @@
   "dependencies": {
     "@terra-money/terra.js": "^2.0.11",
     "@cosmjs/encoding": "^0.26.2",
-    "ethers": "^5.4.4"
+    "ethers": "^5.4.4",
+    "yargs": "^17.0.1"
   }
 }