I learned from this documentation https://docs.soliditylang.org/en/v0.8.15/contracts.html and this discussion How to use address.call{}() in solidity about abi.encodeWithSignature() .

I have question about this snippet below.

contract TestPayable {
uint x;
uint y;
// This function is called for all messages sent to
// this contract, except plain Ether transfers
// (there is no other function except the receive function).
// Any call with non-empty calldata to this contract will execute
// the fallback function (even if Ether is sent along with the call).
fallback() external payable { x = 1; y = msg.value; }

// This function is called for plain Ether transfers, i.e.
// for every call with empty calldata.
receive() external payable { x = 2; y = msg.value; }

Then we have the caller

contract Caller {

function callTestPayable(TestPayable test) public returns (bool) {
    (bool success,) = address(test).call(abi.encodeWithSignature("nonExistingFunction()"));
    // results in test.x becoming == 1 and test.y becoming 0.
    (success,) = address(test).call{value: 1}(abi.encodeWithSignature("nonExistingFunction()"));
    // results in test.x becoming == 1 and test.y becoming 1.
    return true;
  1. I am wondering this line (bool success,) = address(test).call(abi.encodeWithSignature("nonExistingFunction()"));

    What could come after the comma (bool success, **What other parameters could fit here?**)?

  2. If that line only returns bool success , then why we need to put it in a bracket with comma (bool success,)? Why can't we just put bool success = address(test).call(abi.encodeWithSignature("nonExistingFunction()"));

  3. Is nonExistingFunction() a default reserved function name to call no-name fallback function from other smart contract?

I can't find this information in the official documentation.

2 Answers 2

  1. This is low level call. you can call a function directly and with call function (it is preferred to import the interface of the contract to call functions on it). recommended that call is used to call the fallback and receive functions of the contract.
  2. because it returns a tuple. The return value for the call function is a tuple of a bool and bytes array. The first one is the status of the call and the bytes array has the return values of the contract function called.(see this)
  3. No. This is a function name that does not exist :) if your msg.data (first call paramateter) is empty then call receive() and for any Unmatched data call fallback().see this
  1. it also returns bytes, but often the coder isn't interested in the return data, so omits as in your example. Otherwise, something like this e.g.

    (bool success, bytes memory retData) = msg.sender.call{ ...

  2. see 1.

  3. no, not a reserved name, just a meaningful name for the example. anything that didn't match a function name would have worked just as well

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.