Complex state and maps
In more complex solutions, it may be necessary to store additional information. One option is to serialize extensive JSON data structures, allowing data retrieval through key-value pairs. In the context of CW20, associating addresses with their CW20 balances is achieved using a Map data structure:
pub const BALANCES: Map<&Addr, Uint128> = Map::new("balance");
The code for this can be found here.
The following presents an example of interacting with the BALANCES map value, as seen here. The relevant code snippet is:
let rcpt_addr = deps.api.addr_validate(&recipient)?;
BALANCES.update(
deps.storage,
&info.sender,
|balance: Option<Uint128>| -> StdResult<_> {
Ok(balance.unwrap_or_default().checked_sub(amount)?)
},
)?;
There's a lot happening here, so let's break it down:
- deps.storage is provided as an input. This is from the contract context. deps is similar to ctx you may have encountered in the Cosmos SDK.
- &rcpt_addr is a borrowed reference to the validated recipient address. It has been verified and is valid, or else the let statement would have raised an error. This represents the key in the key/value pair.
- The third statement is an anonymous function (lambda) that returns StdResult and performs some computation based on the current value of balance. balance represents the value in the key/value pair, and &rcpt_addr is the key.
For more advanced usage, including indexing and additional features, refer to: