Writing a smart contract with CosmWasm (Part 4)
Tags: rust, beginners, smartcontrac, cosmwasm
Published: 2022-09-13 14:57:18

### Introduction

Continue with my series, we will perform `query`.
The `query` is an action in order to get data from the contract.

### Create message query smart contracts

Same as `execute`, we need to define two structs `QueryMsg` and `QueryResponse` in the `src/msg.rc` to visualize the data type we want to receive and respond. Insert the below code:

```rust

#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)]
#[serde(rename_all = "snake_case")]
pub enum QueryMsg {
    Counter {},
}

#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)]
#[serde(rename_all = "snake_case")]
pub struct QueryResponse {
    pub counter: i32,
}
```

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/mfwscl0sdzn2omngowxi.png)


`QueryResponse` is response of the smart contract return when we perform `query` with `QueryMsg`. Same as the response from API, it returns `json` data.

Next, create a file: `query.rs` in the `src` folder and import module `query` to `lib.rs`. Our `lib.rs` will show:

```rust
pub mod contract;
mod error;
pub mod execute;
pub mod msg;
pub mod query;
pub mod state;

pub use crate::error::ContractError;
```

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/nrv444pbc5qkpd5xo2tz.png)


In the file `query.rs`, we are implementing a function with the name `query_counter` and we pass the `deps` as a parameter. The function return a `StdResult<Binary>`. Update the below code:

```rust
#[cfg(not(feature = "library"))]
use cosmwasm_std::{to_binary, Binary, Deps, Env, StdResult};

use crate::msg::QueryResponse;
use crate::state::STATE;

pub fn query_counter(deps: Deps, _env: Env) -> StdResult<Binary> {
    let current_state = STATE.load(deps.storage)?;
    let counter = current_state.counter;

    let resp = to_binary(&QueryResponse { counter }).unwrap();
    Ok(resp)
}
```

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/khsllrqzphwdrus5v40r.png)


That's right. Simple, we implement a logic to query data stored in smart contract.
We need to bind response to `json` data with `to_binary` function support from `cosmwasm-std`.
And don't forget add an new entry point to `src/contract.rs`: 

```rust
#[cfg_attr(not(feature = "library"), entry_point)]
pub fn query(deps: Deps, env: Env, msg: QueryMsg) -> StdResult<Binary> {
    match msg {
        QueryMsg::Counter {} => query_counter(deps, env),
    }
}
```

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/cao69o7p73ahgfttq3ss.png)


I think we have familiar with this syntax throughout of series.
The last entry point of our contract has appeared. We need to test it.

### Testing module

Still in the file: `src/query.rs`. and update the below code to bottom:

```rust
#[cfg(test)]
mod tests {
    use crate::contract::{execute, instantiate, query};
    use crate::msg::{ExecuteMsg, InstantiateMsg, QueryMsg, QueryResponse};
    use cosmwasm_std::testing::{mock_dependencies, mock_env, mock_info};
    use cosmwasm_std::to_binary;

    const ADDR: &str = "addr1";

    #[test]
    fn test_query() {
        let mut deps = mock_dependencies();
        let env = mock_env();
        let info = mock_info(ADDR, &[]);
        let expect_data_0 = to_binary(&QueryResponse { counter: 0 }).unwrap();
        let expect_data_1 = to_binary(&QueryResponse { counter: 1 }).unwrap();

        let msg = InstantiateMsg {};
        let _resp = instantiate(deps.as_mut(), env.clone(), info.clone(), msg).unwrap();

        // query one time.
        let msg = QueryMsg::Counter {};
        let resp = query(deps.as_ref(), env.clone(), msg).unwrap();
        assert_eq!(resp, expect_data_0);

        // query two time
        let msg = ExecuteMsg::Update {};
        let _resp = execute(deps.as_mut(), env.clone(), info, msg).unwrap();
        let msg = QueryMsg::Counter {};
        let resp = query(deps.as_ref(), env, msg).unwrap();
        assert_eq!(resp, expect_data_1);
    }
}
```

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/h73432vz6y316d2laphq.png)


In `query` testing module, we will coverage all logic of the smart contract includes: create contract, execute contract, and query contract.

We create a module test and unit test function `test_query`.
We still import all dependencies and create two values expected. One for getting state after instantiate contract, two for getting state after execute the contract.

Run `cargo-test` in the terminal

If your output like below, everything is right:

```
running 1 test
test query::tests::test_query ... ok

test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 2 filtered out; finished in 0.00s
```

### Sumary

I mentioned all entry points of the smart contract, wrote logic attach test case for our logic of smart contract.
Next part, I will build and deploy our contract to `testnet` network.
Thanks for reading and have a good day!