3
pragma solidity ^0.5.3;

contract SimpleFallback{
    event FallbackCalledEvent(bytes data);
    event AddEvent(uint a, uint b, uint result);
    event DoubleEvent(uint a, uint b);
    event GetNameEvent(string);

    function() external{
        emit FallbackCalledEvent(msg.data);
    }

    function add(uint a, uint b) public returns(uint){
        // assert(a >= 0);
        // assert(b >= 0);
        // assert(a + b > a && a + b > b);

        uint _result = a + b;
        emit AddEvent(a, b, _result);

        return _result;
    }

    function double(uint a) public returns(uint){
        // assert(a >= 0);
        // assert(2*a >= 0 && 2*a >= a);
        uint _result = 2*a;

        emit DoubleEvent(a, _result);

        return _result;
    }

    function getName(string memory name) public returns(string memory){
        emit GetNameEvent(name);

        return name;
    }
}


contract RunTest{


    function callAddlTest(address other) public {
        // bytes4 messageId = bytes4(keccak256("add(uint, uint)"));
        // other.call(messageId, 5, 60);
        other.call(abi.encodeWithSignature("add(uint,uint)", 85, 60));
    }

    function callDoublelTest(address other) public {
        // bytes4 messageId = bytes4(keccak256("add(uint, uint)"));
        // other.call(messageId, 5, 60);
        other.call(abi.encodeWithSignature("double(uint)", 100));
    }

    function callgetNameTest(address other) public{
        other.call(abi.encodeWithSignature("getName(string)", "hello"));
    }
}

Operation as below.

  • Step 1. deploy 2 contracts;
  • Step 2. call callAddlTest whit contract SimpleFallback's address, event log is as below, which showed that called add() failed, the fallback function was triggered.
[
    {
        "from": "0x038f160ad632409bfb18582241d9fd88c1a072ba",
        "topic": "0x5cd57a899be814fb3a40e18f9d1ba77420bbd22073d35165511f750aa70538b6",
        "event": "FallbackCalledEvent",
        "args": {
            "0": "0xb89663520000000000000000000000000000000000000000000000000000000000000055000000000000000000000000000000000000000000000000000000000000003c",
            "data": "0xb89663520000000000000000000000000000000000000000000000000000000000000055000000000000000000000000000000000000000000000000000000000000003c",
            "length": 1
        }
    }
]
  • Step 3. call callDoubleTest whit contract SimpleFallback's address, event log is as below, which showed that called double() failed, the fallback function was triggered.
[
    {
        "from": "0x038f160ad632409bfb18582241d9fd88c1a072ba",
        "topic": "0x5cd57a899be814fb3a40e18f9d1ba77420bbd22073d35165511f750aa70538b6",
        "event": "FallbackCalledEvent",
        "args": {
            "0": "0xd524bc570000000000000000000000000000000000000000000000000000000000000064",
            "data": "0xd524bc570000000000000000000000000000000000000000000000000000000000000064",
            "length": 1
        }
    }
]
  • Step 4. call callgetNameTest whit contract SimpleFallback's address, event log is as below, which showed that called getName() successfully.

    {
        "from": "0x038f160ad632409bfb18582241d9fd88c1a072ba",
        "topic": "0x26c73f7f14382f5db0b9f94dd29ff8938f2e4be69fb13e0825ece287e8e538d5",
        "event": "GetNameEvent",
        "args": {
            "0": "hello",
            "length": 1
        }
    }
]

Question:

for call(abi.encodeWithSignature()), why: - 1)other.call(abi.encodeWithSignature("add(uint,uint)", 85, 60)); did not work? - 2)other.call(abi.encodeWithSignature("double(uint)", 100)); did not work? - 3)other.call(abi.encodeWithSignature("getName(string)", "hello")); did work? - 4) does encodeWithSignature not support multiple parameters, compared 1) and 3)? and does encodeWithSignature not support a uint parameters, compared 2) and 3)?

3 Answers 3

5

I already found out the root cause. It should use the full names of the types, not their aliases, so it should be uint256 instead of uint.

2
  • OMG, thank you for this. I just spent ~3 hours trying to understand why my staticcall is always failing. Commented Apr 9, 2019 at 6:36
  • I think encodeWithSignature shuold provide better friendly interface, fox example, abi.encodeWithSignature("add(uint,uint)") and abi.encodeWithSignature("add(uint, uint)") are two different function signature, just because of spaces.
    – Yannick
    Commented Apr 9, 2019 at 6:42
0
(bool success, bytes memory response) = address(_address).call(abi.encodeWithSignature("transfer(address,address,uint256)", msg.sender, _to, _amount));

First argument should not contain any space in encodeWithSignature method.

-1

it's all about space

other.call(abi.encodeWithSignature("add(uint,uint)", 85, 60));

change it to:

other.call(abi.encodeWithSignature("add(uint,uint)",85,60));
4
  • I don't think there's a difference between those you provided
    – Origami
    Commented Mar 6, 2022 at 22:03
  • Yes, I know it's crazy. But I test it, and it's working. Gives an error due to the space between ',' and the number
    – saied sao
    Commented Mar 8, 2022 at 3:23
  • No, that's wrong. It would only have a difference if the space was in the function abi , eg "add(uint, uint)". The compiler doesn't care if there's a space between 85, 60, it will run the same
    – Origami
    Commented Mar 9, 2022 at 3:00
  • I know, it should be exactly as you say. But I tested and it gave an error because of this space. Corrected when I deleted the space
    – saied sao
    Commented Mar 10, 2022 at 3:54

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.