Background
I have two contracts A and B, I can do cross-contract call from A to B, or from B to A. But it failed when I try to do cross-contract call like this: A -> B -> A.
Test code
I developed a contract for test, repo is https://github.com/hthuang996/test/tree/main/ink/flipper. There are four methods.
#[ink(message)]
pub fn send_message(&mut self, addr1: AccountId, addr2: AccountId, m: u8) {
ink_env::call::build_call::<ink_env::DefaultEnvironment>()
.call_type(
ink_env::call::Call::new()
.callee(addr1)
.gas_limit(0)
.transferred_value(0))
.exec_input(
// call receive_message
ink_env::call::ExecutionInput::new(ink_env::call::Selector::new([0x3a, 0x6e, 0x96, 0x96]))
.push_arg(addr2)
.push_arg(m)
)
.returns::<()>()
.fire().
unwrap();
}
#[ink(message)]
pub fn receive_message(&mut self, addr: AccountId, i: u8) {
self.message = i;
ink_env::call::build_call::<ink_env::DefaultEnvironment>()
.call_type(
ink_env::call::Call::new()
.callee(addr)
.gas_limit(0)
.transferred_value(0))
.exec_input(
// call receive_message2
ink_env::call::ExecutionInput::new(ink_env::call::Selector::new([0x03, 0x0e, 0x11, 0xd0]))
.push_arg(i)
)
.returns::<()>()
.fire().
unwrap();
}
#[ink(message)]
pub fn receive_message2(&mut self, i: u8) {
self.message = i;
}
#[ink(message)]
pub fn get_message(& self) -> u8 {
self.message
}
Test step
Here I use substrate-contracts-node.
Step 1
Build the contract.
Step 2
Deploy three contracts named A, B, C with the same wasm file.
Step 3
Call send_message
of A, params are B, A, 8
.
Result
The transaction failed.
But If I change 3 as shown below:
Call send_message
of A, params are B, C, 8
.
The transaction was successful, and get_message
of B, C were both 8
.
Question
Is there any error in my code, or the circular call between multi contracts is impossible in ink!?