| Chapter 9 | 異常處理 Handling Exception
面對異常處理,我們得先簡單理解交易以及錯誤(Transactions and Errors),並且條列一些在Solidity中異常處理的性質。
交易是自動化的,一旦送出便沒有辦法在過程中透過人為終止
拋出Errors是會回復狀態的行為,並不會讓錯誤發生。
語法包含
require
,assert
,revert
,在更早的版本還有throw;
除了以下 Low-Level 的函數以外,皆為接連發生的(cascade)
Address.send
,address.call
,address.delegatecall
,address.staticcall
Revert
和require
可以回傳錯誤訊息
0.4.10 版的 Solidity 新增了 require()
, assert()
, revert()
這三個語法
require()
用來檢查較不嚴重的錯誤,通常是在執行前就檢驗合理的輸入或條件,可以退回為使用到的 gasassert()
用來檢查較嚴重的錯誤,會像以前一樣拿走所有的 gasLimit 的手續費revert()
跟require()
基本上相同,但是revert()
沒有包括狀態檢查
0.6 之後新增了 try/catch
可以使用
pragma solidity ^0.8.11;
contract Exception{
mapping(address => uint64) public balanceReveived;
function receiveMoney() public payable {
assert(balanceReceived[msg.sender] + uint64(msg.value) >= balanceReceived[msg.sender])
balanceReveived[msg.sender] += uint64(msg.value);
}
function withdrawMoney(address payable _to, uint64 _amount) public {
require(balanceReceived[msg.sender] <= _amount, "You don't have enough ether");
assert(balanceReceived[msg.sender] >= balanceReceived[msg.sender] - _amount)
balanceReceived[msg.sender] -= _amount;
_to.transfer(_amount);
}
}
以上例子之中我們可以發現:
在加上
assert
之前,當我們想要匯入10ethers兩次,實際上合約不會收到20ethers,原因是來自於uint64
在我們加上
assert
之後,當我們想要匯入10ethers兩次,便會在第二次動作時接收到回傳的錯誤。
Throw
於Solidity 0.4.10版本後移除
if (msg.sender != owner) {
throw;
}
Last updated
Was this helpful?