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 130 131 132 133 134
//! # 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"
)]
/// Generates a _non-predictable_ contract address based on the number of contract's instances.
/// This is a simplified version of simulating contract addresses that is deprecated in favour of
/// [contract_address](Self::contract_address) and
/// [predictable_contract_address](Self::predictable_contract_address) functions.
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 abstract_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 abstract_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/{}/{}",
api.addr_humanize(creator)?,
HexBinary::from(salt).to_hex()
)))
}
}
/// Default contract address generator used in [WasmKeeper](crate::WasmKeeper).
pub struct SimpleAddressGenerator;
impl AddressGenerator for SimpleAddressGenerator {}