Solidity
如果使用 address.call() 呼叫失敗,如何防止完全失去狀態?
程式碼:
interface MyInterface { function functionName(uint256 x, uint256 y, uint256 z) external returns (uint256[] memory k); }
然後我的契約中有以下內容,它使用了外部契約
addr
:MyInterface(addr).functionName(x,y,z); MyInterface(addr).functionName(x,y,z); MyInterface(addr).functionName(x,y,z);
如果 3 個函式呼叫中的任何一個失敗,我想在那裡停止執行,但確保已保存由先前函式呼叫引起的任何狀態更改。
很多時候,我在 etherscan 上看到了部分執行的此類事務。據我所知,如果出現錯誤,solidity 不會保存任何更改。
在這個答案中:當拋出發生時,整個事務是否會恢復?,已經提到可以使用較低級別的程式碼。
以下是我正在考慮的解決方案:
addr.call(abi.encodeWithSignature("functionName(uint256, uint256, uint256)",x,y,z)); addr.call(abi.encodeWithSignature("functionName(uint256, uint256, uint256)",x,y,z)); addr.call(abi.encodeWithSignature("functionName(uint256, uint256, uint256)",x,y,z));
如果其中一個呼叫失敗,之前的呼叫導致的先前狀態更改是否仍然存在?
如果您使用 call 之類的低級函式,狀態更改將持續存在,您將必須顯式檢查 ‘call’ 的返回值,並恢復整個事務。
(bool success,) = address.call(.....) if(!success){ revert("Failed") }