title | tags | date | |||
---|---|---|---|---|---|
如何撰寫智能合約(Smart Contract)?(I) |
|
2017-09-06 11:30:31 -0700 |
上一篇中介紹了智能合約是什麼,也概略描述了從編譯到部署智能合約的流程,接下來將介紹如何使用solidity語言來寫智能合約。
Ethereum上的智能合約需要使用solidity[^1]語言來撰寫。雖然還有其他能用來撰寫智能合約的語言如Serpent(類Python)、lll(類Fortran),但目前看到所有公開的智能合約都是使用solidity撰寫。
宣傳上說,solidity是一種類似Javascript的語言,而且圍繞著solidity的各種開發工具鏈,都是使用屬於Javascript生態系的npm來提供的。但我覺得solidity還是比較像Java或C#。 因為和Javascript不同,solidity與Java或C#同屬於強型別(Strong Type,在定義變數時需要指定型別)語言、在定義函式(function)時同樣需指定回傳的型別(type)、同樣也需要先編譯才能執行。這些特性都是Javascript所不具備的。
本文將使用當前最活躍的智能合約開發框架truffle[^3]為基礎來開發。之前提到過的ENS(Ethereum Name Service)[^5]也是採用truffle框架。其他選擇還有embark[^4]。
就像一般網站或App開發一樣,在提供公開服務之前,開發者會在自己用於寫程式的電腦(又稱作本機)或透過測試網路來測試程式執行的效果,測試完成後,才會部署到公開的網路上提供服務。 開發區塊鏈智能合約(程式)的過程也是如此。特別是公開鏈上所有的操作都需要真金白銀(虛擬代幣),而且根據網路狀況,每個公開鏈上的操作都需要要一小段反應時間(15秒 ~ 數分鐘),這些等待頗浪費寶貴的開發時間。 因此在開發的過程中,我們將使用testrpc[^6]工具在電腦上模擬智能合約所需的乙太坊區塊鏈測試環境。
testrpc中也包含了Javascript版本的Ethereum虛擬機(Ethereum Virtual Machine)[^7],因此可以完整地執行智能合約。
首先開發機上必須裝好Node.js,再使用以下命令安裝所需的工具:
https://gist.github.com/c739d0c830da8c9a0b07d3719cc14633
安裝好後隨時可以使用testrpc
命令來啟動乙太坊測試環境。
https://gist.github.com/abda706077f162273173ef3c646df601
可以看到testrpc啟動後自動建立了10個帳號(Accounts),與每個帳號對應的私鑰(Private Key)。
一切準備就緒,我們可以開始建立第一份智能合約專案了。
開啟另一個命令列視窗,輸入以下命令以建立專案:
https://gist.github.com/121108494fc9645b7f935a005e4c9245
如此一來,我們已建立好第一份智能合約專案了。
在demo
資料夾下,可以看到contracts
資料夾,裡面放的是這個專案所包含的所有solidity程式。我們在contracts
資料夾中額外建立一個HelloWorld.sol
檔案。(或者也可以用truffle create contract HelloWorld
命令來建立)
HelloWorld.sol檔案內容如下: https://gist.github.com/31b282e479ec086f00690dba2db6f502
https://gist.github.com/48032eec9a714883fd5d489f1f540c92
第一行指名目前使用的solidity版本,不同版本的solidity可能會編譯出不同的bytecode。
https://gist.github.com/7ac96f0651d1428d4df6062d5474f794
contract
關鍵字類似於其他語言中較常見的class
。因為solidity是專為智能合約(Contact)設計的語言,宣告contract
後即內建了開發智能合約所需的功能。也可以把這句理解為class HelloWorld extends Contract
。
https://gist.github.com/1cd3b377ae9a4403a07e0e45926b0115
函式的結構與其他程式類似,但如果有傳入的參數或回傳值,需要指定參數或回傳值的型別(type)。
現在執行truffle compile
命令,我們可以將HelloWorld.sol
原始碼編譯成Ethereum bytecode。
https://gist.github.com/26f5c0c00768e82f7dda9ef4639561ac
編譯成功的話,在build/contracts
目錄下會多出HelloWorld.json
這個檔案。(在Windows平台上執行truffle compile若遇到問題,可以查看參考資料[^9]來解決。)
truffle框架中提供了部署的腳本,打開/migrations/2_deploy_contracts.js
檔案,將內容修改如下
https://gist.github.com/b33c835abf757627613b09414a96521f
使用artifacts.require
語句來取得準備部署的合約,使用deployer.deploy
語句將合約部署到區塊鏈上。
現在執行truffle migrate
命令,
https://gist.github.com/763e4d16ea04e84788cbef7b87585395
如此一來合約已經部署到testrpc中。切換到testrpc視窗,可以看到testrpc有反應了。
truffle提供命令行工具,執行truffle console
命令後,可用Javascript來和剛剛部署的合約互動。
https://gist.github.com/b09007f8837478f3d7b59b080a3ee21e
https://gist.github.com/93ce77dff4022db948f7a0c2ee2d4990
這邊使用HelloWorld.deployed().then
語句來取得HelloWorld合約的Object,並存到hello
變數中,以方便後續的呼叫。
上面用的是Javascript ES6+的語法,這句也可以寫成
https://gist.github.com/d94e48adef77422271cecb36159607ac
如此一來我們已寫好並部署完成了第一個智能合約,也驗證了合約確實可以運作。
本篇設計的範例[^8]超級簡單,但已達到完整地帶大家快速走一遍智能合約開發流程的目的。要透過智能合約實現各種功能,可以參考Solidity by example 和 Truffle getting started 網站學習更多的內容。也歡迎讀者留言,分享學習資源或提供建議。
下一篇會接著介紹如何建立一個可以放到乙太幣錢包的加密代幣。
- [1] Solidity http://solidity.readthedocs.io/en/latest/index.html
- [2] Solidity線上編輯器 https://ethereum.github.io/browser-solidity/ etherscan.io https://etherscan.io/ ethstats.net https://ethstats.net/
- [3] Truffle Framework http://truffleframework.com/
- [4] Embark Framework https://github.com/iurimatias/embark-framework
- [5] ENS也使用Truffle框架 https://github.com/ethereum/ens
- [6] https://github.com/ethereumjs/testrpc
- [7] https://github.com/ethereumjs/ethereumjs-vm
- [8] HelloWorld範例修改自 https://app.pluralsight.com/library/courses/blockchain-fundamentals/
- [9] Truffle issue on windows http://truffleframework.com/docs/advanced/configuration#resolving-naming-conflicts-on-windows