Ethereum 實驗筆記

miZyind
miZyind Singularity
8 min readMay 29, 2018

--

由於我的工作是開發 NodeJS 程式,因此相關的開發環境已經預先設置完畢,建議可以先了解部份背景知識再閱讀本文

名詞解釋:

  • Ethereum -- 核心區塊鏈平台,智能合約編寫與執行機制是其一大特色
  • Solidity -- 用來撰寫智能合約的一種程式語言
  • OpenZepplein Solidity -- 豐富的智能合約庫,可直接引用許多現成合約
  • Truffle -- 基於 NodeJS 所生,是個輕巧快速的合約測試、編譯、發佈框架
  • Ganache -- 個人私鏈模擬器,支援 GUI 與 CLI 操作
  • MetaMask -- 操作便利的虛擬錢包、交易檢視器

建立專案:

# 建立資料夾並切換工作路徑
$ mkdir tutorial-token && cd tutorial-token
# 使用 tutorialtoken 預設模板
$ truffle unbox tutorialtoken
# 建立一份名為 TutorialToken 的合約
$ truffle create contract TutorialToken

完成後,利用 VSCode 開啟本專案並找到 contracts/TutorialToken.sol
會發現樣板已經幫忙填好了部分程式碼,卻帶有部分警告
這或許是因為 Solidity 的語法持續在更新,樣板更新的速度不夠即時所致
由於 VSCode 的 Solidity 套件 內建了「語視美化」以及「語法檢查」
所以可以在開發階段立即檢查出這些有待改進的語法

雖然這些警告並不影響後續的編譯與發佈
但既然是初次學習 Solidity,更要扎實的理解每一段語法打好基礎!

撰寫合約:

查閱 Solidity 的 Changelog 可以發現在 0.4.22 版加入了建構子語法
按照新語法把合約內容更新一番:

將版本宣告變更為 0.4.22,並改寫建構子語法

再來就可以參考 TutorialToken 開始編寫合約內容了!

當然,既然已經有前人幫我們造了輪子,就不用費心從頭自己造了
安裝完套件即可直接引入合約:

# 利用 Yarn 安裝 openzeppelin-solidity 套件
yarn add openzeppelin-solidity

查閱 OpenZepplein Solidity 專案找到所需的貨幣 (Token) 合約:

ERC20, ERC721, ERC827?

這時出現了一個先前沒看過的名詞:ERC
經過了解,它實際上就是經由社群所討論出來的合約規範
讓開發者們能有個標準依循,例如這份合約一定要含有轉帳功能等
而這次的實驗基本上選用 ERC20 做為標準就足夠了

引入 openzeppelin-solidity/contracts/token/ERC20/StandardToken.sol
接著以 StandardToken 做為基底,並宣告以下屬性:

  • name -- 貨幣名(自由決定)
  • symbol--貨幣特徵名(自由決定)
  • decimals-- 貨幣最小單位(表示這個貨幣可以被分割到小數點後第幾位數)
  • INITIAL_SUPPLY-- 初始貨幣供應量(自由決定)

有許多文章提到自製貨幣可選擇性加上 name ,symbol ,decimals 這些屬性
但是查閱了 ERC20 的規範後,卻找不到關於這些屬性的詳細說明
例如 symbol 是否有字數限制,或是 decimals 是否有長度限制等
也不清楚這幾個屬性的由來是什麼,為何會這麼命名?讓我有點疑惑
後來翻到 EIP20 的相關討論才明白:

There will be tokens minted that don’t have any requirement for names, symbols or decimals. Like prediction market outcomes or energy meter kwh tokens for example. This should not be at the token layer. All tokens are not automatically a sub-currency or coin (that uses additional information).

簡言之 ERC20 僅規範了 Token 的最低流通需求
開發者可以基於它,再衍生出適用於不同狀況的貨幣

不過貨幣總免不了要有名稱或是縮寫等利於辨識的資訊,交易起來比較方便
在 symbol 長度沒有硬性規定的狀況下
可能就會有 name 跟 symbol 一樣,甚至 symbol 比 name 長的狀況產生
這兩個欄位是否就失去意義了?
也許在未來的 ERC 會將這些視為標準也說不定,這邊就不再深究

撰寫完成的合約如下:

如果對程式語言有基本的了解,會發現 Solidity 語法其實非常簡單易讀
宣告式是以 型別 可視性 是否為不變常數(選擇性) 屬性名 = 所組成

不過建構子的部分出現了兩個沒宣告的屬性 totalSupply_balances
初步推測可能跟這份合約是衍生自 StandardToken 有關
進一步追蹤會發現 StandardToken 又衍生自 BasicToken

在 BasicToken 中可以找到這兩個屬性
  • totalSupply_ -- 貨幣發行總量
  • balances -- 此份合約所有帳號餘額

了解所有屬性的由來後,這份簡易的合約就撰寫完畢了

編譯合約:

完成合約後,需要告知 Truffle 如何部署這份合約
新增 migrations/2_deploy_contracts.js
TutorialToken 合約加入部署階段即可:

假如我們在部署 B 合約時會需要用到 A 合約的資訊又該怎麼做呢?
這在 Truffle Deployer 文件中有提及:

deployer 可以寫成同步形式,也可寫成 Promise 鏈

可以利用 JavaScript Promise 語法,將資訊傳給後面的函式達成這個需求

了解完畢後,輸入 truffle compile 指令
即可看到編譯後的合約存放於 build 資料夾中:

發佈合約:

發佈合約等同是呼叫區塊鏈上的節點來幫忙執行自己寫的程式
在以太坊的機制中,會根據合約內容計算出所需的計算力 (Gas)
如果要發佈放到區塊主鏈上,就需要給予鏈上的節點以太幣做為報酬才行

這時可以利用 Ganache 建立自己的私有區塊鏈做測試
把自己的電腦變成區塊鏈上的唯一節點直接解析合約,就不需支付費用
安裝並啟動後可以看到以下畫面:

Ganache 會自動建立多組錢包供測試 (可以在設定中調整組數)
預設的私鏈位址為 http://127.0.0.1:7545
接著就可以利用 truffle migrate 指令將合約發佈到私鏈上:

可以在 Transations 頁觀察到區塊鏈消耗了 Gas 並完成了合約發佈

履行合約、移轉貨幣:

利用樣板內建的 Web Server 跟前端介面進行轉帳
使用 yarn dev 指令將 Server 啟動,預設會在 localhost:3000

再來使用 MetaMask 與私鏈建立連線,並導入錢包私鑰
測試時就可以快速在私鏈上切換錢包、檢視錢包狀態:

選擇對應的錢包後,會看到合約一開始訂立的貨幣量顯示在畫面上:

透過介面進行轉帳,輸入目標錢包位址以及轉帳單位量:

轉帳完畢後,Ganache 介面上會同步觀察到合約已被觸發
接著再用 MetaMask 切換到目標錢包,看裡面是否成功收到了 2000 TT:

結論:

透過這次實驗可以大概了解合約從無到有的建立與發佈流程
雖然整體流程以及合約的編寫看起來很容易
但如何利用這些機制開發去中心化的應用程式 (Dapp),實現商業邏輯
才是一門有趣且高深的學問啊!

--

--