Reading through the ink source code (here), my understanding is that a contract call is the selector concatenated with any arguments to the function.
From a Substrate runtime module test, I use the CallData builder which does as described
let mut call = CallData::new( Selector::from_str("foo") );
call.push_arg(&0);
And then make the call through the contracts frame module
let res = <contracts::Module<Test>>::bare_call(
ALICE,
contract_addr,
0,
100_000,
//codec::Encode::encode(&call.to_bytes().to_vec()));
call.to_bytes().to_vec());
To a contract function signature of
fn foo(&self, x: AccountId)
This returns a successful execution (Ok(())
) but does not invoke the contract function.
It's worth saying that the test is using type AccountId = u64
and ink uses a struct AccountId([u8;32])
, but I've tried passing as 32 bytes and it hasn't made a difference.
I've verified that the surrounding test code should work by calling a wasm program written in wat here, which is able to call the exported "call" without passing any parameters.
The complete repositories are also on github for the module and the contract.