The problem here is that Solidity call encoder have troubles in encoding dynamic arrays. Here is the example to illustrate this, assuming you have an instance of your first contract in web3.eth:
console.log(settingContract.set.getData([10]));
0x6ea9bfc5
0000000000000000000000000000000000000000000000000000000000000020
0000000000000000000000000000000000000000000000000000000000000001
000000000000000000000000000000000000000000000000000000000000000a
This is the correct encoding of set function invocation. Here you can see the function signature 0x6ea9bfc5
, a pointer to the length of the array 0x20
(in that case, the size of the pointer itself which is 32 bytes), length of the array 0x1
which is 1 (single 32 bytes word), and 0xa
which is the value of the first element 10.
Now let's see what call
will produce assuming the same input:
Debug(bytes data);
function () {
Debug(data);
}
function setIt(uint256[] _values) returns(bool) {
return address(this).call(bytes4(sha3("set(uint256[])")), _values);
}
// Data of Debug event log from receipt of calling contract.setIt([10]);
0x6ea9bfc5
000000000000000000000000000000000000000000000000000000000000000a
This is incorrect encoding, Solidity encodes it as a fixed size uint256[1] array.
In order to overcome this problem, you can put dynamic array prefixes yourself:
function setIt(uint256[] _values) returns(bool) {
return address(this).call(
bytes4(sha3("set(uint256[])")),
uint256(32), // pointer to the length of the array
uint256(_values.length), // length of the array
_values // array itself
);
}
Now it will work as expected. Nevertheless I think this is a compiler bug, so I will report it.
See more details and examples in the ABI specification: http://solidity.readthedocs.io/en/develop/abi-spec.html#use-of-dynamic-types.