五分鐘構(gòu)建基于以太坊(Ethereum)錢(qián)包Parity的聯(lián)盟鏈測(cè)試環(huán)境
作者:張立勇 區(qū)塊鏈底層開(kāi)發(fā)| 網(wǎng)絡(luò)架構(gòu) | 網(wǎng)絡(luò)運(yùn)維自動(dòng)化
微信ID:yy109628620 博客:https://bolenzhang.github.io
parity是什么?
Ethereum的常見(jiàn)客戶(hù)端一般有g(shù)eth和eth。Parity是由以太坊前CTO開(kāi)發(fā)的一款Ehtereum客戶(hù)端(即以太坊錢(qián)包)。它是用一種全新的系統(tǒng)級(jí)別的編程語(yǔ)言RUST開(kāi)發(fā)而成。
為什么需要PoA chain?
在寫(xiě)基于以太坊的DAPP時(shí)經(jīng)常要通過(guò)testRPC或或直連以太坊的testnet作一些測(cè)試,但是testRPC各種坑,而testnet還要等待漫長(zhǎng)的同步block時(shí)間。Parity1.5以后支持PoA可以直接解決上述問(wèn)題。
PoA chain的應(yīng)用場(chǎng)景
- 公司測(cè)試網(wǎng)絡(luò)無(wú)法同步區(qū)塊
- 降低測(cè)試時(shí)等待區(qū)塊的時(shí)間
- 不想碰到testrpc各種坑
PoA Chain特點(diǎn)
- 有別于
PoW(Proof-of-Work)需要解數(shù)學(xué)難題來(lái)產(chǎn)生block,PoA是依靠預(yù)設(shè)好的Authority nodes,負(fù)責(zé)產(chǎn)生block。 - 可依照需求設(shè)定
Authority node數(shù)量。 - 可指定產(chǎn)生
block的時(shí)間,例如收到交易的5秒后產(chǎn)生block。 - 一般的
Ethereum node也可以連接到PoA Chain,正常發(fā)起transactions,contracts等。
parity是一個(gè)注重效率的以太坊客戶(hù)端軟件
大綱
- Parity錢(qián)包下載安裝
- 設(shè)置chain spec
- 設(shè)置兩個(gè)節(jié)點(diǎn)
- 設(shè)置賬號(hào)(Account)
- 啟動(dòng)Authority node
- 連接兩個(gè)節(jié)點(diǎn)
- 發(fā)送交易
- 分享給其他節(jié)點(diǎn)
一、Parity錢(qián)包下載安裝
之前的教程中我們講解了Mist錢(qián)包、MetaMask、myetherwallet錢(qián)包,這篇教程中,我們系統(tǒng)介紹一下Parity錢(qián)包的使用,為下一篇文章中聯(lián)盟鏈搭建做鋪墊。
Parity錢(qián)包下載安裝https://parity.io。

如官網(wǎng)所示,The fastest and most secure way of interacting with the Ethereum blockchain。
打開(kāi)官網(wǎng),我們看到有三種安裝方式,第一種,直接下載安裝,第二種,Brew安裝,第三種,Docker安裝。
在我們的示例中,我們以Ubuntu為例來(lái)進(jìn)行安裝。
1、Getting Homebrew
/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
2、Adding Parity to your list of Homebrew 'kegs'
打開(kāi)終端,輸入下面的命令,按enter。
brew tap paritytech/paritytech
3、Installing Parity
- 穩(wěn)定版
brew install parity --stable
- 最新版
brew install parity
- 最新開(kāi)發(fā)版
brew install parity --master
- 更新最新版本
brew update && brew upgrade parity
and
brew reinstall parity
4、查看安裝版本
liyuechun:~ yuechunli$ parity --version
Parity
version Parity/v1.8.2-beta-1b6588c-20171025/x86_64-macos/rustc1.21.0
Copyright 2015, 2016, 2017 Parity Technologies (UK) Ltd
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>.
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
By Wood/Paronyan/Kotewicz/Drwi?ga/Volf
Habermeier/Czaban/Greeff/Gotchac/Redmann
liyuechun:~ yuechunli$
二、設(shè)置chain spec
PoA chain 需要設(shè)置一個(gè)創(chuàng)世區(qū)塊。
{
"name": "DemoPoA",
"engine": {
"authorityRound": {
"params": {
"stepDuration": "5",
"validators": {
"list": [
]
}
}
}
},
"params": {
"gasLimitBoundDivisor": "0x0400",
"maximumExtraDataSize": "0x20",
"minGasLimit": "0x1388",
"networkID": "0x2323"
},
"genesis": {
"seal": {
"authorityRound": {
"step": "0x0",
"signature": "0x0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
}
},
"difficulty": "0x20000",
"gasLimit": "0x5B8D80"
},
"accounts": {
"0x0000000000000000000000000000000000000001": {
"balance": "1",
"builtin": {
"name": "ecrecover",
"pricing": {
"linear": {
"base": 3000,
"word": 0
}
}
}
},
"0x0000000000000000000000000000000000000002": {
"balance": "1",
"builtin": {
"name": "sha256",
"pricing": {
"linear": {
"base": 60,
"word": 12
}
}
}
},
"0x0000000000000000000000000000000000000003": {
"balance": "1",
"builtin": {
"name": "ripemd160",
"pricing": {
"linear": {
"base": 600,
"word": 120
}
}
}
},
"0x0000000000000000000000000000000000000004": {
"balance": "1",
"builtin": {
"name": "identity",
"pricing": {
"linear": {
"base": 15,
"word": 3
}
}
}
}
}
}
-
stepDuration設(shè)定成5秒產(chǎn)生一個(gè)區(qū)塊。 -
validators設(shè)定Authority的地方,目前先空著,后面創(chuàng)建account之后再回來(lái)填入。
將上面的文件保存到桌面的一個(gè)文件中,保存為demo-spec.json。
三、設(shè)置兩個(gè)節(jié)點(diǎn)
在我們這篇文章中,我們?cè)谕慌_(tái)電腦設(shè)置兩個(gè)節(jié)點(diǎn),跟我們講解以太坊私網(wǎng)建立 (2) - 同一臺(tái)電腦/不同電腦運(yùn)行多個(gè)節(jié)點(diǎn)時(shí),如果在同一臺(tái)電腦設(shè)置兩個(gè)節(jié)點(diǎn),需要將rpcport和port設(shè)置為不同的值,否則就會(huì)發(fā)生沖突,POA chain中也是一樣,需要將一些參數(shù)設(shè)置為不同的值。
-
-d:指定存儲(chǔ)資料與賬號(hào)的目錄 -
--dport:指定Parity的network port,可用來(lái)讓其他node連接 -
--jsonrpc-port:這是JSON RPC port,使用web3.js時(shí)會(huì)需要 -
ui-port:Parity提供的Web-based UI port
可以用下列指令啟動(dòng)Parity node。
parity --chain demo-spec.json -d parity0 --port 30300 --ui-port 8180 --jsonrpc-port 8540 --jsonrpc-apis web3,eth,net,personal,parity,parity_set,traces,rpc,parity_accounts
除了打一長(zhǎng)串的指令外,Parity也提供更為簡(jiǎn)潔的config檔案設(shè)定方式,使用 --config 即可引用配置文件。
-
node0使用如下配置文件node0.toml:
[parity]
chain = "demo-spec.json"
base_path = "parity0"
[network]
port = 30300
[rpc]
port = 8540
apis = ["web3", "eth", "net", "personal", "parity", "parity_set", "traces", "rpc", "parity_accounts"]
cors = ["*"]
[ui]
port = 8180
[websockets]
port = 8456
-
node1使用如下配置文件node1.toml:
[parity]
chain = "demo-spec.json"
base_path = "parity1"
[network]
port = 30301
[rpc]
port = 8541
apis = ["web3", "eth", "net", "personal", "parity", "parity_set", "traces", "rpc", "parity_accounts"]
cors = ["*"]
[ui]
port = 8181
[websockets]
port = 8457
四、設(shè)置賬號(hào)(Account)
我們總共需要設(shè)置三個(gè)賬號(hào),兩個(gè)Authority和一個(gè)user賬號(hào)。
第一步:首先啟動(dòng)node0 : parity --config node0.toml

打開(kāi)網(wǎng)頁(yè)http://localhost:8180,按照步驟創(chuàng)建一個(gè)用戶(hù)賬號(hào)。






- 新增
Authority account,使用Restore功能,為了示范一致性,我們使用node0當(dāng)作pass phrase。



到目前為止我們已經(jīng)完成node0的賬號(hào)設(shè)置。
-
Authority account:
0x00Bd138aBD70e2F00903268F3Db08f2D25677C9e -
User account:
0x0064B0999c0142eE99aB0ceC054BAb53fe0a3EcC
第二步:設(shè)置node1的賬號(hào),啟動(dòng)parity --config node1.toml。步驟相同,連接到 http://localhost:8181 ,pass phrase使用 node1。


這樣就完成了node1的賬號(hào)設(shè)置。
-
Authority account:
0x00F9B30838ca40c8A53c672840acbDec6fCDb180
第三步:將Authority account 寫(xiě)入 demo-spec.json 文件
"validators": {
"list": [
"0x00F9B30838ca40c8A53c672840acbDec6fCDb180",
"0x00Bd138aBD70e2F00903268F3Db08f2D25677C9e"
]
}
再將user account加入accounts,並給一些balance,后續(xù)可以使用。
"0x0064B0999c0142eE99aB0ceC054BAb53fe0a3EcC": {
"balance": "10000000000000000000000"
}
完成后的demo-spec.json如下:
{
"name": "DemoPoA",
"engine": {
"authorityRound": {
"params": {
"stepDuration": "5",
"validators": {
"list": [
"0x00F9B30838ca40c8A53c672840acbDec6fCDb180",
"0x00Bd138aBD70e2F00903268F3Db08f2D25677C9e"
]
}
}
}
},
"params": {
"gasLimitBoundDivisor": "0x0400",
"maximumExtraDataSize": "0x20",
"minGasLimit": "0x1388",
"networkID": "0x2323"
},
"genesis": {
"seal": {
"authorityRound": {
"step": "0x0",
"signature": "0x0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
}
},
"difficulty": "0x20000",
"gasLimit": "0x5B8D80"
},
"accounts": {
"0x0000000000000000000000000000000000000001": {
"balance": "1",
"builtin": {
"name": "ecrecover",
"pricing": {
"linear": {
"base": 3000,
"word": 0
}
}
}
},
"0x0000000000000000000000000000000000000002": {
"balance": "1",
"builtin": {
"name": "sha256",
"pricing": {
"linear": {
"base": 60,
"word": 12
}
}
}
},
"0x0000000000000000000000000000000000000003": {
"balance": "1",
"builtin": {
"name": "ripemd160",
"pricing": {
"linear": {
"base": 600,
"word": 120
}
}
}
},
"0x0064B0999c0142eE99aB0ceC054BAb53fe0a3EcC": {
"balance": "10000000000000000000000"
},
"0x0000000000000000000000000000000000000004": {
"balance": "1",
"builtin": {
"name": "identity",
"pricing": {
"linear": {
"base": 15,
"word": 3
}
}
}
}
}
}
五、啟動(dòng)Authority node
為了啟動(dòng)Authority node來(lái)產(chǎn)生區(qū)塊,我們必須設(shè)定負(fù)責(zé)產(chǎn)生block的signer,分別是 node0 和 node1 account。
1、第一步,創(chuàng)建一個(gè)node.pwds文件,寫(xiě)入node0與node1的password,內(nèi)容如下:
node0
node1
2、第二步,在node0.toml文件中加入[account]及[mining]設(shè)置,如下:
[parity]
chain = "demo-spec.json"
base_path = "parity0"
[network]
port = 30300
[rpc]
port = 8540
apis = ["web3", "eth", "net", "personal", "parity", "parity_set", "traces", "rpc", "parity_accounts"]
cors = ["*"]
[ui]
port = 8180
[account]
password = ["node.pwds"]
[mining]
engine_signer = "0x00Bd138aBD70e2F00903268F3Db08f2D25677C9e"
reseal_on_txs = "none"
3、第三步,在node1.toml文件中加入[account]及[mining]設(shè)置,如下:
[parity]
chain = "demo-spec.json"
base_path = "parity1"
[network]
port = 30301
[rpc]
port = 8541
apis = ["web3", "eth", "net", "personal", "parity", "parity_set", "traces", "rpc", "parity_accounts"]
cors = ["*"]
[ui]
port = 8181
[websockets]
port = 8457
[account]
password = ["node.pwds"]
[mining]
engine_signer = "0x00F9B30838ca40c8A53c672840acbDec6fCDb180"
reseal_on_txs = "none"
4、第四步,Step 4 分別啟動(dòng)兩個(gè)node
parity --config node0.toml
parity --config node1.toml
六、連接兩個(gè)節(jié)點(diǎn)
使用Postman透過(guò)JSON RPC來(lái)測(cè)試。
1、第一步,Post下列JSON數(shù)據(jù)至 http://localhost:8540 以取得 node0 的enode資料
{
"jsonrpc":"2.0",
"method":"parity_enode",
"params":[],
"id":0
}

獲取到的數(shù)據(jù)如下:
{
"jsonrpc": "2.0",
"result": "enode://cfb3af513da3a7a8138450f0dc01fa38cb2ac837744dc645038940287f4dce3f416f0e7e17fd10619a263c360d9324fd2dcd8753c4500fcc54cf84e076b39cd6@192.168.10.101:30300",
"id": 0
}
"enode://cfb3af513da3a7a8138450f0dc01fa38cb2ac837744dc645038940287f4dce3f416f0e7e17fd10619a263c360d9324fd2dcd8753c4500fcc54cf84e076b39cd6@192.168.10.101:30300"是node0的標(biāo)識(shí)。下一步中我們將將它加入到node1中以實(shí)現(xiàn)兩個(gè)節(jié)點(diǎn)之間的連接。
2、第二步,將 node0 的enode加入 node1 ,Post下列JSONs數(shù)據(jù)至node1 (http://localhost:8541 )
{
"jsonrpc":"2.0",
"method":"parity_addReservedPeer",
"params":["enode://cfb3af513da3a7a8138450f0dc01fa38cb2ac837744dc645038940287f4dce3f416f0e7e17fd10619a263c360d9324fd2dcd8753c4500fcc54cf84e076b39cd6@192.168.10.101:30300"],
"id":0
}

返回的數(shù)據(jù)如下,result為true,說(shuō)明連接成功:
{
"jsonrpc": "2.0",
"result": true,
"id": 0
}
再切換到node1的終端,會(huì)看到下面的數(shù)據(jù):
1/25 peers 13 KiB chain 11 KiB db 0 bytes queue 10 KiB sync RPC: 0 conn, 0 req/s, 24 μs

如上圖所示,表示連接成功。
七、發(fā)送交易
在我們這個(gè)案例中,我們一個(gè)創(chuàng)建了三個(gè)賬號(hào),一個(gè)用戶(hù)賬號(hào),兩個(gè)POA賬號(hào),剛開(kāi)始的時(shí)候我們?yōu)橛脩?hù)賬號(hào)初始化了10000 ETH。如下圖所示,賬號(hào)與賬號(hào)之間可以相互轉(zhuǎn)賬。





八、分享給其他節(jié)點(diǎn)
在開(kāi)發(fā)時(shí)通常會(huì)將node跑在server上,讓其他人可以通過(guò)JSON RPC port連接上去使用,此時(shí)只要在config文件里面加入 [interface] 設(shè)置即可。
假設(shè)server ip為192.168.1.5,將 node0.toml 修改如下:
[parity]
chain = "demo-spec.json"
base_path = "parity0"
[network]
port = 30300
[rpc]
port = 8540
apis = ["web3", "eth", "net", "personal", "parity", "parity_set", "traces", "rpc", "parity_accounts"]
cors = ["*"]
interface = "192.168.1.5"
[ui]
port = 8180
[account]
password = ["node.pwds"]
[mining]
engine_signer = "0x00Bd138aBD70e2F00903268F3Db08f2D25677C9e"
reseal_on_txs = "none"
node1.toml 修改如下:
[parity]
chain = "demo-spec.json"
base_path = "parity1"
[network]
port = 30301
[rpc]
port = 8541
apis = ["web3", "eth", "net", "personal", "parity", "parity_set", "traces", "rpc", "parity_accounts"]
interface = "192.168.1.5"
cors = ["*"]
[ui]
port = 8181
[websockets]
port = 8457
[account]
password = ["node.pwds"]
[mining]
engine_signer = "0x00F9B30838ca40c8A53c672840acbDec6fCDb180"
reseal_on_txs = "none"