How do you test cross-contract calling with Substrate using `ink!`?

300 views Asked by At

Given a 2-contract Substrate blockchain written using ink!, how can I run a unit test which instantiates both contracts?

The "root" MyContract

use ink_storage::Lazy;
use other_contract::OtherContract;

//--snip--
#[ink(storage)]
struct MyContract {
    /// The other contract.
    other_contract: Lazy<OtherContract>,
}

impl MyContract {
    /// Instantiate `MyContract with the given
    /// sub-contract codes and some initial value.
    #[ink(constructor)]
    pub fn new(
        other_contract_code_hash: Hash,
    ) -> Self {
        let other_contract = OtherContract::new(1337)
            .endowment(total_balance / 4)
            .code_hash(other_contract_code_hash)
            .instantiate()
            .expect("failed at instantiating the `OtherContract` contract");
        Self {
            other_contract
        }
    }

    /// Calls the other contract.
    #[ink(message)]
    pub fn call_other_contract(&self) -> i32 {
        self.other_contract.get_value()
    }
}
//--snip--

The OtherContract

#[ink::contract]
pub mod other_contract {
    /// Storage for the other contract.
    #[ink(storage)]
    pub struct OtherContract {
        value: i32,
    }

    impl OtherContract {
        /// Initializes the contract.
        #[ink(constructor)]
        pub fn new(value: i32) -> Self {
            Self { value }
        }

        /// Returns the current state.
        #[ink(message)]
        pub fn get_value(&self) -> i32 {
            self.value
        }
    }
}

The delegator example also represents a playground for multiple contracts.

1

There are 1 answers

0
Karel Kubat On

You cannot unit test this with the regular testing framework yet. https://redspot.patract.io/en/ is a framework which allows you to write integratiation tests.