Skip to main content
Version: 1.0

Uploading and Interacting

We have the binary ready. Now it is time to see some wasm action. You can use Go CLI or Node Console as you wish.

Go CLI#

We generated a wasm binary executable in the previous chapter. Let's put it into use. Now, we will upload the code to the blockchain. Afterwards, you can download the bytecode to verify it is proper:

# see how many codes we have nowwasmd query wasm list-code $NODE
# gas is huge due to wasm size... but auto-zipping reduced this from 1.8M to around 600k# you can see the code in the resultRES=$(wasmd tx wasm store artifacts/cw_escrow.wasm --from fred $TXFLAG -y)
# you can also get the code this wayCODE_ID=$(echo $RES | jq -r '.logs[0].events[0].attributes[-1].value')
# no contracts yet, this should return an empty listwasmd query wasm list-contract-by-code $CODE_ID $NODE --output json
# you can also download the wasm from the chain and check that the diff between them is emptywasmd query wasm code $CODE_ID $NODE download.wasmdiff artifacts/cw_escrow.wasm download.wasm

Instantiating the Contract#

We can now create an instance of this wasm contract. Here the verifier will fund an escrow, that will allow fred to control payout and upon release, the funds go to bob.

# instantiate contract and verifyINIT=$(jq -n --arg fred $(wasmd keys show -a fred) --arg bob $(wasmd keys show -a bob) '{"arbiter":$fred,"recipient":$bob}')wasmd tx wasm instantiate $CODE_ID "$INIT" \    --from fred --amount=50000usponge  --label "escrow 1" $TXFLAG -y
# check the contract state (and account balance)wasmd query wasm list-contract-by-code $CODE_ID $NODE --output jsonCONTRACT=$(wasmd query wasm list-contract-by-code $CODE_ID $NODE --output json | jq -r '.contracts[-1]')echo $CONTRACT
# we should see this contract with 50000uspongewasmd query wasm contract $CONTRACT $NODEwasmd query bank balances $CONTRACT $NODE
# you can dump entire contract statewasmd query wasm contract-state all $CONTRACT $NODE
# note that we prefix the key "config" with two bytes indicating it's length# echo -n config | xxd -ps# gives 636f6e666967# thus we have a key 0006636f6e666967
# you can also query one key directlywasmd query wasm contract-state raw $CONTRACT 0006636f6e666967 $NODE --hex
# Note that keys are hex encoded, and val is base64 encoded.# To view the returned data (assuming it is ascii), try something like:# (Note that in many cases the binary data returned is non in ascii format, thus the encoding)wasmd query wasm contract-state all $CONTRACT $NODE --output "json" | jq -r '.models[0].key' | xxd -r -pswasmd query wasm contract-state all $CONTRACT $NODE --output "json" | jq -r '.models[0].value' | base64 -d
# or try a "smart query", executing against the contractwasmd query wasm contract-state smart $CONTRACT '{}' $NODE# (since we didn't implement any valid QueryMsg, we just get a parse error back)

Once we have the funds in the escrow, let us try to release them. First, failing to do so with a key that is not the verifier, then using the proper key to release.

# execute fails if wrong personAPPROVE='{"approve":{"quantity":[{"amount":"50000","denom":"usponge"}]}}'wasmd tx wasm execute $CONTRACT "$APPROVE" \    --from thief $TXFLAG -y
# looking at the logs should show: "execute wasm contract failed: Unauthorized"# and bob should still be broke (and broken showing the account does not exist Error)wasmd query bank balances $(wasmd keys show bob -a) $NODE
# but succeeds when fred trieswasmd tx wasm execute $CONTRACT "$APPROVE" \    --from fred $TXFLAG -y
wasmd query bank balances $(wasmd keys show bob -a) $NODE
# contract coins must be emptywasmd query bank balances $CONTRACT $NODE

Node Console#

caution

Node console needs to be updated. The code below is obsolete

If you set up the Node Console / REPL in the client setup section, you can use that to deploy and execute your contract. I think you will find that JSON manipulation and parsing is a bit nicer in JavaScript than in Shell Script.

First, go to the cli directory and start up your console:

npx @cosmjs/cli@^0.25 --init https://raw.githubusercontent.com/CosmWasm/testnets/master/heldernet/cli_helper.ts

Now, we make all the keys and initialize clients:

const fredSeed = loadOrCreateMnemonic("fred.key");const {address: fredAddr, client: fredClient} = await connect(fredSeed, {});
// bob doesn't have a client here as we will not// submit any tx with this account, just query balanceconst bobSeed = loadOrCreateMnemonic("bob.key");const bobAddr = await mnemonicToAddress("muffin fix provide project obtain......", bobSeed);
const thiefSeed = loadOrCreateMnemonic("thief.key");
const {address: thiefAddr, client: thiefClient} = await connect(thiefSeed, {});
console.log(fredAddr, bobAddr, thiefAddr);

Hit the faucet it needed for fred, so he has tokens to submit transactions:

fredClient.getAccount();// if "undefined", do the followinghitFaucet(defaultFaucetUrl, fredAddr, "usponge")fredClient.getAccount();
thiefClient.getAccount();// if "undefined", do the followinghitFaucet(defaultFaucetUrl, thiefAddr, "usponge")thiefClient.getAccount();
// check bobAddr has no fundsfredClient.getAccount(bobAddr);
// get the working directory (needed later)process.cwd()

Uploading with JS#

Now, we go back to the Node console and upload the contract and instantiate it:

const wasm = fs.readFileSync('artifacts/cw_escrow.wasm');// you can add extra information to contract details such as source and builder.const up = await fredClient.upload(wasm, {  source: "https://crates.io/api/v1/crates/cw-escrow/0.10.0/download",  builder: "cosmwasm/rust-optimizer:0.10.7"});
console.log(up);const {codeId} = up;
const initMsg = {arbiter: fredAddr, recipient: bobAddr};const {contractAddress} = await fredClient.instantiate(codeId, initMsg, "Escrow 1", {  memo: "memo",  transferAmount: [{denom: "usponge", amount: "50000"}]});
// check the contract is set up properlyconsole.log(contractAddress);fredClient.getContract(contractAddress);fredClient.getAccount(contractAddress);
// make a raw query - key length prefixed "config"const key = new Uint8Array([0, 6, ...toAscii("config")]);const raw = await fredClient.queryContractRaw(contractAddress, key);JSON.parse(fromUtf8(raw))// note the addresses are stored in base64 internally, not bech32, but the data is there... this is why we often implement smart queries on real contracts

Executing Contract with JS#

Once we have properly configured the contract, let's show how to use it, both the proper "approve" command:

const approve = {approve: {quantity: [{amount: "50000", denom: "usponge"}]}};
// thief cannot approvethiefClient.execute(contractAddress, approve)
// but fred can (and moves money to bob)fredClient.execute(contractAddress, approve);// verify bob got the tokensfredClient.getAccount(bobAddr);// verify contract lostfredClient.getAccount(contractAddress);