Execution messages
We created instantiate
and query
messages. We have the state in our contract and can test it.
Now let's expand our contract by adding the possibility of updating the state. In this chapter, we
will add the increase_count
execute message.
Add a message
Adding a new variant of ExecMsg
is as simple as adding one to the QueryMsg
.
use cosmwasm_std::{Response, StdResult};
use cw_storage_plus::Item;
use sylvia::types::{ExecCtx, InstantiateCtx, QueryCtx};
use sylvia::{contract, entry_points};
use crate::responses::CountResponse;
pub struct CounterContract {
pub(crate) count: Item<u32>,
}
#[entry_points]
#[contract]
impl CounterContract {
pub const fn new() -> Self {
Self {
count: Item::new("count"),
}
}
#[sv::msg(instantiate)]
pub fn instantiate(&self, ctx: InstantiateCtx, count: u32) -> StdResult<Response> {
self.count.save(ctx.deps.storage, &count)?;
Ok(Response::default())
}
#[sv::msg(query)]
pub fn count(&self, ctx: QueryCtx) -> StdResult<CountResponse> {
let count = self.count.load(ctx.deps.storage)?;
Ok(CountResponse { count })
}
#[sv::msg(exec)]
pub fn increment_count(&self, ctx: ExecCtx, ) -> StdResult<Response> {
self.count
.update(ctx.deps.storage, |count| -> StdResult<u32> {
Ok(count + 1)
})?;
Ok(Response::default())
}
}
We will add the #[sv::msg(exec)]
attribute and make it accept ExecCtx
parameter. It will return StdResult<Response>
, similiar to the instantiate method.
Inside we call update
to increment the count
state.
Like that new variant for the ExecMsg
is created, execute
entry point properly dispatches a message
to this method and our multitest helpers are updated and ready to use.
Again I encourage you to expand the macro and inspect all three things mentioned above.
Testing
Our contract has a new variant for the ExecMsg
. Let's check if it works properly.
use sylvia::cw_multi_test::IntoAddr;
use sylvia::multitest::App;
use crate::contract::sv::mt::{CodeId, CounterContractProxy};
#[test]
fn instantiate() {
let app = App::default();
let code_id = CodeId::store_code(&app);
let owner = "owner".into_addr();
let contract = code_id.instantiate(42).call(&owner).unwrap();
let count = contract.count().unwrap().count;
assert_eq!(count, 42);
contract.increment_count().call(&owner).unwrap();
let count = contract.count().unwrap().count;
assert_eq!(count, 43);
}
As in the case of query we can call increment_count
directly on our proxy contract. Same as in
the case of instantiate we have to pass the caller here. We could also send funds here using with_funds
method.
Next step
I encourage you to add a new ExecMsg
variant by yourself. It could be called set_count
. Test it
and see how easy it is to add new message variants even without the guide.