[Ethereum] abi.encodeWithSignature did not work

abisolidity

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)?

Best Answer

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.