[Ethereum] How does one dynamically craft message data for a transaction in Solidity

solidity

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 into address.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 and decode functions that will do this encoding for you.

Related Topic