> For the complete documentation index, see [llms.txt](https://initia.gitbook.io/initia/kBNuZF5MglV9d3zOOUeW/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://initia.gitbook.io/initia/kBNuZF5MglV9d3zOOUeW/initia-developer-tutorials/6.-build-and-publish-contracts/cosmwasm-contract.md).

# CosmWasm Contract

{% hint style="warning" %}
**Note**: CosmWasm contracts are only supported on Minitias that are using WasmVM.&#x20;
{% endhint %}

## Step 0: Clone cw-contracts

In this tutorial, we will use `nameservice` module of `cw-contracts` repository.

```bash
git clone https://github.com/deus-labs/cw-contracts.git
cd cw-contracts
git checkout main
cd contracts/nameservice
```

***

## Step 1: Compile a contract

By using the command below, a Wasm binary to be published on Wasm Minitia is compiled.

```bash
RUSTFLAGS='-C link-arg=-s' cargo wasm
```

When compiling is completed, `target/wasm32-unknown-unknown/release/cw_nameservice.wasm` file will be generated.

## Step 1-1: Compile with rust-optimizer (Advanced)

{% hint style="info" %}
Docker must be installed in order to use `rust-optimizer`.
{% endhint %}

Wasm binary file must be as small as possible in order to reduce gas costs for both the deployment and for every interaction with the deployed contract. The [rust-optimizer](https://github.com/CosmWasm/rust-optimizer) is a tool which can be used to make the binary size as small as possible while ensuring that all contract features are still working.&#x20;

```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/rust-optimizer:0.12.11
```

By running the above command,  the binary file will be generated within `artifacts/cw_nameservice.wasm`.

***

## Step 2: Store a contract

Let's store `cw_nameservice.wasm` contract created in the previous step onto the Minitia.&#x20;

{% tabs %}
{% tab title="CLI" %}

```bash
> minitiad tx wasm store [binary-path] \
  --from test-account \
  --gas auto --gas-adjustment 1.5 \
  --gas-prices [gas-price] \
  --node [rpc-url]:[rpc-port] \
  --chain-id [chain-id]
```

{% endtab %}

{% tab title="initia.js" %}

```typescript
import { LCDClient, MnemonicKey, MsgStoreCode, Wallet } from '@initia/initia.js';
import * as fs from 'fs';

const path =
  '${path_to_binary}';

async function storeContract() {
  const lcd = new LCDClient('[rest-url]', {
    gasPrices: '0.15uinit',
    gasAdjustment: '1.5',
  });

  const key = new MnemonicKey({
    mnemonic:
      'beauty sniff protect ...',
  });
  const wallet = new Wallet(lcd, key);

  const codeBytes = fs.readFileSync(
    ${path}
  );

  const msgs = [
    new MsgStoreCode(key.accAddress, codeBytes.toString('base64'))
  ];


  // sign tx
  const signedTx = await wallet.createAndSignTx({ msgs });
  // send(broadcast) tx
  lcd.tx.broadcastSync(signedTx).then(res => console.log(res));
  // {
  //   height: 0,
  //   txhash: '162AA29DE237BD060EFEFFA862DBD07ECD1C562EBFDD965AD6C34DF856B53DC2',
  //   raw_log: '[]'
  // }
}

storeContract();
```

{% endtab %}
{% endtabs %}

***

## Step 3: Instantiate a contract

In this step, we will instantiate a new contract using the stored code in the previous step.&#x20;

First, `codeId` is required in order to instantiate the stored `cw_nameservice.wasm` contract. `codeID` can be fetched with the command line below.

{% tabs %}
{% tab title="CLI" %}

```bash
> RES=$(minitiad q tx --type=hash [txhash] --node [rpc-url]:[rpc-port] --output json)
CODE_ID=$(echo $RES | jq -r '.events[-1].attributes[1].value') 
echo $CODE_ID
```

{% endtab %}

{% tab title="initia.js" %}

```typescript
const lcd = new LCDClient('[rest-url]');

lcd.tx
  .txInfo('13F0DE1D8E394F9CCE879AF0DAEFCA3D717E8C97B075B23BB7E799FFC18F0473')
  .then(res =>
    console.log(
      `codeId: ${res.events[res.events.length - 1].attributes[1].value}`
    )
  );

```

{% endtab %}
{% endtabs %}

Let's instantiate a new wasm contract using the stored code.

{% tabs %}
{% tab title="CLI" %}

<pre class="language-bash"><code class="lang-bash"><strong>> INIT='{"purchase_price":{"amount":"100","denom":"l2/2588fd87a8e081f6a557f43ff14f05dddf5e34cb27afcefd6eaf81f1daea30d0"},"transfer_price":{"amount":"100","denom":"l2/2588fd87a8e081f6a557f43ff14f05dddf5e34cb27afcefd6eaf81f1daea30d0"}}'
</strong>
minitiad tx wasm instantiate 1 "$INIT" --label=nameservice --no-admin \
  --from test-account \
  --gas auto --gas-adjustment 1.5 \
  --gas-prices [gas-price] \
  --node [rpc-url]:[rpc-port] \
  --chain-id [chain-id]
</code></pre>

{% endtab %}

{% tab title="initia.js" %}

```typescript
import {
  LCDClient,
  MnemonicKey,
  MsgInstantiateContract,
  Wallet,
  Coins,
} from '@initia/initia.js';

async function instantiateContract() {
  const lcd = new LCDClient('[rest-url]', {
    gasPrices: '0.15uinit',
    gasAdjustment: '1.5',
  });

  const key = new MnemonicKey({
    mnemonic:
      'beauty sniff protect ...',
  });
  const wallet = new Wallet(lcd, key);

  const instantiateMsg = {
    purchase_price: {
      amount: '100',
      denom:
        '[denom]',
    },
    transfer_price: {
      amount: '100',
      denom:
        '[denom]',
    },
  };

  const msgs = [
    new MsgInstantiateContract(
      key.accAddress,
      undefined,
      1,
      'nameservice',
      Buffer.from(JSON.stringify(instantiateMsg)).toString('base64'),
      new Coins()
    ),
  ];


  // sign tx
  const signedTx = await wallet.createAndSignTx({ msgs });
  // send(broadcast) tx
  await lcd.tx.broadcastSync(signedTx).then(res => console.log(res));
  // {
  //   height: 0,
  //   txhash: '162AA29DE237BD060EFEFFA862DBD07ECD1C562EBFDD965AD6C34DF856B53DC2',
  //   raw_log: '[]'
  // }
}

instantiateContract();
```

{% endtab %}
{% endtabs %}

***

## Step 4: Interact with a contract

We are now ready to interact with the instantiated CosmWasm contract.&#x20;

Contract address is required in order to interact with the instantiated contract. The contract address can be found by using the below command:&#x20;

{% tabs %}
{% tab title="CLI" %}

```bash
> RES=$(minitiad q tx --type=hash [txhash] --node [rpc-url]:[rpc-port] --output json)
CONTRACT_ADDRESS=$(echo $RES | jq -r '.events[-1].attributes[0].value') 
echo $CONTRACT_ADDRESS
```

{% endtab %}

{% tab title="initia.js" %}

```typescript
const lcd = new LCDClient('[rest-url]');

lcd.tx
  .txInfo('2C578BF0CD21B98CE89182746B59C3524F3C44A67E4307C8646143F310CD1759')
  .then(res =>
    console.log(
      `contractAddress: ${
        res.events[res.events.length - 1].attributes[0].value
      }`
    )
  );
```

{% endtab %}
{% endtabs %}

#### Execute a contract function

In this example, we will use the `register` function from the published contract, to register `test` as a name service domain.&#x20;

{% tabs %}
{% tab title="CLI" %}

<pre class="language-bash"><code class="lang-bash"><strong>> REGISTER='{"register":{"name":"test"}}'
</strong>minitiad tx wasm execute [contract_address] "$REGISTER" --amount 100[denom]  \
  --from test-account \
  --gas auto --gas-adjustment 1.5 \
  --gas-prices [gas-price] \
  --node [rpc-url]:[rpc-port] \
  --chain-id [chain-id]
</code></pre>

{% endtab %}

{% tab title="initia.js" %}

```typescript
import {
  LCDClient,
  MnemonicKey,
  MsgExecuteContract,
  Wallet,
} from '@initia/initia.js';

async function executeContract() {
  const lcd = new LCDClient('[rest-url]', {
    gasPrices: '0.15uinit',
    gasAdjustment: '1.5',
  });

  const key = new MnemonicKey({
    mnemonic: 'beauty sniff protect ...',
  });
  const wallet = new Wallet(lcd, key);

  const executeMsg = { register: { name: 'test' } };
  const msgs = [
    new MsgExecuteContract(
      key.accAddress,
      '[contract address]',
      Buffer.from(JSON.stringify(executeMsg)).toString('base64'),
      '100[denom]'
    ),
  ];

  // sign tx
  const signedTx = await wallet.createAndSignTx({ msgs });
  // send(broadcast) tx
  await lcd.tx.broadcastSync(signedTx).then(res => console.log(res));
  // {
  //   height: 0,
  //   txhash: '162AA29DE237BD060EFEFFA862DBD07ECD1C562EBFDD965AD6C34DF856B53DC2',
  //   raw_log: '[]'
  // }
}

executeContract();

```

{% endtab %}
{% endtabs %}

#### Query Results

Once the `register` function is successfully executed, we can confirm the name that was registered through a contract query.

{% tabs %}
{% tab title="CLI" %}

<pre class="language-bash"><code class="lang-bash"><strong>> NAME_QUERY='{"resolve_record": {"name": "test"}}'
</strong>minitiad query wasm contract-state smart [contract_address] "$NAME_QUERY" --node [rpc-url]:[rpc-port]
# data:
#   address: init150748hf2e3mjed5w0xqkp9wn8xs55nnzneg452
</code></pre>

{% endtab %}

{% tab title="initia.js" %}

```typescript
const lcd = new LCDClient('[rest-url]');

lcd.wasm
  .smartContractState(
    '[contract_address]',
    Buffer.from('{"resolve_record": {"name": "test"}}').toString('base64')
  )
  .then(res => console.log(res));
```

{% endtab %}
{% endtabs %}
