In Solidity, one can create a bytes array and then use address.call(bytesData) to create a new transaction matching a function signature, as well as passing through the arguments.
One can do address.call(bytes4(bytes32(sha3("someFunction(uint256,address)"))), 10, 0x42)
for example. One can dynamically craft the function signature by just passing another bytes variable. But how does one make it possible to have dynamic arguments as well?
Something like this. But functionSig & encoded_params are created IN Solidity.
function doSomething() {
if(someCondition) {
bytes memory data = functionSig + encoded_params.
toAddress.call(data);
}
}
I want to be able to IN Solidity craft this. Not from the outside using web3 or some of the other encoding functions? Is there an easy way to do this? Or should a Solidity encoding function be written that converts the arguments to bytes and creates this message data?
Best Answer
To do this you will need to implement the appropriate RLP encoding for the arguments you wish to pass.
RLP Spec: https://github.com/ethereum/wiki/wiki/RLP
For simple non-array fixed length types this is as simple as just concatenating the
func_sig + arg_1_as_bytes + arg_2_as_bytes
into a single bytes value and passing this intoaddress.call(...)
.For complex types like arrays,
bytes
,string
or structs, you will have to do more complex things to construct the appropriate RLP bytes representation for your data.There is a story in the solidity pivotal tracker to create
encode
anddecode
functions that will do this encoding for you.