上一篇了解到在以太坊的 log 功能以及 Solidity 如何撰寫 log ,接下來會講解 Solidity 另一個重要功能 - 函式庫 。
相信不論是 C 、 JAVA 、 Python 、 JavaScript 等開發者都對函式庫不陌生吧!簡單來說,函式庫就是用來幫助開發者在開發上能夠更快速、更簡潔的完成開發,更直白一點就是把許多函式打包成函式庫,讓開發者引入函式庫來使用這些函式,以減少重複的程式碼,在 Solidity 中也可以透過撰寫函式庫來減少重複的程式碼,也因為如此,可以省下反覆部署所消耗的資源、 Gas 。在 Solidity 中的函式庫可以視為物件導向程式語言中的靜態類別,不需要產生實體就可以使用!
物件導向語言大致上都是建立類別並寫靜態方法(Static),雖然說在 Solidity 的 library 可以視為靜態類別,但不使用 contract
建立,也不寫 static
,而是使用 library
建立,下方是一個簡單的 library 範例,是進行字串比對的:
pragma solidity ^0.5.0;
library StringLib {
function compare(string memory str1, string memory str2) public pure returns (bool) {
bytes memory str1_bytes = bytes(str1);
bytes memory str2_bytes = bytes(str2);
return keccak256(str1_bytes) == keccak256(str2_bytes);
}
}
可以看到寫法與一般合約沒有太大的差異,基本上把 library 部署到以太坊之後,也與其他合約沒有什麼區別,但 library 其實是有些限制的:
payable
函式library 跟合約一樣需要被部署才能使用,與被繼承的合約不同,繼承是把程式碼 複製到繼承的合約 ,而 library 是 呼叫 library 中程式碼 ,兩者有很大的不同,因此我們可以知道合約要使用 library 就必須要先部署 library ,再拿 library 的位址來用,這大概就是串接的核心思想。
我們先寫一個簡單的合約來使用上方的函式庫:
pragma solidity ^0.5.0;
import "./StringLib.sol";
contract Str {
function strCompare(string memory s, string memory t) public pure returns (bool) {
return StringLib.compare(s, t);
}
}
會發現我們 import 了 library ,但剛剛不是說要先部署 library ,然後透過位址來呼叫 library 的函式嗎?其實並沒有做錯喔!就好像透過 CDN 取得 jQuery ,然後在程式碼裡面使用 jQuery 的功能一樣。
接著我們要先進行編譯:
truffle compile
然後去看 Str.json
裡面的 bytecode
,會找到下面這個東西:
...b600073__StringLib_____________________________633a96fdd...
這個其實就是要 填入 library 的合約位址 ,但我們用 Truffle 來自動化完成這些動作會比較快!首先要先修改部署檔,順序就是先部署 library ,然後透過 link()
來自動綁定,再部署合約:
const StringLib = artifacts.require("StringLib");
const Str = artifacts.require("Str");
module.exports = function(deployer) {
deployer.deploy(StringLib);
deployer.link(StringLib, Str);
deployer.deploy(Str);
};
接著用 truffle console 進行測試就好囉~
是一個特別的用法,類似原型鏈,能夠將 library 中的函式擴充到某個資料型別上,下方範例使用了 using...for
將 StringLib 的函式擴充到 string
型別,若該函式本身有參數的話,預設是以合約中呼叫 library 函式的變數作為第一個參數:
pragma solidity ^0.5.0;
import "./StringLib.sol";
contract Str {
using StringLib for string;
function strCompare(string memory s, string memory t) public pure returns (bool) {
return s.compare(t);
}
}
了解 Solidity 如何撰寫函式庫,以減少重複的程式碼,並使用 Truffle 來自動化部署與串接。使用 Truffle 來開發智能合約真的是非常方便,只要把該定義的弄好就可以自動化完成,真的太好用了!
Libraries in Solidity for code reusability and testing it