用Loom SDK 搭建的以太坊側鏈並部署智慧合約
前兩天寫了一篇 用Truffle開發一個鏈上記事本 ,很多人講,這樣寫一條筆記成本該多高呀,今天我們開看看如何在Loom SDK 搭建的以太坊側鏈部署這個DApp。
關於 Loom
Loom (或者稱 Loom Network) 是一支探索區塊鏈二層擴容方面技術的團隊,他們在嘗試構建可用於遊戲等領域的二層網路(Layer2)平臺,目前兩個開發的兩個重要產品是 Loom PlasmaChain 及 Loom SDK 。
Loom PlasmaChain
Loom PlasmaChain是一條實現了 Plasma Cash 框架模型 的高效能 DPoS 側鏈(提供1–3秒的交易確認時間)。
這條側鏈帶來的特點是顯而易見的,它可以獲得由以太坊底層網路的安全背書,讓我們使用在以太坊上釋出的Token(包含 ERC20和 ERC721支援),又可以享受 DPos 共識帶來的高效能。
以太坊交易確認至少是15秒以上,並且需要消耗一筆 Gas 費用,當然因此犧牲了一些去中心化。
這張圖可以表明 PlasmaChain 與 以太坊的關係,它未來會連結多條側鏈,據官方搞 PlasmaChain 整合排名前100的ERC20代幣,其中包含6種穩定幣。
Loom SDK(工具集)
Loom SDK則讓開發者快速構建自己的區塊鏈(DApp側鏈),同時也提供了一些工具開發部署應用,它包含內容有:
-
一個可執行的
loom
命令列工具, 用於建立一條自己的應用鏈。有時狹義的Loom SDK就是單指這個工具
- 一些其他工具,如用來在主鏈和側鏈之間轉移資產的工具:plasma-cli gateway-cli。
-
用來部署合約及開發DApp 的 JavaScript SDK, 包含
Loom Truffle Provider
及loom-js
, 這篇文章後面會介紹他的使用。 -
用來部署合約及開發DApp 的 Go SDK。
- 以及開發遊戲相關的 SDK: Cosos SDK、Unity SDK。
本篇文章重點就是要介紹如何使用 Loom SDK 建立一條自己的鏈並部署應用。
Loom 安裝 & 啟動區塊鏈
loom
安裝
loom
命令列工具安裝很簡單,直接下載可執行檔案,在控制檯輸入:
wget https://private.delegatecall.com/loom/osx/stable/loom chmod +x loom
大家可以把 loom
加入到環境變數裡,方便後面使用。
我使用的系統是 Mac OS, 如果你使用 Linux, 則 wget 後面的 url 是 https://private.delegatecall.com/loom/linux/stable/loom
,Window 暫時不支援,可以選擇虛擬機器。
初始化鏈
mkdir loom-chain# 為側鏈建立一個目錄 cd loom-chain loom init
初始化命令會生成 genesis.json
和 chaindata
目錄, genesis.json
是這條側鏈的創世紀塊配置, chaindata
目錄使用者儲存區塊資料。
執行區塊鏈
使用以下的命令可以啟動剛剛初始化的DApp側鏈:
loom run
輸出像下面這樣:
I[29046-04-29|20:46:50.356] Loading IAVL Storemodule=loom I[29046-04-29|20:46:50.362] Using simple log event dispatcher I[29046-04-29|20:46:50.368] Deployed contractvm=plugin location=coin:1.0.0 name=coin address=default:0xe288d6eec7150D6a22FDE33F0AA2d81E06591C4d Init DPOS Params &dpos.DPOSInitRequest{Params:(*dpos.Params)(0xc000e44dc0), Validators:[]*types.Validator{(*types.Validator)(0xc000e46dc0)}, XXX_NoUnkeyedLiteral:struct {}{}, XXX_unrecognized:[]uint8(nil), XXX_sizecache:0} I[29046-04-29|20:46:50.369] Deployed contractvm=plugin location=dpos:1.0.0 name=dpos address=default:0x01D10029c253fA02D76188b84b5846ab3D19510D E[29046-04-29|20:46:50.374] Couldn't connect to any seedsmodule=p2p I[29046-04-29|20:46:50.374] Starting RPC HTTP server on [::]:46658module=query-server I[29046-04-29|20:46:50.374] Starting RPC HTTP server on 127.0.0.1:9999module=query-server
啟動的側鏈執行在埠 46658
上, 可以通過區塊鏈瀏覽器 https://blockexplorer.loomx.io/?rpc=http://127.0.0.1:46658
, 檢視這條測試鏈的出塊資料,如圖:

https://blockexplorer.loomx.io/
是 Plasma Chain
的區塊鏈瀏覽器,在區塊瀏覽器瀏覽器的下方可以選擇連結的RPC 伺服器,選擇本地的IP及埠。
現在鏈已經準備好了,接下來就是開發及部署DApp了,我們依然使用 Truffle 進行開發,不熟悉可參考: Truffle 官方開發文件-中文
在側鏈上開發和部署智慧合約
在 用Truffle開發一個鏈上記事本 文章裡,以及介紹瞭如何開發這個DApp 這裡不再重複介紹。
這個鏈上記事本的原始碼在 GitHub , 進行下面的操作之前,需要 git clone 到本地:
> git clone [email protected]:xilibi2003/note_dapp.git > npm install# 安裝相應的依賴
Truffle 配置側鏈網路
原來的程式碼裡,Truffle 連線的是以太坊網路,因此需要修改 truffle.js
新增剛剛建立的側鏈網路,和我們之前介紹的 使用 truffle-hdwallet-provider
連線 Infura
網路原理類似,連線側鏈網路也需要提供一個 Provider
,它是 Loom Truffle Provider , 修改配置之前先安裝它:
npm install loom-truffle-provider --save
然後修改配置檔案 truffle.js
,(這有有一份Truffle 配置 文件),參考配置如下:
const { readFileSync } = require('fs') const LoomTruffleProvider = require('loom-truffle-provider') const chainId= 'default' const writeUrl= 'http://127.0.0.1:46658/rpc' const readUrl= 'http://127.0.0.1:46658/query' const privateKey = readFileSync('./priv_key', 'utf-8') const loomTruffleProvider = new LoomTruffleProvider(chainId, writeUrl, readUrl, privateKey) module.exports = { networks: { loom_dapp_chain: { provider: loomTruffleProvider, network_id: '*' } } }
在配置裡,我們新加入一個網路 loom_dapp_chain
,這個網路有 LoomTruffleProvider 提供, http://127.0.0.1:46658/
是 使用 loom run
啟動側鏈節點提供的RPC 服務, 細心的同學應該已經發現了 priv_key
, 它是用來部署合約到側鏈上賬號的私鑰檔案,下面就來建立它。
配置連結到其他的側鏈,可以參考 PlasmaChain 測試網
建立測鏈賬號
loom
工具提供了選項來建立賬號,在專案 note_dapp
目錄下,執行如下命令:
$ loom genkey -k priv_key -a pub_key
輸出結果像下面(當然大家的賬號和我的會不一樣):
local address: 0x8b7A68cFf3725ca1b682XLb575bC891e381138ef8 local address base64: i3poz/NyXKG2gv5XW8iR44ETjvg=
這個命令會在當前資料夾加生成私鑰和公鑰檔案: priv_key
和 pub_key
, priv_key
檔案裡包含後面用來把合同部署到側鏈的私鑰。
部署到DApp側鏈
執行部署時(需要先確定鏈當前在執行),使用 —network 指定網路,命令如下:
truffle migrate --network loom_dapp_chain
輸出的結構像下面:
Compiling ./contracts/Migrations.sol... Compiling ./contracts/NoteContract.sol... Writing artifacts to ./build/contracts Starting migrations... ====================== > Network name:'loom_dapp_chain' > Network id:13654820909954 > Block gas limit: 0 ....... 2_deploy_contract.js ==================== Deploying 'NoteContract' ------------------------ > transaction hash:0x88a6131cb89fcf...d72d3f92ceb2e > Blocks: 0Seconds: 0 > contract address:0x0611Afc2fac9B72f5a75E1BC330Ba4c5da103217 > account:0x8b7A68cFf3725ca1b682XLb575bC891e381138ef8 > balance:0 > gas used:0 > gas price:0 gwei > value sent:0 ETH > total cost:0 ETH > Saving migration to chain. > Saving artifacts ------------------------------------- > Total cost:0 ETH Summary ======= > Total deployments:2 > Final cost:0 ETH
從這個輸出會列出部署的網路名、網路id、交易hash、合約地址等資訊,用樣部署動作也在 build
目錄下生成對應的檔案 contracts/NoteContract.json
。
與側鏈上的智慧合約進行互動
Truffle 提供了一個控制檯truffle console
啟動控制檯
首先通過 --network
選項指定連線到DApp側鏈 loom_dapp_chain
, 進入控制檯,命令如下:
truffle console --network loom_dapp_chain
進入控制檯後,控制檯提示文字是這樣:
truffle(loom_dapp_chain)>
然後我們就可以在這個控制檯內執行互動命令。
獲取合約例項
truffle(loom_dapp_chain)> let instance = await NoteContract.deployed() truffle(loom_dapp_chain)> instance
檢視 instance
,會輸出 instance 例項的詳情,使用的Provider, 包含哪些方法,ABI 描述等, 結果像下面:
TruffleContract { ... web3: Web3 { class_defaults: { from: '0x8b7A68cFf3725ca1b682XLb575bC891e381138ef8', gas: 6721975, gasPrice: 20000000000 }, currentProvider: TruffleLoomProvider { _engine: [LoomProvider], send: [Function], _alreadyWrapped: true }, network_id: '13654820909954' }, methods: { 'notes(address,uint256)': { ... }, 'addNote(string)': {... }, 'getNotesLen(address)': {...}, 'modifyNote(address,uint256,string)': { ... }, abi: [...] }
通過合約例項呼叫合約函式
呼叫合約新增一條筆記:
truffle(loom_dapp_chain)> instance.addNote("abc");
獲取當前賬號(後面檢視筆記數量函式需要使用賬號作為引數,因此先獲取下賬號):
truffle(loom_dapp_chain)> let accounts = await web3.eth.getAccounts() truffle(loom_dapp_chain)> accounts[0]
這時控制檯會打印出賬號地址:
‘0x8b7A68cFf3725ca1b682XLb575bC891e381138ef8’
檢視這個下這個賬號的筆記條數:
truffle(loom_dapp_chain)> let noteNum = await instance.getNotesLen("0x8b7A68cFf3725ca1b682XLb575bC891e381138ef8") truffle(loom_dapp_chain)> noteNum.toNumber() # 輸出結果 1
呼叫其他的方法類似,不一一講解,可以參考 Truffle 文件 - 與合約互動
下一篇將繼續介紹在DApp 中怎麼和合約進行互動。