pub fn build_call<E>() -> CallBuilder<E, Unset<Call>, Unset<ExecutionInput<EmptyArgumentList>>, Unset<ReturnType<()>>>where
E: Environment,
Expand description
Returns a new CallBuilder
to build up the parameters to a cross-contract call.
§Example
Note: The shown examples panic because there is currently no cross-calling support in the off-chain testing environment. However, this code should work fine in on-chain environments.
§Example 1: No Return Value
The below example shows calling of a message of another contract that does not return any value back to its caller. The called function:
- has a selector equal to
0xDEADBEEF
- is provided with 5000 units of gas for its execution
- is provided with 10 units of transferred value for the contract instance
- receives the following arguments in order 1. an
i32
with value42
2. abool
with valuetrue
3. an array of 32u8
with value0x10
type AccountId = <DefaultEnvironment as Environment>::AccountId;
build_call::<DefaultEnvironment>()
.call(H160::from([0x42; 20]))
.ref_time_limit(5000)
.transferred_value(ink::U256::from(10))
.exec_input(
ExecutionInput::new(Selector::new([0xDE, 0xAD, 0xBE, 0xEF]))
.push_arg(42u8)
.push_arg(true)
.push_arg(&[0x10u8; 32]),
)
.returns::<()>()
.invoke();
§Example 2: With Return Value
The below example shows calling of a message of another contract that does
return a i32
value back to its caller. The called function:
- has a selector equal to
0xDEADBEEF
- is provided with 5000 units of gas for its execution
- is provided with 10 units of transferred value for the contract instance
- receives the following arguments in order 1. an
i32
with value42
2. abool
with valuetrue
3. an array of 32u8
with value0x10
let my_return_value: i32 = build_call::<DefaultEnvironment>()
.call_type(Call::new(ink::H160::from([0x42; 20])))
.ref_time_limit(5000)
.transferred_value(ink::U256::from(10))
.exec_input(
ExecutionInput::new(Selector::new([0xDE, 0xAD, 0xBE, 0xEF]))
.push_arg(42u8)
.push_arg(true)
.push_arg(&[0x10u8; 32]),
)
.returns::<i32>()
.invoke();
§Example 3: Delegate call
Note: The shown example panics because there is currently no delegate calling support in the off-chain testing environment. However, this code should work fine in on-chain environments.
use ink::H160;
let my_return_value: i32 = build_call::<DefaultEnvironment>()
.delegate(H160::zero())
.exec_input(
ExecutionInput::new(Selector::new([0xDE, 0xAD, 0xBE, 0xEF]))
.push_arg(42u8)
.push_arg(true)
.push_arg(&[0x10u8; 32])
)
.returns::<i32>()
.invoke();
§Handling LangError
s
It is also important to note that there are certain types of errors which can happen
during cross-contract calls which can be handled know as
[LangError
][ink_primitives::LangError
].
If you want to handle these errors use the CallBuilder::try_invoke
methods instead
of the CallBuilder::invoke
ones.
Note: The shown examples panic because there is currently no cross-calling support in the off-chain testing environment. However, this code should work fine in on-chain environments.
§Example: Handling a LangError
type AccountId = <DefaultEnvironment as Environment>::AccountId;
let call_result = build_call::<DefaultEnvironment>()
.call(H160::from([0x42; 20]))
.ref_time_limit(5000)
.transferred_value(ink::U256::from(10))
.try_invoke()
.expect("Got an error from the Contract's pallet.");
match call_result {
Ok(_) => unimplemented!(),
Err(e @ ink_primitives::LangError::CouldNotReadInput) => unimplemented!(),
Err(_) => unimplemented!(),
}