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 {}