I am trying to run a setter function (testCallBar) in Caller contract which should run setVal() of Receiver contract using call method. But it does not works. testCallFoo() works as expected but testCallBar() always returns false.
What I want to achieve is to run any function of Receiver contract from Caller contract using call() method.
What am I doing wrong here? Also, what is the better way to run any function with any datatype arguments to run using address.call() method in such scenarios?
pragma solidity ^0.8.3;
contract Receiver {
event Received(address caller, uint256 amount, string message);
uint256 bar = 9;
function foo(string memory _message, uint _x) public payable returns (uint256) {
emit Received(msg.sender, msg.value, _message);
return _x + 1;
}
function getVal() public view returns(uint256) {
return bar;
}
function setVal(uint256 _bar) public payable returns (uint256) {
bar = _bar;
return bar;
}
}
contract Caller {
event Response(bool success, bytes data);
// Let's imagine that contract B does not have the source code for
// contract A, but we do know the address of A and the function to call.
function testCallFoo(address payable _addr, uint256 z) public payable {
// You can send ether and specify a custom gas amount
(bool success, bytes memory data) = _addr.call{value: msg.value, gas: 5000}(
abi.encodeWithSignature("foo(string,uint256)", "call foo", z)
);
emit Response(success, data);
}
function testCallBar(address payable _addr, uint256 z) public payable {
// You can send ether and specify a custom gas amount
(bool success, bytes memory data) = _addr.call{value: msg.value, gas: 5000}(
abi.encodeWithSignature("setVal(uint256)", z)
);
emit Response(success, data);
}
}