0

I would like to have a contract MainContract that can call any other contract functions depending on arguments given a MainContract function. It would look like this:

pragma solidity 0.8.16;

contract MainContract{

    function callAnotherFunctionOfAnyContract(bytes[] calldata neededData, ..?) public {
        //Use neededData to call the described function (anyFunction in this example)
    }
}

contract AnyOtherContract{
    MainContract mainContract = MainContract(0x...)

    function callMainContract() public {
        bytes[] memory neededData;
        neededData = ??; //Set neededData so that it calls the anyFunction below from the mainContract
        mainContract.callAnotherFunctionOfAnyContract(neededData, ..?);
    }

    function anyFunction(address parameter1, uint256 parameter2, ...) public {
        //Do something
    }
}

So what I'm looking for is a way for the callMainContract function to provide callAnotherFunctionOfAnyOtherContract what it needs to call the anyFunction from there, and for the callAnotherFunctionOfAnyOtherContract function to finally call anyFunction. Note that in this case the anyFunction is in the same contract as the initial function, but that is just to simplify the example, it could be from any other deployed contract. The important point is that there is no need for the MainContract to know the contract it's calling (if that is even possible in current Solidity), so it can work with any contract as long as the correct data is provided.

2 Answers 2

1

You can put all the needed parameters for the call in a bytes neededData argument, then make the call like this:

(bool success, ) = targetContract.call(neededData);

To encode neededData you can use abi.encodeWithSignature(), like so:

pragma solidity 0.8.16;

contract MainContract{

    function callAnotherFunctionOfAnyContract(address targetContract, bytes calldata neededData) public {
        (bool success, ) = targetContract.call(neededData);
        require(success, "Call failed");
    }
}

contract AnyOtherContract{
    MainContract mainContract = MainContract(0x...)

    function callMainContract() public {
        address targetContract = ...;  // the contract to call

        address param1 = ...; uint256 param2 = ...;
        bytes memory neededData = abi.encodeWithSignature("anyFunction(address,uint256)", param1, param2);
        mainContract.callAnotherFunctionOfAnyContract(targetContract, neededData);
    }

    function anyFunction(address parameter1, uint256 parameter2) public {
        //Do something
    }
}
1
  • 1
    Exactly what I was looking for. Thank you for the help!
    – Pacdac
    Oct 18, 2023 at 11:56
1

As anyFunction() can be a function of any contract, so you need to have address of that contract. Seems like neededData provided by callMainContract should have an address field which will be the contract address of target contract with anyFunction. So lets say there is a TargetContract which has anyFunction then code required... Now in MainContract -

function callAnotherFunctionOfAnyContract(bytes[] calldata neededData, ..?) public {
        (address targetContract, address parameter1, uint256 parameter2, ...) = abi.decode(neededData, (address, address, uint256, ...));
        TargetContract targetContractInstance = TargetContract(targetContract);
        targetContractInstance.anyFunction(parameter1,parameter2, ...); 
    }

Note: anyFunction definition in targetContract should be fixed ie the number of parameters it has cant be dynamic, as you will also be required to provide interface for anyFunction's targetContract.

2
  • Thanks for the answer. My goal is to avoid the need of knowing the other contract. So I wanted to know if it was possible to do so without having the other contract interface, by providing everything in the callAnotherFunctionOfAnyContract arguments (which function to call, from which contract and with which argument(s)), so that literally any contract function could be executed by going through the MainContract.
    – Pacdac
    Oct 18, 2023 at 9:54
  • ok... now i get it. Happy to see you found your answer
    – Harsh
    Oct 19, 2023 at 17:52

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.