使用Node.js部署智能合約(Smart Contract)
從智能合約原始檔、編譯、部署,一氣呵成
我想大部分的人應該都是為了寫智能合約(Smart Contract)而選擇使用Ethereum,在開發應用程式(Dapp)時,若能透過程式碼自動部署智能合約,就像truffle一樣,即可以省下可觀的測試時間。
本教學文適合有Node.js與Solidity基礎的讀者。本文預設的系統架構如下圖,共有兩個角色,首先有作為測試使用的PoA chain,包含至少兩個Authority node?node0, node1?。接著是以node.js開發的app,將會使用web3.js?module (這是本篇的主角),透過JSON RPC API與?node0?溝通。全部的流程只有下列三個步驟:
1. 架設測試用的chain
可以依據自己的習慣使用testrpc, ethereum testnet或是參考下列文章建立一個測試用的PoA chain。
使用Parity建立Proof-of-Authority (PoA) Ethereum Chain5分鐘快速從無到有建立Ethereum聯盟鏈medium.com
在後續的操作過程中,chain都要保持開啟的狀態,不再特別提醒。
2. 建立Node.js專案
$ mkdir deploy_contract $ cd deploy_contract $ npm init #一路enter到底此時檔案結構如下:
deploy-contract └── package.json3. 連接至PoA?chain
為了讓其他開發者能夠方便地與Ethereum node溝通,Ethereum定義了JSON RPC API介面,使用JSON-RPC 2.0標準。基本上這是一個無關傳輸協定(transport agnostic)的標準,只定義資料交換格式,所以不管是透過HTTP或是socket通訊,都應該要得到相同的結果。
因為我們使用node.js開發app,所以選擇使用web3.js模組,它完整實作了JSON RPC API,可以很方便地呼叫?node0?幫我們做事。
Step 1.?安裝web3.js模組
$ npm install web3 --save #在deploy_contract目錄裡安裝web3.js模組Step 2.?新增index.js檔案,填入下列code
- ethereumUri設定連接至?node0?的位址與port,一般來說JSON RPC的port是8545,但此範例是依照PoA chain的設定使用?http://localhost:8450。
- 設定web3 Provider連接至?node0?,接著呼叫isConnected()確認連接是否成功
- 最後取些基本資料,coinbase, getBalance, accounts,測試是否能夠順利溝通。輸出資料如下(若有按照PoA chain來設定輸出應該會一致,但balance可能會有些微差異)
coinbase 就是?node0?的Authority account位址
accounts 列表會有兩個,一個是 user account,另一個是Authority account。
此時檔案結構如下:
deploy-contract ├── index.js ├── node_modules └── package.json4. 編譯智能合約sol檔案
這邊要使用solc.js模組來編譯智能合約sol檔案,最後取得部署合約需要的資訊:
- ABI (Application Binary Interface)
- bytecode
Step 1.?安裝solc.js
$ npm install solc --saveStep 2.?建立contracts資料夾
$ mkdir contracts $ cd contractsStep 3.?在contracts資料夾裡面新增一個BasicToken.sol檔案
填入下列code (此範例由openZeppelin專案修改而來)
此時檔案結構如下:
deploy-contract ├── contracts //新增 │ └── BasicToken.sol //新增 ├── index.js ├── node_modules └── package.jsonStep 4.?開啟index.js,載入fs與solc模組,並加入編譯合約的程式碼
- 透過fs.readFileSync讀取BasicToken.sol內容
- 使用solc.compile編譯合約,得到一個JSON物件
- 取出我們需要的bytecode與ABI
- 最後印出ABI看看是否跟BasicToken.sol定義的function相同
5. 部署智能合約
部署合約就跟一般的交易一樣,需要發送一個交易至?node0?,因此要付交易手續費(gas),所以需要一個有足夠ETH的帳戶,這邊使用?user?這個User account,但使用之前要透過web3.personal.unlockAccount解除鎖定。
Step 1.?unlockAccount
開啟index.js,修改connect部分的程式碼,如下:
- 宣告address為user account
- 呼叫web3.personal.unlockAccount(addr, passwd)解鎖user account
addr填入欲解鎖的帳戶,即上面的?address?
passwd填入帳戶的密碼,如PoA chain裡的?'user'
執行
$ node index.js //執行會看到unlocked資訊,後面省略Step 2.?加入部署合約的code
開啟index.js,code加在最後面,如下:
- 先預估會消耗的gas,?web3.eth.estimateGas({data: bytecode})?這邊只需要提供交易的data資訊即可。
- 使用abi建立一個contract instance
- 部署合約使用 web3.js封裝過的MyContract.new(),就會自動幫我們發送transaction至?node0
new()參數如下圖,總共有四個,其中?param1, param2?是optional,就我們的例子不需要填寫,只要給 transaction object與callback即可。
web3.js的contract.new() methodtransaction object需要提供下列資訊:
{from: address, // user accountdata: '0x'+ bytecode, // 記得加 '0x'gas: gasEstimate + 50000 // 多加一些gas,不然gas會不足 }- 為了等待callback,以取得transaction id與部署之後的contract address,再加入下列wait function
執行程式
$ node index.js 輸出transaction id 與 contract address,前面省略完整的index.js內容應該要長這樣:6. 測試智能合約功能
我們有contract address與abi就可以使用Parity UI加入已經部署成功的合約,並且使用合約上面的功能。
礙於篇幅長度,這邊使用Parity UI來測試,下次再寫篇透過web3.js呼叫智能合約的介紹文。Step 1.?到SETTINGS頁面開啟Contracts功能
開啟Contracts功能Step 2.?設定已經部署成功的智能合約
至CONTRACTS頁面,選擇WATCH CONTRACT
選擇 WATCH?CONTRACT選擇Custom Contract填入contract address, abi, 以及名稱
- contract address,請填入node.js app輸出的address
- abi
點進去之後就可以使用合約功能
查詢User的token數量,總共10,000這樣就完成了,完整的程式碼都在這裡。
https://medium.com/taipei-ethereum-meetup/%E4%BD%BF%E7%94%A8node-js%E9%83%A8%E7%BD%B2%E6%99%BA%E8%83%BD%E5%90%88%E7%B4%84-smart-contract-520534305aaf
總結
以上是生活随笔為你收集整理的使用Node.js部署智能合約(Smart Contract)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Truffle 4.0、Geth 1.7
- 下一篇: 以太坊Oracle系列二:My Orac