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