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
ispublic
andmyFuncA
+myFuncB
are alsopublic
.- 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!
address(this).call(abi.encodePacked(selector, <func-args>))
? – HemphillmyDynamicFunc2
, in same link above), and looks like: (1) the return value isbytes memory
, which can't be easily typecast to intended type, and (2) requires an additionalrequire()
... which is less than ideal from a gas point of view (should experiment to verify, but that's another question). – Stabilizerpure
orview
function then, they can be called off-chain viaeth_call
so in this case there is no need for gas optimization. However, I assume that here is no such case. Am I right? – Hemphill