当使用较低级别的address.call(data)调用外部契约时,可以检索外部契约抛出的异常吗?返回数据的一部分是成功布尔值返回的数据吗?
发布于 2022-07-11 23:20:05
是的,在可靠的情况下,恢复原因作为调用的返回数据传递。
因此,如果调用失败的原因是:
revert CustomError(uint256(100))返回数据将是abi.encodeWithSelector(CustomError.selector, uint256(100))。如果还原原因是字符串,则返回数据将是字符串abi编码的。
我已经做了这个关于如何从自定义错误中获取数据的例子。
pragma solidity ^0.8.0;
contract TestError {
error TimeError(uint256 time);
event LogTime(uint256 time);
function getTimestampAsError() external {
revert TimeError(block.timestamp);
}
function main() external {
// make external call to this contract
bytes memory data = abi.encodeWithSelector(this.getTimestampAsError.selector);
(bool success, bytes memory returndata) = address(this).call(data);
// call failed
if (!success) {
// decode returndata
// we need assembly cause there's no 'decodeWithSelector'
uint256 time;
assembly {
// mload(returndata) -> length of bytes
// mload(returndata + 0x20) -> start of body
// first 4 bytes are TimeError.selector
time := mload(add(returndata,0x24))
}
// return time using logs
emit LogTime(time);
}
}
}https://ethereum.stackexchange.com/questions/131326
复制相似问题