In the latest master of Ink! examples there is only one main contract, delegator
, for understanding cross-contract calls. Unfortunately, there are no tests either for this system.
Cross-contract calling seems to rest on the ContractRef
pattern where the ContractRef
s are instantiated in the base contract's constructor.
#[ink(storage)]
pub struct Delegator {
/// Says which of `adder` or `subber` is currently in use.
which: Which,
/// The `accumulator` smart contract.
accumulator: AccumulatorRef,
/// The `adder` smart contract.
adder: AdderRef,
/// The `subber` smart contract.
subber: SubberRef,
}
...
impl Delegator {
/// Instantiate a `delegator` contract with the given sub-contract codes.
#[ink(constructor)]
pub fn new(
init_value: i32,
version: u32,
accumulator_code_hash: Hash,
adder_code_hash: Hash,
subber_code_hash: Hash,
) -> Self {
let total_balance = Self::env().balance();
let salt = version.to_le_bytes();
let accumulator = AccumulatorRef::new(init_value)
.endowment(total_balance / 4)
.code_hash(accumulator_code_hash)
.salt_bytes(salt)
.instantiate()
.unwrap_or_else(|error| {
panic!(
"failed at instantiating the Accumulator contract: {:?}",
error
)
});
let adder = AdderRef::new(accumulator.clone())
.endowment(total_balance / 4)
.code_hash(adder_code_hash)
.salt_bytes(salt)
.instantiate()
.unwrap_or_else(|error| {
panic!("failed at instantiating the Adder contract: {:?}", error)
});
let subber = SubberRef::new(accumulator.clone())
.endowment(total_balance / 4)
.code_hash(subber_code_hash)
.salt_bytes(salt)
.instantiate()
.unwrap_or_else(|error| {
panic!("failed at instantiating the Subber contract: {:?}", error)
});
Self {
which: Which::Adder,
accumulator,
adder,
subber,
}
}
...
}
For testing, how does one create code hashes to instantiate the main contract that will delegate calls downstream?