我在 Solidity 中遇到一个问题,即使用“call”函数调用合约中的特定函数会重定向到后备函数。目标函数 (bar) 未标记为应付,直接调用它可以正常工作。见下图:
// SPDX-License-Identifier: MIT
pragma solidity >= 0.8.0;
contract ReceiveContract {
event ReceiveLog(address caller, uint amount, string message);
receive() external payable {
emit ReceiveLog(msg.sender, msg.value, "Receive.");
}
fallback() external payable {
emit ReceiveLog(msg.sender, msg.value, "Fallback.");
}
function bar(string memory _s, uint _n) external returns (uint) {
emit ReceiveLog(msg.sender, 0, _s);
return _n+1;
}
}
contract CallContract {
ReceiveContract receiver;
constructor() {
receiver = new ReceiveContract();
}
event DoLog(address caller, bool ok, bytes b);
function do4() external {
(bool ok, bytes memory b) = address(receiver).call(abi.encodeWithSignature("bar(string,uint)", "hello", 3)); // not work, receiver redirect to fallback()
// receiver.bar("hello", 7); // this line work
emit DoLog(msg.sender, ok, b);
}
}
我在 Remix 中编写的所有代码。 我试过:
(bool ok, bytes memory b) = address(receiver).call(abi.encodeWithSignature("bar(string,uint)", "hello", 3));
但不起作用。
并尝试过:
receiver.bar("hello", 7);
这个工作正常。
uint
是 uint256
的别名。函数签名需要包含完整的类型名称,包括其长度。
// `uint256` instead of `uint`
abi.encodeWithSignature("bar(string,uint256)", "hello", 3)
来自文档页面:
、uint
:分别是int
、uint256
的同义词。为了计算函数选择器,必须使用int256
和uint256
。int256