clone_cw_multi_test/
addresses.rs

1//! # Implementation of address generators
2
3use crate::error::AnyResult;
4use crate::prefixed_storage::prefixed_read;
5use crate::wasm::{CONTRACTS, NAMESPACE_WASM};
6use cosmwasm_std::{Addr, Api, CanonicalAddr, HexBinary, Order, Storage};
7
8/// Common address generator interface.
9///
10/// The default implementation of this trait generates fully predictable
11/// addresses, no matter if [contract_address](AddressGenerator::contract_address)
12/// or [predictable_contract_address](AddressGenerator::predictable_contract_address) is used,
13/// but users should not make any assumptions about the value of the generated address.
14pub trait AddressGenerator {
15    #[deprecated(
16        since = "0.18.0",
17        note = "use `contract_address` or `predictable_contract_address` instead; will be removed in version 1.0.0"
18    )]
19    fn next_address(&self, storage: &mut dyn Storage) -> Addr {
20        //TODO After removing this function in version 1.0, make `CONTRACTS` and `NAMESPACE_WASM` private in `wasm.rs`.
21        let count = CONTRACTS
22            .range_raw(
23                &prefixed_read(storage, NAMESPACE_WASM),
24                None,
25                None,
26                Order::Ascending,
27            )
28            .count();
29        Addr::unchecked(format!("contract{}", count))
30    }
31
32    /// Generates a _non-predictable_ contract address, just like the real-life chain
33    /// returns contract address after its instantiation.
34    /// Address generated by this function is returned as a result of processing
35    /// `WasmMsg::Instantiate` message.
36    ///
37    /// The default implementation generates a contract address based
38    /// on contract's instance identifier only.
39    ///
40    /// # Example
41    ///
42    /// ```
43    /// # use cosmwasm_std::testing::{MockApi, MockStorage};
44    /// # use cw_multi_test::{AddressGenerator, SimpleAddressGenerator};
45    /// # let api = MockApi::default();
46    /// # let mut storage = MockStorage::default();
47    /// struct MyAddressGenerator;
48    ///
49    /// impl AddressGenerator for MyAddressGenerator {}
50    ///
51    /// let my_address_generator = MyAddressGenerator{};
52    ///
53    /// let addr = my_address_generator.contract_address(&api, &mut storage, 100, 0).unwrap();
54    /// assert_eq!(addr.to_string(),"contract0");
55    ///
56    /// let addr = my_address_generator.contract_address(&api, &mut storage, 100, 1).unwrap();
57    /// assert_eq!(addr.to_string(),"contract1");
58    ///
59    /// let addr = my_address_generator.contract_address(&api, &mut storage, 200, 5).unwrap();
60    /// assert_eq!(addr.to_string(),"contract5");
61    ///
62    /// let addr = my_address_generator.contract_address(&api, &mut storage, 200, 6).unwrap();
63    /// assert_eq!(addr.to_string(),"contract6");
64    /// ```
65    fn contract_address(
66        &self,
67        _api: &dyn Api,
68        _storage: &mut dyn Storage,
69        _code_id: u64,
70        instance_id: u64,
71    ) -> AnyResult<Addr> {
72        Ok(Addr::unchecked(format!("contract{instance_id}")))
73    }
74
75    /// Generates a _predictable_ contract address, just like the real-life chain
76    /// returns contract address after its instantiation using `MsgInstantiateContract2` message.
77    /// Address generated by this function is returned as a result of processing
78    /// `WasmMsg::Instantiate2` message.
79    ///
80    /// The default implementation generates a contract address based on provided salt only.
81    ///
82    /// # Example
83    ///
84    /// ```
85    /// # use cosmwasm_std::Api;
86    /// # use cosmwasm_std::testing::{MockApi, MockStorage};
87    /// # use cw_multi_test::{AddressGenerator, SimpleAddressGenerator};
88    /// # let api = MockApi::default();
89    /// # let mut storage = MockStorage::default();
90    /// # let creator = api.addr_canonicalize("creator").unwrap();
91    /// struct MyAddressGenerator;
92    ///
93    /// impl AddressGenerator for MyAddressGenerator {}
94    ///
95    /// let my_address_generator = MyAddressGenerator{};
96    ///
97    /// let addr = my_address_generator.predictable_contract_address(&api, &mut storage, 100, 0, &[0], &creator, &[0]).unwrap();
98    /// assert_eq!(addr.to_string(),"contract00");
99    ///
100    /// let addr = my_address_generator.predictable_contract_address(&api, &mut storage, 100, 1, &[1], &creator, &[0]).unwrap();
101    /// assert_eq!(addr.to_string(),"contract00");
102    ///
103    /// let addr = my_address_generator.predictable_contract_address(&api, &mut storage, 200, 0, &[2], &creator, &[1]).unwrap();
104    /// assert_eq!(addr.to_string(),"contract01");
105    ///
106    /// let addr = my_address_generator.predictable_contract_address(&api, &mut storage, 200, 1, &[3], &creator, &[1]).unwrap();
107    /// assert_eq!(addr.to_string(),"contract01");
108    /// ```
109    fn predictable_contract_address(
110        &self,
111        _api: &dyn Api,
112        _storage: &mut dyn Storage,
113        _code_id: u64,
114        _instance_id: u64,
115        _checksum: &[u8],
116        _creator: &CanonicalAddr,
117        salt: &[u8],
118    ) -> AnyResult<Addr> {
119        Ok(Addr::unchecked(format!(
120            "contract{}",
121            HexBinary::from(salt).to_hex()
122        )))
123    }
124}
125
126/// Default contract address generator used in [WasmKeeper](crate::WasmKeeper).
127pub struct SimpleAddressGenerator;
128
129impl AddressGenerator for SimpleAddressGenerator {}