使用 throw
而不是 return false
會更好嗎?
我的目標是執行一些簡單的功能,但使用者應該知道呼叫是否失敗。在這裡可以看到一個簡單的函式範例。
而不是
return false
,我想使用throw
. 它們對函式流的影響是否相同?哪一個使用更少的氣體?總的來說,哪一個可能更有動力使用?
這種討論主要在契約呼叫另一個契約的情況下很重要。如果被呼叫者合約拋出,則
catch
目前 EVM 版本中呼叫者合約中沒有。因此,如果需要,拋出錯誤是不可能恢復的。但這在通常的案例中很少需要。使用 throw 可以更容易地查看交易在區塊鏈瀏覽器中是否有任何錯誤。
另請參閱有關解決這些問題的即將推出的功能的討論https://github.com/ethereum/EIPs/issues/140
只是想我會插話,以防這個問答對其他人有用。為簡潔起見,想像一下我認為我在所有內容前面都加上了.
這是一個非常普遍的問題。我將情況分為兩種情況:
- “否”是對問題的有效回答
- 交易有問題
在第一種情況下,
return false
可能是要走的路。例如,“今天是星期一嗎?” - 不。沒有什麼特別錯誤的,“不”是有效且預期的回應。隱含地,呼叫者應該為“不”會回來並相應地處理它的可能性做好準備。大量案件屬於第二類;出了點問題。
throw;
在這些情況下,我認為它幾乎總是比.考慮到我們可以部署一個合約,然後將來呼叫者可能是另一個合約。如果我們
return false
實際上是讓呼叫者承擔了應對意外結果的責任。這會導致複雜性,而復雜性是我們在智能合約中不想要的。另一方面,如果我們throw
一遇到麻煩,我們就會為所有未來的呼叫者提供服務;如果我們的功能“沒有發生”,那麼什麼也沒有發生。這與其他環境中的哲學完全相反,後者幾乎痴迷於發現錯誤和解釋問題。我認為對於那些剛開始並可能想知道習慣方法的人來說,這值得一提。
在智能合約中,我往往會早早失敗,失敗得很厲害,什麼也不解釋。換句話說,
throw
在(幾乎)每一個機會。一般啟發式:
- 驗證輸入並在出現問題時拋出。
- 做東西。
- 檢查結果,如果有問題,拋出。
- 返回“成功”或結果。
可能看起來有點殘酷。在我看來,智能合約應該專注於保護應用程序(和數據)的完整性,並且應該以最簡單的方式做到這一點,因為我們正在處理一個錯誤或疏忽可能產生重大後果並且可能很困難的平台或無法修復。
我們的目標是“明顯正確”。最小化複雜性意味著解釋原因是一個單獨的問題(讓客戶弄清楚)。
Throw
通常是對威脅系統完整性的異常的最可靠和最簡單的響應。希望能幫助到你。