diff --git a/.eslintrc.js b/.eslintrc.js index a1dee715..52a62083 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -41,6 +41,7 @@ module.exports = { files: "**/*.js", rules: { "@typescript-eslint/no-var-requires": "off", + "@typescript-eslint/explicit-function-return-type": "off", }, }, { diff --git a/scripts/cosm/contracts/checksums.sha256 b/scripts/cosm/contracts/checksums.sha256 new file mode 100644 index 00000000..b36dcaa7 --- /dev/null +++ b/scripts/cosm/contracts/checksums.sha256 @@ -0,0 +1 @@ +b26861a6aa9858585ed905a590272735bd4fe8177c708940236224e8c9ff73ca cw-erc20.wasm diff --git a/scripts/cosm/contracts/cw-erc20.wasm b/scripts/cosm/contracts/cw-erc20.wasm new file mode 100644 index 00000000..04512932 Binary files /dev/null and b/scripts/cosm/contracts/cw-erc20.wasm differ diff --git a/scripts/cosm/deploy_erc20.js b/scripts/cosm/deploy_erc20.js new file mode 100644 index 00000000..06fe60b9 --- /dev/null +++ b/scripts/cosm/deploy_erc20.js @@ -0,0 +1,120 @@ +/* eslint-disable @typescript-eslint/camelcase */ +const { Encoding } = require("@iov/encoding"); +const { + encodeSecp256k1Signature, + makeSignBytes, + marshalTx, + logs, + RestClient, + Secp256k1Pen, +} = require("@cosmwasm/sdk"); +const fs = require("fs"); + +const httpUrl = "http://localhost:1317"; +const networkId = "testing"; +const defaultFee = { + amount: [ + { + amount: "5000", + denom: "ucosm", + }, + ], + gas: "1000000", // one million +}; +const faucetMnemonic = + "economy stock theory fatal elder harbor betray wasp final emotion task crumble siren bottom lizard educate guess current outdoor pair theory focus wife stone"; +const faucetAddress = "cosmos1pkptre7fdkl6gfrzlesjjvhxhlc3r4gmmk8rs6"; + +async function uploadContract(client, pen, wasm) { + const memo = "My first contract on chain"; + const storeCodeMsg = { + type: "wasm/store-code", + value: { + sender: faucetAddress, + wasm_byte_code: Encoding.toBase64(wasm), + source: "https://github.com/confio/cosmwasm/raw/0.7/lib/vm/testdata/contract_0.6.wasm", + builder: "cosmwasm-opt:0.6.2", + }, + }; + + const account = (await client.authAccounts(faucetAddress)).result.value; + const signBytes = makeSignBytes([storeCodeMsg], defaultFee, networkId, memo, account); + const signature = encodeSecp256k1Signature(pen.pubkey, await pen.createSignature(signBytes)); + const signedTx = { + msg: [storeCodeMsg], + fee: defaultFee, + memo: memo, + signatures: [signature], + }; + return client.postTx(marshalTx(signedTx)); +} + +async function instantiateContract(client, pen, codeId, msg, transferAmount) { + const memo = "Create an ERC20 instance"; + const instantiateContractMsg = { + type: "wasm/instantiate", + value: { + sender: faucetAddress, + code_id: codeId.toString(), + init_msg: msg, + init_funds: transferAmount || [], + }, + }; + const account = (await client.authAccounts(faucetAddress)).result.value; + const signBytes = makeSignBytes([instantiateContractMsg], defaultFee, networkId, memo, account); + const signature = encodeSecp256k1Signature(pen.pubkey, await pen.createSignature(signBytes)); + const signedTx = { + msg: [instantiateContractMsg], + fee: defaultFee, + memo: memo, + signatures: [signature], + }; + return client.postTx(marshalTx(signedTx)); +} + +async function main() { + const pen = await Secp256k1Pen.fromMnemonic(faucetMnemonic); + const client = new RestClient(httpUrl); + + const wasm = fs.readFileSync(__dirname + "/contracts/cw-erc20.wasm"); + const uploadResult = await uploadContract(client, pen, wasm); + if (uploadResult.code) { + throw new Error(`Uploading failed with code: ${uploadResult.code}; log: '${uploadResult.raw_log}'`); + } + const codeIdAttr = logs.findAttribute(logs.parseLogs(uploadResult.logs), "message", "code_id"); + const codeId = Number.parseInt(codeIdAttr.value, 10); + console.info(`Upload succeeded. Code ID is ${codeId}`); + + const initMsg = { + decimals: 5, + name: "Ash token", + symbol: "ASH", + initial_balances: [ + { + address: faucetAddress, + amount: "11", + }, + ], + }; + const instantiationResult = await instantiateContract(client, pen, codeId, initMsg); + if (instantiationResult.code) { + throw new Error( + `Instantiation failed with code: ${instantiationResult.code}; log: '${instantiationResult.raw_log}'`, + ); + } + const instantiationLogs = logs.parseLogs(instantiationResult.logs); + const contractAddress = logs.findAttribute(instantiationLogs, "message", "contract_address").value; + + console.info(`Contract instantiated at ${contractAddress}`); +} + +main().then( + () => { + console.info("All done, let the coins flow."); + process.exit(0); + }, + error => { + console.error(error); + process.exit(1); + }, +);