1. 程式人生 > >Solidity 中Require(), Assert(), Revert()的用法和區別

Solidity 中Require(), Assert(), Revert()的用法和區別

在Solidity0.4.10之前,if...throw普遍利用於判斷一個條件是否滿足,如果不滿足則終斷執行。但這throw了之後它會撤回所有的狀態轉變,用光你所有的gas,所以這並不是一個好的操作。

之後,assert(), require(), and revert() 三個函式代替了if...throw的功能,並對gas有了更好的處理。原文章中提到的例子:

if(msg.sender != owner) { revert(); }

assert(msg.sender == owner);

require(msg.sender == owner);

這三個函式在功能上是與if(msg.sender != owner) { throw; }是等價的。下面具體說說這三個函式的區別。

Require and assert

同樣作為判斷一個條件是否滿足的函式,require會退回剩下的gas,而assert會燒掉所有的gas。對於兩個函式應該在什麼情況下使用,這裡引用一段原文:

”The require function should be used to ensure valid conditions, such as inputs, or contract state variables are met, or to validate return values from calls to external contracts. If used properly, analysis tools can evaluate your contract to identify the conditions and function calls which will reach a failing assert

Properly functioning code should never reach a failing assert statement; if this happens there is a bug in your contract which you should fix.“

Revert

revert的用法和throw很像,也會撤回所有的狀態轉變。但是它有兩點不同:

1. 它允許你返回一個值;

2. 它會把所有剩下的gas退回給caller

呼叫起來就像這樣子:

revert(‘Something bad happened’);

require(condition, ‘Something bad happened’);

 

適合用Require的時候:

驗證一個使用者的輸入是否合法:ie. require(input<20);

驗證一個外部協議的迴應:require(external.send(amount));

判斷執行一段語句的前置條件: ie. require(block.number > SOME_BLOCK_NUMBER) or require(balance[msg.sender]>=amount);

require應該被最常使用到;

一般用於函式的開頭處。

適合用Revert的時候:

和require()應用場景差不多,適合用在邏輯複雜的情況下。

適合用Assert的時候:

檢查有沒有上溢或者是下溢: ie. c = a+b; assert(c > b)

檢查常數: ie. assert(this.balance >= totalSupply);

在完成變化後檢查狀態

避免本不應該發生的情況出現,如程式的bug

assert不應該被經常利用到;

一般用於函式結尾處。

 

如果你也中意區塊鏈,可以加:

微信公眾號:ipfscom

QQ群:71789361

個人微信:18191727

也可以掃碼加入我的星球,我們一起親密的玩耍