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