一、前言
建構函式缺失漏洞自智慧型合約產生以來就一直出現,歸根到底是由於新進開發者對 solidity **結構不熟悉造成的。bugx.io團隊本次就來介紹一下漏洞的基本原理、表現形式以及對開發者的建議。
二、漏洞原理
1. 什麼是建構函式
solidity編寫合約和物件導向程式設計語言非常相似,我們可以通過建構函式(constructor)來初始化合約物件。建構函式就是方法名和合約名字相同的函式,建立合約時會呼叫建構函式對狀態變數進行資料初始化操作。
建構函式可用的函式型別為 public 或 internal,如果有 payable 修飾,就只能是 public 型別。而大部分人的寫法都是 public 或者不寫。不寫型別則由函式可見性預設為 public 型別。同時,如果建構函式帶引數,則一定要放在合約下的第乙個函式。
pragma solidity 0.4.21;
contract foo
}合約結構的規範化寫作可以讓其他人更好地閱讀,並且 constructor 和 fallback 函式要放在前面以便更好地檢視。官方建議以如下順序寫作:
* constructor
* fallback function (if exists)
* external
* public
* internal
* private
合約結構的規範寫法如下:
contract a
function() external
// external functions
// ...
// external functions that are view
// ...
// external functions that are pure
// ...
// public functions
// ...
// internal functions
// ...
// private functions
// ...
}2. 建構函式缺失與危害
建構函式缺失則是由於建構函式與合約名字不同,而又為 public 型別,就變成了乙個公有函式了,可以被任何人呼叫,一般函式函式比較敏感,用於初始化合約時定義通證數量、管理員位址等基本變數狀態,一時變成了公有函式,危害可想而知,許可權控制、通證管理基本全線奔潰。
3. 版本公升級後建構函式的變化
從 `0.4.22`版本開始,solidity 編譯器引入了 constructors 關鍵字,以替代低版本的將合約名作為建構函式名的語法,避免程式設計師容易出現的編碼錯誤。使用舊寫法會出現 warning 資訊。
新版本寫法為:
contract ownable
// other code
}三、常見漏洞**形式
1. 建構函式使用庫合約名稱,使得建構函式變成了公有函式,可被任意呼叫。
我們發現了不少這種錯誤寫法的合約,在主合約中,建構函式寫成了 token() 或 erc20token() 。這樣子的函式非建構函式,變成了普通函式了。
如 dealguard 合約:
2. 合約名與建構函式名不同,如大小寫不同、拼寫錯誤等,使得建構函式變成了公有函式,可被任意人呼叫。
只能說開發者太大意,對智慧型合約開發有什麼誤解吧。經常看到的漏洞形式是合約名與建構函式不同,只與 name 變數名相同,估計是開發者以為合約名相同就行了,卻忽略了建構函式。
如 reapercoin11 合約:
還有這個 krypticoin 合約,乍一看看不出來,仔細瞅瞅,再仔細瞅瞅,原來 coin 拼錯了 。
之前知道創宇發布了關於 `owned`大小寫編碼漏洞的文章。同時,我們也可以找一些類似的容易大小寫錯誤的庫合約,如 `ownable`。不過經過我們的分析,還是以 owned 大小寫錯誤為主。
如 morph 合約:
contract owned
3. constructor 前加了function ,或者加了 fucntion 然後開頭的 c寫成了大寫,即 `function constructor()public {}`,使得建構函式變成了公有函式,可被任意人呼叫。
版本公升級後的建構函式只需要單獨使用 constructor 即可,但很多開發者卻忽略了此細節。上面這個寫法錯誤在於兩點:
1) 加入了 function 變成了普通函式形式。但是這時編輯器中會報 warning 資訊:
但是有開發者忽了此警告,寫出了錯誤**。
如 mdot 合約:
function constructor() public
2) 但是如果將 `constructor`錯寫成了 `constructor`,使得編輯器識別其為普通函式名,沒有任何 warning 資訊。
如 togtoken 合約:
四、常見漏洞**形式
使用新版本寫法,並且檢查句式、拼寫的正確性。
五、漏洞影響範圍
通過我們對以太坊上的合約進行整體監測,發現有此漏洞的竟達兩千多份,大小寫編碼錯誤的約有20 份。其中不乏正在使用中的合約。
建構函式缺失漏洞分析
建構函式缺失漏洞自智慧型合約產生以來就一直出現,歸根到底是由於新進開發者對 solidity 結構不熟悉造成的。bugx.io團隊本次就來介紹一下漏洞的基本原理 表現形式以及對開發者的建議。solidity編寫合約和物件導向程式設計語言非常相似,我們可以通過建構函式 constructor 來初始化...
建構函式 解析建構函式的作用
建構函式 是一種特殊的方法。主要用來在建立物件時初始化物件,即為物件 成員變數 賦初始值,總與new 運算子一起使用在建立物件的語句中。特別的乙個類可以有多個建構函式 可根據其引數個數的不同或引數型別的不同來區分它們 即建構函式的 過載。那麼,為什麼要在建立物件時初始化物件呢?又是如何實現的呢?接下...
c 建構函式解析
c 建構函式的知識在各種c 教材上已有介紹,不過初學者往往不太注意觀察和總結其中各種建構函式的特點和用法,故在此我根據自己的c 程式設計經驗總結了一下c 中各種建構函式的特點,並附上例子,希望對初學者有所幫助。c 類的建構函式詳解 一 建構函式是幹什麼的 class counter private ...