利用Truffle Framework和OpenZeppelin-Solidity快速構建以太坊智慧合約
前段時間Jarvis+在以太坊部署了JAR的智慧合約,併為參加活動使用者陸續發放JAR。下面由我們的技術人員Michael借本次機會為大家講解一下,如何快速構建以太坊智慧合約。
隨著智慧經濟的逐漸升溫,智慧合約在智慧經濟中的中樞作用逐漸顯現。智慧合約作為智慧經濟的靈魂,有著不可替代的作用。在以太坊智慧經濟生態中,智慧合約已被構建成以Solidity語言為開發語言,多種整合開發環境支援的,影響深遠且功能強大的智慧經濟中樞。在以太坊智慧經濟生態中,負責絕大多數的信用轉移和傳遞。
本文將介紹如何利用Truffle Framework和Zeppelin/">OpenZeppelin-Solidity兩個強大的工具快速地開發一個以太坊智慧合約。
1. 構建開發環境
Truffle Framework是一個世界級的開發環境。同時擁有智慧合約的測試框架和虛擬以太坊資產。使用Truffle 開發環境,會讓智慧合約的開發變得非常簡單。通過Truffle可以實現:
- 內建智慧合約編譯,連結,部署和二進位制管理
- 智慧合約測試
- 可編寫指令碼的可擴充套件部署和遷移框架
- 用於部署到任意數量的公共和專用網路的網路管理
- 支援ERC 190標準,使用ethPM和NPM進行包管理
- 互動式控制檯,用於直接合同通
- 可配置的構建管道,支援緊密整合
- 在Truffle環境中執行指令碼的外部指令碼執行器
OpenZeppelin-Solidity 是OpenZeppelin 組織使用Solidity 語言開發的一套智慧合約基礎庫。包括了對智慧合約的運算、安全智慧合約信用體系的構建等基礎性的功能。使用這樣一套開發庫,開發者就不必再從頭做起,直接可以實現智慧合約的主要功能了。OpenZeppelin-Solidity 保持著持續地更新,不斷地完善合約庫的功能和安全特性。OpenZeppelin-Solidity 的原始碼都是公開的,可以通過https://github.com/OpenZeppelin/openzeppelin-solidity 進行檢視。
建立一個以太坊智慧合約專案的方法很簡單,只需要在Node.js 的支援下執行幾個簡單的命令。如果還沒有安裝Node.js,請訪問:https://nodejs.org/en/ 安裝Node.js。然後在命令列下,通過npm 安裝Truffle framework
$ npm install -g truffle
以全域性的方式安裝好Truffle Framework 之後,再建立專案資料夾:
$ mkdir myFirstContract
$ cd myFirstContract
然後在專案資料夾內,執行truffle 初始化命令,下載專案檔案模板。然後,安裝OpenZeppelin-Solidity 庫
$ truffle init
$ npm init -y
$ npm install -E openzeppelin-solidity
在一系列配置結束之後,就可以使用Visual Studio Code開啟專案檔案夾了。如果沒有安裝Visual Studio Code,可以通過http://code.visualstudio.com 來進行下載。開啟專案資料夾後,目錄內容如下:
1
其中,contract 資料夾用來儲存開發的智慧合約原始碼。資料夾中的Migrations.sol 是Truffle 用來幫助部署Solidity智慧合約的輔助程式碼,請不要隨意改動。mirgations 資料夾是用來儲存部署、編譯和測試合約的JavaScript 指令碼程式碼的資料夾。test資料夾內儲存單元測試原始碼。Truffle-config.js 和truffle.js 檔案是儲存Truffle Framework 配置檔案資訊的,其實兩個檔案中的內容一樣,truffle.js 檔案用於macOS 和Linux作業系統。在Windows下,為了避免重名,改用truffle-config.js作為配置檔案。
2. 開發一個智慧合約
智慧合約的開發,可以用Visual Studio Code 來完成。可以先通過Visual Studio Code 在contracts 目錄下建立一個Solidity原始碼檔案MyCalculator.sol。而後,在原始碼檔案的第一行標註出來期望使用的Solidity 編譯器版本。Solidity 規定在每個原始碼檔案的第一行都要指定一下可以編譯原始碼的Solidity 編譯器的版本。由於Solidity 語言還在持續地改進,這樣做是非常有必要的。
pragma solidity ^0.4.24;
然後就是要引用第三方的函式庫檔案了。其實主要就是OpenZeppelin-Solidity 庫的檔案。由於去年持續爆出了利用智慧合約運算值溢位的漏洞導致的一系列安全風險,OpenZeppelin-Solidity 實現了SafeMath.sol 這個安全運算庫。在簡單數學運算之後進行數值檢查,化解風險。因此,在智慧合約運算時應儘量使用這個函式庫。開發人員可以通過import 關鍵字引入這個函式庫。
import"../node_modules/openzeppelin-solidity/contracts/math/SafeMath.sol";
在引入了第三方庫之後,就可以開始正式地編寫智慧合約了。Solidity規定,智慧合約的關鍵字是contract,類似於日常程式設計使用的類宣告關鍵字class。這裡僅通過建立一個簡單的合約進行展示。
pragma solidity ^0.4.24; import"../node_modules/openzeppelin-solidity/contracts/math/SafeMath.sol"; contract MyCalculator { using SafeMath for uint256; function myAdd(uint256 x, uint256 y) public pure returns(uint256 result) result = x.add(y); return result; } }
程式碼中的add 方法通過SafeMath中的安全運算函式add,實現兩個無符號大整形數字的加法運算。深挖一下SafeMath中的add方法,可以看到在計算結束後,add函式還對計算結果進行了判斷,加法運算溢位之後的結果返回給呼叫端,避免了黑客利用資料運算上下界溢位來對數字資產進行破壞。
function add(uint256 _a, uint256 _b) internal pure returns (uint256 c) { c = _a + _b; assert(c >= _a); return c; }3. 智慧合約的編譯和部署
在智慧合約編寫完成之後,就要開始對智慧合約的編譯了。能夠部署到以太坊上面的智慧合約都是編譯好的二進位制位元組流,而不是原始碼檔案。
Truffle Framework 的Node.js包內已經包含了Solidity編譯器。因此,編譯智慧合約變得非常簡單,在Visual Studio Code 中開啟終端檢視,在終端檢視中輸入truffle compile 命令,即可完成編譯。在Windows 作業系統下,不能直接使用truffle compile命令,因為當前目錄下有一個truffle.js 檔案,作業系統會預設執行這個JavaScript檔案而不是truffle本身。可使用truffle.cmd compile 規避名字衝突。
智慧合約的測試的部分功能是可以通過本地完成的。對於相對複雜的操作,比如生成一筆交易,就要進行上鍊測試了。在這裡先介紹如何在本地進行測試的方法。
首先,需要安裝以太坊本地模擬器ganache。這個工具可以在本地模擬一個以太坊節點,並且生成十組有效的錢包地址和私鑰。安裝的方法是通過npm 安裝ganache 命令列工具。
$ npm I ganache-cli -g --save
安裝結束後,可以通過直接鍵入ganache-cli 命令執行這個本地模擬器。模擬器會持續偵聽本地8545埠來處理請求。
在安裝和執行模擬器之後,還要修改一下truffle.js 或者truffle-config.js檔案,建立一個本地測試網路配置,以便truffle可以連線到本地8545埠。
module.exports = { networks: { development: { host: 'localhost', port: 8545, network_id: '*', // eslint-disable-line camelcase }, }, solc: { optimizer: { enabled: true, runs: 200 } } };
在這一切都就緒之後,還需要編寫一些JavaScript程式碼來實現智慧合約的部署。要在migration資料夾中建立一個JavaScript 檔案“2_deploy_MyCalc.js”。
在這個JavaScript中新增部署智慧合約的指令碼內容。
varMyCalc=artifacts.require("./MyCalculator.sol"); module.exports=async function(deployer, network, accounts) { await deployer.deploy(MyCalc); const deployedMyCalc = await MyCalc.deployed(); console.log("==============================================="); console.log("address = " + deployedMyCalc.address); console.log("==============================================="); }
程式碼中通過artifacts.require 匯入智慧合約原始碼檔案。然後使用deployer 物件部署智慧合約到以太坊網路上面。
正式部署,需要使用truffle migrate 命令,通過—network 指定truffle.js 檔案中預先配置好的網路引數。
當看到生成的智慧合約地址時,就代表本次合約部署成功了。
4. 智慧合約的測試
配置好本地網路之後,就可以編寫測試程式碼了。智慧合約測試程式碼採用JavaScript 編寫,程式碼需要放置在test 資料夾內。首先建立一個名為MyCalc.test.js 的檔案。然後在檔案中新增測試程式碼。
const myCalculator = artifacts.require('MyCalculator'); contract('MyCalculator', function ([_, creator]) { let myCalc; beforeEach(async function() { const myCalc = await myCalculator.new(); }); it('test 56 + 72', async function () { const sum = await myCalc.myAdd(56, 72); assert(sum.eq(128)); }); });
在測試程式碼中,首先匯入MyCalculator 智慧合約,然後建立一個智慧合約物件,最後呼叫合約物件中的方法對方法返回值進行校驗。在Truffle的最新版本中還加入了單步除錯的功能。如果有必要,還可以在本地測試鏈上詳細除錯每一行智慧合約程式碼。
以上僅僅展示了一個智慧合約最簡單的步驟。如果需要實現更多的功能,就需要在測試鏈上進行測試了。鏈上測試的重點在於對於交易的格式以及交易的資料正確性等等。
目前著名的以太坊測試鏈主要是:
Ø ropsten(https://ropsten.etherscan.io/)
Ø kovan(https://kovan.etherscan.io/)
Ø rinkeby(https://rinkeby.etherscan.io/)
他們的區別在於共識機制的不同,所幸這些測試網都有區塊鏈瀏覽器支援,同時又有水管可以自動申請測試ether。下面以kovan為例,看一下如何將智慧合約部署到測試網上面。
向測試網部署智慧合約,需要安裝另外一個元件:truffle-hdwallet-provider
$ npm i truffle-hdwallet-provider –save
在安裝完成之後,需要在truffle.js 配置檔案中做些修改。要通過infura建立測試網對應的provider物件。
const HDWalletProvider = require('truffle-hdwallet-provider'); const providerWithMnemonic = (mnemonic, rpcEndpoint) =>new HDWalletProvider(mnemonic, rpcEndpoint); const infuraProvider = network => providerWithMnemonic(process.env.MNEMONIC || '',`https://${network}.infura.io/${process.env.INFURA_API_KEY}`); const kovanProvider = infuraProvider('kovan');
然後在truffle.js配置檔案中加入kovan 測試網的配置專案。
kovan: { provider: kovanProvider, //gasPrice: 1000000000, network_id: 42, // eslint-disable-line camelcase },
請注意,每個測試網路為了互相區分,他們的network_id 都是不同的。
總結
通過使用Truffle Framework、OpenZeppelin-Solidity 和Visual Studio Code,開發人員可以在幾十分鐘之內就讓自己開發的智慧合約部署到以太坊區塊鏈上。快捷、安全和高效率是這套開發元件的顯著特點。
感謝大家的閱讀,有任何問題可以通過官方渠道聯絡我們,