【Ethereum 智能合約開發筆記】使用 MetaMask, web3 和 EthJS 呼叫合約

一起來輕鬆開發 Dapp!

Anderson Chen
Dapp Pocket
10 min readMar 2, 2018

--

使用 web3 JavaScript API(簡稱 web3) 應該是開發 DApp 必須的,不管要查詢 Ethereum 區塊鏈狀態、發送交易、呼叫智能合約都可以透過 web3。使用 web3 必須連結到 Ethereum 節點,之前我寫了一篇使用 Infura 提供的節點:

其實常用的 Ethereum 瀏覽器錢包 — MetaMask 也有提供 web3 provider,用他提供的 provider 初始化 web3,就可以連上 MetaMask 提供的節點。參考以下兩篇官方文件,我實作了簡單的範例,並記錄幾個可能碰到的問題。

MetaMask Compatibility Guide

Developing for MetaMask

另外 MetaMask/mascara 提供在不安裝 MetaMask 的環境下,使用 MetaMask 提供的 web3。

使用範例

寫一個簡單的 JavaScript 程式,使用 MetaMask 提供的 web3 provider 來初始化 web3:

用 browserify 打包:

在 HTML file 中執行:

再寫個 HTML file 測試看看。希望透過 MetaMask 提供的 web3 取得:

  1. web3 的 API version
  2. 我的 MetaMask account

執行結果:

可能碰到的問題

1) 找不到 web3.currentProvider

Due to browser security restrictions, we can’t communicate with dapps running on file://. Please use a local server for development.

  • 必須確認啟用 MetaMask extension。

2) 無法取得 web3.eth.accounts

必須用密碼解鎖 MetaMask,不然會回傳 undefined

3) 沒有使用 callback

MetaMask 官方文件表示所有提供的 web3 API 都是非同步,必須要傳入 callback function,除了以下例外:

  • eth_accounts (web3.eth.accounts)
  • eth_coinbase (web3.eth.coinbase)
  • eth_uninstallFilter (web3.eth.uninstallFilter)
  • web3.eth.reset (uninstalls all filters)
  • net_version (web3.version.network)

除了以上 API,我在使用時也有其他 API 不需要 callback。但確實碰到 API 是必需要用 callback,不然 MetaMask 會跳出 error。

4) Web3 API 版本

以上範例是使用 官方 wiki 的 API,版本是 0.2x.x。如果直接用 npm install web3 ,根據我的經驗會安裝的版本為 1.0.0,API 使用的方法會有些不同,使用方式請看 web3.js Doc

使用 EthJS 呼叫合約

EthJS 是另一個 Ethereum 的 JavaScript API,也是 MetaMask 開發者推薦的 JavaScript API。根據 EthJS 官方文件的描述:

EthJS is a highly optimised, light-weight JS utility for Ethereum based on web3.js, but lighter, async only and using BN.js.

EthJS 分為多個 module,如果要使用合約要安裝這兩個:

同樣使用 MetaMask 提供的 web3 provider 來初始化 EthJS:

使用 contract 初始化合約,一樣需要合約的 ABI 和 address:

寫一個簡單的 HTML file,有一個 input 欄位可以輸入任意數值,和一個 button。

在寫一個 JavaScript function 監聽這個 button,按下 button 後會透過 EthJS 呼叫合約的 set(uint256),把合約中的狀態 data 設為對應數值。要呼叫合約不需要知道 function signature,也不用自己建 transaction。就像使用 JavaScript 物件中的 function,像是: simpleStorage.set(param, {from: myAddr}, callback() {...})

用看看

1. 任意輸入一個數字後,按 Set Data!

輸入 20

2. 跳出 MetaMask 的提醒視窗。MetaMask 提供介面讓使用者授權交易的發送,點擊 confirm 就可以發送這筆交易。

3. 發送成功,取得 Transaction Hash。

4. 等 transaction confirm 後,再去呼叫合約的 data(),就會得到更新後的值。一樣可以透過 EthJS,像是這段簡單的 code:

References

--

--