Search code examples
blockchainethereumsoliditysmartcontractsrsk

Call solidity function dynamically, based on its bytes4 function selector


In a smart contract, let's say I have a function which wants to invoke another function dynamically, based on some internal logic. Here it obtains the function selector as a bytes4 variable.

After which it is possible to use branching logic to invoke one of the target functions. See: (A)

However, is it possible to avoid that and invoke the function selector directly? See: (B)

function myDynamicFunc(uint256 someParam) public {
    bytes4 selector = /* ... some internal logic ... */

    if (selector == this.myFuncA.selector) {
      myFuncA(someParam);
    } else if (selector == this.myFuncB.selector) {
      myFuncB(someParam);
    }
    // (A) instead of something like this ^ branching logic (which works)

    selector.invoke(someParam);
    // (B) can something like this ^ instead by calling the selector directly instead (does not work)
}


Details

  • myDynamicFunc is public and myFuncA+myFuncB are also public.
  • All 3 functions are implemented in the same smart contract.

Notes

I have written up an answer expanding on @kj-crypto's suggestion in the comments. If there is another way to accomplish the above without using address(this).call(...), I'm all ears!


Solution

  • Regarding option B:

    • Using call will return a bytes object, which then should you convert to appropiate type, in this case to an integer. (extra gas usage)
    • To use call, you need to pack the selector and the parameters (extra gas usage)

    As long as you are using a function in the same contract, there is no point to use its abi specification, because you already now where the function is, how is it defined and you can call it without any hassle.