Query
So you're asking, How do we change the state of our contract but what if we want to read some details? We don't need to pay transaction fees on that, do we? No, my friend, this is what querying is for!
Querying is the other half of the coin to messages. You can think of queries as a database read, or a way of querying state.
So as we did with all other sections let's head to where it starts src/msg.rs
.
Define QueryMsg and Query response
pub enum QueryMsg {
GetConfig {},
}
pub struct ConfigResponse {
pub owner: Addr,
pub cw20_address: Addr,
pub cw721_address: Option<Addr>,
pub max_tokens: u32,
pub unit_price: Uint128,
pub name: String,
pub symbol: String,
pub token_uri: String,
pub extension: Extension,
pub unused_token_id: u32,
}
Our QueryMsg
is very simple. Because we only define a single state - the Config
struct, so we only need a single QueryMsg
to get the Config
.
Below QueryMsg
, we define the ConfigResponse
struct to be used as the return result for the GetConfig {}
query. Its fields are the same as the Config
struct state.
Write querying logic
#[cfg_attr(not(feature = "library"), entry_point)]
pub fn query(deps: Deps, _env: Env, msg: QueryMsg) -> StdResult<Binary> {
match msg {
QueryMsg::GetConfig {} => to_binary(&query_config(deps)?),
}
}
fn query_config(deps: Deps) -> StdResult<ConfigResponse> {
let config = CONFIG.load(deps.storage)?;
Ok(ConfigResponse {
owner: config.owner,
cw20_address: config.cw20_address,
cw721_address: config.cw721_address,
max_tokens: config.max_tokens,
unit_price: config.unit_price,
name: config.name,
symbol: config.symbol,
token_uri: config.token_uri,
extension: config.extension,
unused_token_id: config.unused_token_id,
})
}
You can see in query
function, QueryMsg
are handled differently than InstantiateMsg
or ExecuteMsg
. When returning from a query you don't return via a Response
. You must define a custom struct which can then be encoded to Binary
.
When msg
matches with QueryMsg::GetConfig{}
, the query thread are passed to the query_config
function.
About the query_config
function, in the first line, by using load()
, we get the CONFIG
Item data previously stored in the store and assign it to a config
variable.
And at the end, it's a simple return line using the Ok structure, inside it is a ConfigResponse
struct containing the return result.
Ok, next chapter we will test some thing that we write from Instantiate
to Query
chapter. For now, we're done!