1

Here I am trying to call contract A's callMe function from contract B using the low level function, call (bool success, )=_b.call(abi.encodeWithSignature("callMe(uint)",val)); But when I do so it won't emit the event 'called' which is in the callMe fucntion and at the same time the transaction is not getting reverted. Also the variable money is not getting update. I am doing this in remix. Here is my code

// SPDX-License-Identifier: UNLICENSED
pragma solidity^ 0.8.10;
contract B{
    event called(address _add, uint val);
    uint public money;
    fallback() external payable{}
    function callMe(uint val) public payable{
        money+=val;
        emit called(msg.sender,val);
    }
}

contract A{
    constructor() payable{}
    function callB(address _b,uint val) public payable{
        (bool success, )=_b.call(abi.encodeWithSignature("callMe(uint)",val));
        require(success);
    }
}

Strange thing is that when i remove the argument val in both the contracts the code work fine, it emits the event. Can Anyone please tell me what am I doing wrong here. I think there might be a silly mistake I am doing.

2 Answers 2

2

uint is an alias for uint256: https://minfengqi.com/2021/01/Solidity_tutorial/#unsigned-integers-uint

The issue is that when your contract gets compiled to bytecode, the aliasing gets removed and the bytecode stores the argument as uint256. As such, the FunctionSelector will also be using uint256, so your explicit keccak of "callme(uint)" doesn't match any of the known functions in the bytecode.

1

I am not sure why it is not getting reverted, but if you change the parameter to be uint256 in contract A, like this:

        (bool success, )=_b.call(abi.encodeWithSignature("callMe(uint256)",val));

It will work.

1

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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