智能合約開發
函式庫
函式庫是一束沒有自身狀態、可重複使用的函數——共用的數學、輔助工具或資料結構邏輯,許多合約可以借用,而不必各自重新實作。OpenZeppelin 經過審計的工具與歷史上的 SafeMath 都是函式庫。using-for 語法甚至讓你把函式庫的函數附加到某個型別上,使 uint256 能呼叫 x.max(y),彷彿 max 是它的方法。
底層有兩種風味。內部(internal)函式庫函數在編譯期被內聯進呼叫合約的位元組碼——只是一個 JUMP,無需另外部署,因此存取它們不會有額外成本。public 或 external 的函式庫函數則作為獨立合約部署一次,並透過 DELEGATECALL 呼叫:函式庫的程式碼在呼叫者的儲存情境中執行,而函式庫本身不持有狀態。這讓許多合約共享一份昂貴程式碼的鏈上副本,並把自己的位元組碼縮到大小上限之下。
函式庫帶有明確限制:不能有(非常數的)狀態變數、不能持有以太幣、不能繼承或被繼承、也不能被銷毀。被連結的(public 函數)函式庫,必須在連結期把其部署位址修補進使用合約的位元組碼,取代編譯器留下的佔位符。由於它們透過 delegatecall 在呼叫者情境中執行,惡意或有缺陷的函式庫原則上能觸碰呼叫者的儲存——所以只連結你信任的函式庫。
library Math {
function max(uint256 a, uint256 b) internal pure returns (uint256) {
return a > b ? a : b;
}
}
using Math for uint256;
// now: x.max(y)無狀態、可重用、可附加到型別。
內部函式庫函數部署免費(被內聯);public 函數透過存於單一位址節省位元組碼,但每次使用增加一次 DELEGATECALL。依「程式碼大小」或「每次呼叫的 gas」何者更重要來抉擇。
另见