|
1 | 1 | --- |
2 | | -title: First Composed Response |
| 2 | +title: First composed response |
3 | 3 | description: Return something more after execution. |
4 | 4 | --- |
5 | 5 |
|
6 | | -# First Composed Response |
| 6 | +# First composed response |
7 | 7 |
|
8 | | -As it stands, your `execute` function only returns a `Response::default()`. That is the bare minimum. Eventually, as your smart contract communicates with others or even other modules, it needs to pass more information as part of its response. This section is a step in this direction. |
| 8 | +As it stands, your `execute` function only returns a `Response::default()`. That is the bare minimum. |
| 9 | +Eventually, as your smart contract communicates with others or even other modules, it needs to pass |
| 10 | +more information as part of its response. This section is a step in this direction. |
9 | 11 |
|
10 | | -<HighlightBox type="info" title="Exercise progression"> |
| 12 | +:::info Exercise progression |
11 | 13 |
|
12 | | -If you skipped the previous section, you can just switch the project to its [`first-multi-test`](https://github.com/b9lab/cw-my-nameservice/tree/first-multi-test) branch and take it from there. |
| 14 | +If you skipped the previous section, you can just switch the project to its |
| 15 | +[`first-multi-test`](https://github.com/b9lab/cw-my-nameservice/tree/first-multi-test) branch and take it from there. |
13 | 16 |
|
14 | | -</HighlightBox> |
| 17 | +::: |
15 | 18 |
|
16 | 19 | ## Add an event |
17 | 20 |
|
18 | | -A very simple thing to add to your response is an [event](https://docs.cosmwasm.com/core/architecture/events). It is the same concept as [events in Cosmos](https://tutorials.cosmos.network/academy/2-cosmos-concepts/10-events.html). You can add attributes to the `wasm` event that is added by the CosmWasm module itself, and is always present. |
19 | | - |
20 | | -Better yet, you add your own event, which will mean something to those who interact with your smart contract. Update your `src/contract.rs` with: |
21 | | - |
22 | | -<CodeBlock title="src/contract.rs"> |
23 | | - ```diff-rust |
24 | | - ... |
25 | | - |
26 | | - use cosmwasm_std::{ |
27 | | - - entry_point, to_json_binary, Binary, Deps, DepsMut, Env, MessageInfo, Response, StdResult, |
28 | | - + entry_point, to_json_binary, Binary, Deps, DepsMut, Env, Event, MessageInfo, Response, |
29 | | - + StdResult, |
30 | | - }; |
| 21 | +A very simple thing to add to your response is an [event](https://docs.cosmwasm.com/core/architecture/events). |
| 22 | +It is the same concept as [events in Cosmos](https://tutorials.cosmos.network/academy/2-cosmos-concepts/10-events.html). |
| 23 | +You can add attributes to the `wasm` event that is added by the CosmWasm module itself, and is always present. |
| 24 | + |
| 25 | +Better yet, you add your own event, which will mean something to those who interact with your smart contract. |
| 26 | +Update your `src/contract.rs` with: |
| 27 | + |
| 28 | +```rust title="src/contract.rs" |
| 29 | + ... |
| 30 | + |
| 31 | + use cosmwasm_std::{ |
| 32 | +//diff-del |
| 33 | +- entry_point, to_json_binary, Binary, Deps, DepsMut, Env, MessageInfo, Response, StdResult, |
| 34 | +//diff-add-start |
| 35 | ++ entry_point, to_json_binary, Binary, Deps, DepsMut, Env, Event, MessageInfo, Response, |
| 36 | ++ StdResult, |
| 37 | +//diff-add-end |
| 38 | + }; |
| 39 | + |
| 40 | + ... |
| 41 | + |
| 42 | + fn execute_register(deps: DepsMut, info: MessageInfo, name: String) -> ContractResult { |
| 43 | + let key = name.as_bytes(); |
| 44 | +//diff-del |
| 45 | +- let record = NameRecord { owner: info.sender }; |
| 46 | +//diff-add-start |
| 47 | ++ let record = NameRecord { |
| 48 | ++ owner: info.sender.to_owned(), |
| 49 | ++ }; |
| 50 | +//diff-add-end |
31 | 51 |
|
32 | 52 | ... |
33 | 53 |
|
34 | | - fn execute_register(deps: DepsMut, info: MessageInfo, name: String) -> ContractResult { |
35 | | - let key = name.as_bytes(); |
36 | | - - let record = NameRecord { owner: info.sender }; |
37 | | - + let record = NameRecord { |
38 | | - + owner: info.sender.to_owned(), |
39 | | - + }; |
40 | | - |
41 | | - ... |
42 | | - |
43 | | - - Ok(Response::default()) |
44 | | - + let registration_event = Event::new("name-register") |
45 | | - + .add_attribute("name", name) |
46 | | - + .add_attribute("owner", info.sender); |
47 | | - + let resp = Response::default().add_event(registration_event); |
48 | | - + Ok(resp) |
49 | | - } |
| 54 | +//diff-del |
| 55 | +- Ok(Response::default()) |
| 56 | +//diff-add-start |
| 57 | ++ let registration_event = Event::new("name-register") |
| 58 | ++ .add_attribute("name", name) |
| 59 | ++ .add_attribute("owner", info.sender); |
| 60 | ++ let resp = Response::default().add_event(registration_event); |
| 61 | ++ Ok(resp) |
| 62 | +//diff-add-end |
| 63 | + } |
50 | 64 |
|
51 | | - ... |
52 | | - ``` |
53 | | -</CodeBlock> |
| 65 | + ... |
| 66 | +``` |
54 | 67 |
|
55 | 68 | Note that: |
56 | 69 |
|
57 | | -* You are free to choose any event name other than `name-register`. You ought to make it a visible constant too. |
58 | | -* The CosmWasm module will prefix it with `wasm-` before sending the event as a Cosmos one. |
59 | | -* You can add more attributes in your event if the need arises. |
60 | | -* You can add more events to the response if you need or want to. |
| 70 | +- You are free to choose any event name other than `name-register`. You ought to make it a visible constant too. |
| 71 | +- The CosmWasm module will prefix it with `wasm-` before sending the event as a Cosmos one. |
| 72 | +- You can add more attributes in your event if the need arises. |
| 73 | +- You can add more events to the response if you need or want to. |
61 | 74 |
|
62 | 75 | ## Adjust the unit test |
63 | 76 |
|
64 | 77 | The response has changed, so must the unit test: |
65 | 78 |
|
66 | | -<CodeBlock title="src/contract.rs"> |
67 | | - ```diff-rust |
68 | | - ... |
| 79 | +```rust title="src/contract.rs" |
| 80 | + ... |
69 | 81 |
|
70 | | - mod tests { |
| 82 | + mod tests { |
71 | 83 |
|
72 | | - ... |
73 | | - |
74 | | - - use cosmwasm_std::{testing, Addr, Binary, Response}; |
75 | | - + use cosmwasm_std::{testing, Addr, Binary, Event, Response}; |
76 | | - |
77 | | - ... |
| 84 | + ... |
78 | 85 |
|
79 | | - fn test_execute() { |
| 86 | +//diff-del |
| 87 | +- use cosmwasm_std::{testing, Addr, Binary, Response}; |
| 88 | +//diff-add |
| 89 | ++ use cosmwasm_std::{testing, Addr, Binary, Event, Response}; |
80 | 90 |
|
81 | | - ... |
| 91 | + ... |
82 | 92 |
|
83 | | - - assert_eq!(contract_result.unwrap(), Response::default()); |
84 | | - + let received_response = contract_result.unwrap(); |
85 | | - + let expected_event = Event::new("name-register") |
86 | | - + .add_attribute("name", name.to_owned()) |
87 | | - + .add_attribute("owner", mocked_addr.to_string()); |
88 | | - + let expected_response = Response::default().add_event(expected_event); |
89 | | - + assert_eq!(received_response, expected_response); |
| 93 | + fn test_execute() { |
90 | 94 |
|
91 | | - ... |
| 95 | + ... |
92 | 96 |
|
93 | | - } |
| 97 | +//diff-del |
| 98 | +- assert_eq!(contract_result.unwrap(), Response::default()); |
| 99 | +//diff-add-start |
| 100 | ++ let received_response = contract_result.unwrap(); |
| 101 | ++ let expected_event = Event::new("name-register") |
| 102 | ++ .add_attribute("name", name.to_owned()) |
| 103 | ++ .add_attribute("owner", mocked_addr.to_string()); |
| 104 | ++ let expected_response = Response::default().add_event(expected_event); |
| 105 | ++ assert_eq!(received_response, expected_response); |
| 106 | +//diff-add-end |
94 | 107 |
|
95 | 108 | ... |
96 | 109 |
|
97 | 110 | } |
98 | 111 |
|
99 | 112 | ... |
100 | | - ``` |
101 | | -</CodeBlock> |
| 113 | + |
| 114 | + } |
| 115 | + |
| 116 | + ... |
| 117 | +``` |
102 | 118 |
|
103 | 119 | Note that: |
104 | 120 |
|
105 | | -* The `assert_eq!` macro does a deep equal between the _received_ and _expected_ responses. |
106 | | -* Because you have only tested the function in isolation, the event name is not prefixed with `wasm-`. |
| 121 | +- The `assert_eq!` macro does a deep equal between the _received_ and _expected_ responses. |
| 122 | +- Because you have only tested the function in isolation, the event name is not prefixed with `wasm-`. |
107 | 123 |
|
108 | 124 | ## Adjust the mocked-app test |
109 | 125 |
|
110 | | -It too needs modifying: |
| 126 | +It needs modifying too: |
111 | 127 |
|
112 | | -<CodeBlock title="test/contract.rs"> |
113 | | - ```diff-rust |
114 | | - - use cosmwasm_std::Addr; |
115 | | - + use cosmwasm_std::{Addr, Event}; |
| 128 | +```rust title="test/contract.rs" |
| 129 | +//diff-del |
| 130 | +- use cosmwasm_std::Addr; |
| 131 | +//diff-add |
| 132 | ++ use cosmwasm_std::{Addr, Event}; |
116 | 133 |
|
117 | | - ... |
| 134 | + ... |
118 | 135 |
|
119 | | - fn test_register() { |
| 136 | + fn test_register() { |
120 | 137 |
|
121 | | - ... |
122 | | - |
123 | | - assert!(result.is_ok(), "Failed to register alice"); |
124 | | - - let received_response = result.unwrap(); |
125 | | - + let expected_event = Event::new("wasm-name-register") |
126 | | - + .add_attribute("name", name_alice.to_owned()) |
127 | | - + .add_attribute("owner", owner_addr_value.to_owned()); |
128 | | - + received_response.assert_event(&expected_event); |
129 | | - + assert_eq!(received_response.data, None); |
| 138 | + ... |
130 | 139 |
|
131 | | - ... |
| 140 | + assert!(result.is_ok(), "Failed to register alice"); |
| 141 | +//diff-del |
| 142 | +- let received_response = result.unwrap(); |
| 143 | +//diff-add-start |
| 144 | ++ let expected_event = Event::new("wasm-name-register") |
| 145 | ++ .add_attribute("name", name_alice.to_owned()) |
| 146 | ++ .add_attribute("owner", owner_addr_value.to_owned()); |
| 147 | ++ received_response.assert_event(&expected_event); |
| 148 | ++ assert_eq!(received_response.data, None); |
| 149 | +//diff-add-end |
| 150 | + ... |
132 | 151 |
|
133 | | - } |
| 152 | + } |
134 | 153 |
|
135 | | - ... |
136 | | - ``` |
137 | | -</CodeBlock> |
| 154 | + ... |
| 155 | +``` |
138 | 156 |
|
139 | 157 | Note that: |
140 | 158 |
|
141 | | -* Here, the received response is of type `AppResponse`, which contains your new event, and may eventually contain other events that would be emitted by other smart contracts that may have been called as part of `ExecuteMsg::Register`. |
142 | | -* This time, the mocked app prefixed the event with `wasm-`. |
143 | | -* The response has an `assert_event` function that calls `assert!` and `has_event` with a nice message so that you don't have to write it yourself. |
| 159 | +- Here, the received response is of type `AppResponse`, which contains your new event, and may eventually contain |
| 160 | + other events that would be emitted by other smart contracts that may have been called as part of `ExecuteMsg::Register`. |
| 161 | +- This time, the mocked app prefixed the event with `wasm-`. |
| 162 | +- The response has an `assert_event` function that calls `assert!` and `has_event` with a nice message |
| 163 | + so that you don't have to write it yourself. |
144 | 164 |
|
145 | 165 | ## Conclusion |
146 | 166 |
|
147 | 167 | There is more to execution responses than events, as you will learn in subsequent sections. |
148 | 168 |
|
149 | | -<HighlightBox type="info" title="Exercise progression"> |
| 169 | +:::info Exercise progression |
150 | 170 |
|
151 | | -At this stage, you should have something similar to the [`first-event`](https://github.com/b9lab/cw-my-nameservice/tree/first-event) branch, with [this](https://github.com/b9lab/cw-my-nameservice/compare/first-multi-test..first-event) as the diff. |
| 171 | +At this stage, you should have something similar to the |
| 172 | +[`first-event`](https://github.com/b9lab/cw-my-nameservice/tree/first-event) branch, |
| 173 | +with [this](https://github.com/b9lab/cw-my-nameservice/compare/first-multi-test..first-event) as the diff. |
152 | 174 |
|
153 | | -</HighlightBox> |
| 175 | +::: |
0 commit comments