Closed loloicci closed 2 years ago
In the traditional way, the callee contract address is specified with storage value. The key of the address in storage is specified in the dynamic link macro.
// import
#[dynamic_link(contract_name = "callee_contract")]
extern "C" {
fn pong(a: u64) -> u64;
}
// specify cellee contract + call
fn some_func(deps: DepsMut){
// specify callee contract
deps.storage.set(b"callee_contract", &to_vec("address1")?);
// call "address1"'s pong
let ret1 = pong(42);
// change callee contract
deps.storage.set(b"callee_contract", &to_vec("address2")?);
// call "address2"'s pong
let ret2 = pong(42);
// change callee contract
deps.storage.set(b"callee_contract", &to_vec("address1")?);
// call "address1"'s pong using ret2
let ret3 = pong(ret2);
}
In this way, which contract is called is dependent on a value in storage. So, the value must be renewed each time another contract is called. And, the same pong
returns different values depending on storage status (sometimes it looks strange.)
In the example contract, the importing is https://github.com/line/cosmwasm/blob/4a4e15573f061a90788d955ad25664967c97d756/contracts/dynamic-caller-contract/src/contract.rs#L22-L30 and the specifying address is https://github.com/line/cosmwasm/blob/4a4e15573f061a90788d955ad25664967c97d756/contracts/dynamic-caller-contract/src/contract.rs#L41-L42. (But, it uses only one contract, so it may looks having few problems.)
My suggestion is make the callee contract represented with a struct in following way:
use cosmwasm_std::{Addr, Contract};
#[derive(Contract)]
struct CalleeContract {
pub address: Addr;
}
#[dynamic_link(CalleeContract)]
trait Callee: Contract {
fn pong(&self, a: u64) -> u64;
}
// specify callee contract + call
fn some_func(){
// specify callee contract
let contract1 = Callee { address: Addr::unchecked("address1") };
// specify another calle contract
let contract2 = Callee { address: Addr::unchecked("address2") };
// call "address1"'s pong
let ret1 = contract1.pong(42);
// call "address2"'s pong
let ret2 = contract2.pong(42);
// call "address1"'s pong using ret2
let ret3 = contract1.pong(ret2);
}
closed via #215
Now, the callee contract is specified by storage value. Reconsider it and compare it with other ways, for example specifying by parameter or macro.