鏈客,專為開發者而生,有問必答!
solidity 是以太坊智慧型合約程式語言,閱讀本文前,你應該對以太坊、智慧型合約有所了解,如果你還不了解,建議你先看以太坊是什麼?
什麼是錯誤處理
錯誤處理是指在程式發生錯誤時的處理方式,solidity處理的方式和常見的語言不一樣,其時通過回退狀態的方式來處理錯誤,發生異常時會撤銷當前呼叫所改變的狀態,同時給呼叫者返還乙個錯誤標識。
為什麼要這麼設計呢?
我們把區塊鏈理解為全球分享的分布式事務性資料庫,全球共享意味著每個人都可以讀取其中記錄,想要修改這個資料庫的內容,就必須建立乙個事務,意味著要的修改只能被完全應用或不進行。
如何處理
solidity提供2個函式assert和requrie進行檢查,條件如果不滿足則丟擲異常,assert函式通常用來檢查內部錯誤,另乙個用來檢查輸入變數或合同狀態變數是否滿足條件及驗證呼叫外部合約返回值。如果正確使用assert,由乙個solitity分析工具就可以分析出只能合約中的錯誤,幫助我們發現合約中邏輯錯誤的bug。
另外還有兩種方式來觸發異常:
revert函式可以用來標記錯誤並回退當前呼叫
使用throw關鍵字丟擲異常
當子呼叫中發生異常時,異常會自動向上「冒泡」。 不過也有一些例外:send,和底層的函式呼叫call, delegatecall,callcode,當發生異常時,這些函式返回false。
在下面通過乙個示例來說明如何使用require來檢查輸入條件,以及assert用於內部錯誤檢查:
pragma solidity ^0.4.0;contract sharer }
執行測試2:附加2wei 去呼叫sendhalf,執行正常。
執行測試3:附加2wei以及sendhalf引數為當前合約本身,在轉賬是發生異常,因為合約無法接收轉賬,錯誤提示上圖類似。
assert型別異常
在下述場景中自動產生assert型別的異常:
如果越界,或負的序號值訪問陣列,如i >= x.length 或 i < 0時訪問x[i]
如果序號越界,或負的序號值時訪問乙個定長的bytesn。
被除數為0, 如5/0 或 23 % 0。
對乙個二進位制移動乙個負的值。如:5<
require型別異常
在下述場景中自動產生require型別的異常:
呼叫throw
如果呼叫require的引數為false
如果在使用new建立乙個新合約時出現第3條的原因沒有正常完成。
如果呼叫外部函式呼叫時,被呼叫的物件不包含**。
當發生require型別的異常時,solidity會執行乙個回退操作(指令0xfd)。當發生assert型別的異常時,solidity會執行乙個無效操作(指令0xfe)。在上述的兩種情況下,evm都會撤回所有的狀態改變。是因為期望的結果沒有發生,就沒法繼續安全執行。注意assert型別的異常會消耗掉所有的gas, 而require從大都會版本(metropolis, 即目前主網所在的版本)起不會消耗gas。
solidity智慧型合約程式設計基礎
基礎語法 一 1 函式定義 function 函式名 引數型別 引數1,引數型別 引數2 訪問許可權 讀取資料型別函式 returns 返回資料型別 訪問許可權 public private 一般private許可權的話,引數命名前面加乙個 例如 name 讀取資料型別函式 view函式 唯讀且不可...
solidity智慧型合約重要特性
solidity智慧型合約的一些重要特性,如變長陣列中的storage和memory變數,storage和memory的儲存位置以及字串陣列string使用。區塊鏈開發 以太坊 fabric bcos 密碼技術 共識演算法 位元幣 其他鏈 string,bytes 對於變長陣列,在初始化分配空間前不...
solidity 智慧型合約之間的呼叫
在智慧型合約的編譯過程中,有兩種情況 呼叫者和被呼叫者在乙個sol檔案中和分別在不同的檔案中。在下面的智慧型合約中,demo1和demo在同乙個檔案中,可進行同時編譯,然後逐個發布。pragma solidity 0.5.10 contract demo1 contract demo2 當發布完成,...