共同點
在看差别之前,我們先了解他們之間的共同點:
-
與assert()
語句都需要滿足括号中的條件,才能進行下面的操作require()
- 若不滿足則抛出錯誤
以下三個語句的功能完全相同:
if(msg.sender != owner) { revert(); }
assert(msg.sender == owner);
require(msg.sender == owner);
差異化分析
gas效率
assert(false)
編譯為
0xfe
,這是一個無效的操作碼,故将消耗掉所有剩餘的gas,并恢複所有的操作
require(false)
0xfd
,這是
revert()
的操作碼,它将退還所有剩餘的gas,同時可以傳回一個值(自定義的報錯資訊)
位元組碼輸出分析
require()
函數應用于滿足輸入或合約狀态變量等有效條件,或驗證調用外部合約的傳回值等,總之
require()
語句的失敗報錯應該被看作一個正常的判斷語句流程不通過的事件,而
assert()
語句的失敗報錯,意味着發生了代碼層面的錯誤事件,很大可能是合約中有一個bug需要修複。
故此,使用
require()
的情況有:
- 驗證使用者輸入,例如
require(input_var>100);
- 驗證外部合約的調用結果,例如
require(external.send(amount));
- 在執行狀态更改操作之前驗證狀态條件,例如
或require(block.number > 49999)
require(balance[msg.sender]>=amount)
一般來說,使用
require()
的頻率更多,通常應用于函數的開頭
使用
assert()
- 檢查溢出(上溢出或者下溢出)
- 檢查不變量
- 更改後驗證狀态
- 預防永遠不會發生的情況
assert()
的頻率較少,通常用于函數的結尾
基本上,
require()
應該是您檢查條件的功能,
assert()
隻是為了防止發生任何非常糟糕的事情,但條件不應該等于為
false
.