Solidity Functions – How to Pass a Function as a Parameter in Solidity

abicontract-designcontract-developmentcontract-invocationsolidity

Can you pass a function as a parameter in Solidity?

My guess: There is the concept of address in Solidity, but they represent contracts. Contracts can have fallback functions, but I don't think you can give them parameters. Thinking about passing the function as a parameter by address like you would do in C.

Is there a legit way to pass functions as parameters, or if not, is there a hacky way?

If there is, how? And if there isn't, why not?

Best Answer

Functions (aka Methods) are specified by the ABI, and have a Method ID, which is the first 4 bytes of the sha3 (Keccak-256) of the method's signature.

Here's an example of invoking someFunction on contract: contract.call(bytes4(sha3("someFunction()")))

Here is a tested function with passing a methodId as a parameter:

contract C1 {
    uint public _n;  // public just for easy inspection in Solidity Browser

    function foo(uint n) returns(uint) {
        _n = n;
        return _n;
    }

    function invoke(bytes4 methodId, uint n) returns(bool) {
        return this.call(methodId, n);
    }
}

Test it in Solidity Browser by using "0x2fbebd38", 9 as the parameters to invoke, then see that _n equals 9.

Notes:

  • 0x2fbebd38 is the result of bytes4(sha3("foo(uint256)")) (don't forget the need to use canonical types, in this case uint256, per the ABI.)

  • Return values from call and callcode are boolean, either the call succeeded or the call failed. It is not possible to return a value from call since that would require the contract to know the return type beforehand.