5分钟快速从无到有建立Ethereum联盟链
开发Ethereum Dapp的过程中,需要一个测试用的chain,之前是使用testrpc或直接连到Ethereum testnet (Ropsten),不过testrpc有各种坑需要处理,而Ropsten testnet则是需要同步与等待区块,相当的烦人。前几天看到Parity 1.5版以后支持建立Proof of Authority Chains,可以直接解决上述的问题,果然一试成主顾。
若你有下列困扰,可以建立自己测试用的PoA chain
PoA Chain特点有
Parity是一个注重效能的Ethereum Client端软体
请自行到Parity官网安装,支持Ubutnu, OSX, Docker, Windows
PoA chain需要设定一个创世区块
{
"name": "DemoPoA",
"engine": {
"authorityRound": {
"params": {
"gasLimitBoundDivisor": "0x400",
"stepDuration": "5",
"validators" : {
"list": []
}
}
}
},
"params": {
"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 } } } }
}
}
将上述资料存成 demo-spec.json
此教学会在同一台机器上跑两个node,因此有些Parity原生的设定参数会有衝突,两个node需要分别设定不同值。
可以用下列指令启动Parity node
parity --chain demo-spec.json -d /tmp/parity0 --port 30300 --jsonrpc-port 8540 --ui-port 8180 --dapps-port 8080 --jsonrpc-apis web3,eth,net,personal,parity,parity_set,traces,rpc,parity_accounts
除了打一长串的指令外,Parity也提供更为简洁的config档案设定方式,使用 --config 即可引用设定档。
node0 使用如下设定档 node0.toml
[parity]
chain = "demo-spec.json"
base_path = "/tmp/parity0"
[network]
port = 30300
[rpc]
port = 8540
apis = ["web3", "eth", "net", "personal", "parity", "parity_set", "traces", "rpc", "parity_accounts"]
[ui]
port = 8180
[dapps]
port = 8080
node1 使用如下设定档 node1.toml
[parity]
chain = "demo-spec.json"
base_path = "/tmp/parity1"
[network]
port = 30301
[rpc]
port = 8541
apis = ["web3", "eth", "net", "personal", "parity", "parity_set", "traces", "rpc", "parity_accounts"]
[ui]
port = 8181
[dapps]
port = 8081
我们总共要开3个帐号:2个Authority跟1个user帐号。
接著开启网页 http://localhost:8180
我不知道怎么略过WELCOME操作,所以先跟著指示随便建立一个account,然后再删除XD
接著新增一个user account,使用Recover account from recovery phrase功能,为了示范的一致性,使用 user 当作pass phrase
新增Authority account,一样使用Recover account from recovery phrase功能,为了示范的一致性,使用 node0 当作pass phrase
最后要看到User与Node0 (Authority) account
这样就完成 node0 的帐号设定
这样就完成 node1 的帐号设定
"validators" : {
"list": [
"0x00Bd138aBD70e2F00903268F3Db08f2D25677C9e",
"0x00Aa39d30F0D20FF03a22cCfc30B7EfbFca597C2"
]
}
再将user account加入accounts,并给一些balance,后续可以使用
"0x004ec07d2329997267Ec62b4166639513386F32E": { "balance": "10000000000000000000000" }
完成后的demo-spec.json如下
{
"name": "DemoPoA",
"engine": {
"authorityRound": {
"params": {
"gasLimitBoundDivisor": "0x400",
"stepDuration": "5",
"validators" : {
"list": [
"0x00Bd138aBD70e2F00903268F3Db08f2D25677C9e",
"0x00Aa39d30F0D20FF03a22cCfc30B7EfbFca597C2"
]
}
}
}
},
"params": {
"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 } } } },
"0x004ec07d2329997267Ec62b4166639513386F32E": { "balance": "10000000000000000000000" }
}
}
为了启动Authority node来产生区块,我们必须设定负责产生block的signer,分别是 node0 与 node1 account
node0
node1
[parity]
chain = "demo-spec.json"
base_path = "/tmp/parity0"
[network]
port = 30300
[rpc]
port = 8540
apis = ["web3", "eth", "net", "personal", "parity", "parity_set", "traces", "rpc", "parity_accounts"]
[ui]
port = 8180
[dapps]
port = 8080
[account]
password = ["node.pwds"]
[mining]
engine_signer = "0x00Bd138aBD70e2F00903268F3Db08f2D25677C9e"
reseal_on_txs = "none"
[parity]
chain = "demo-spec.json"
base_path = "/tmp/parity1"
[network]
port = 30301
[rpc]
port = 8541
apis = ["web3", "eth", "net", "personal", "parity", "parity_set", "traces", "rpc", "parity_accounts"]
[ui]
port = 8181
[dapps]
port = 8081
[account]
password = ["node.pwds"]
[mining]
engine_signer = "0x00Aa39d30F0D20FF03a22cCfc30B7EfbFca597C2"
reseal_on_txs = "none"
parity --config node0.toml
parity --config node1.toml
使用Postman透过JSON RPC来测试
{
"jsonrpc":"2.0",
"method":"parity_enode",
"params":[],
"id":0
}
{
"jsonrpc":"2.0",
"method":"parity_addReservedPeer",
"params":["enode://6c4f53fc8536553c8f151516b7ee17f4b0719d21abe8fdd273588419cf467e3deafb414cd8efa331e4ad55fd7c2820a303a160895129e142a4306e7c3367d67c@172.20.160.80:30300"],
"id":0
}
你的IP地址会不一样,172.20.160.80
最后到 node1 的console画面,会看到 0/1/25 peers,就表示已经连接上。
通过Parity提供的web-based UI可以很容易发送transaction,这边就不赘述了。
在开发时通常会将node跑在server上,让其他人可以透过JSON RPC port连接上去使用,此时只要在config里面加入 [interface] 设定即可。
假设server ip为192.168.1.1,将 node0.toml 修改如下:
[parity]
chain = "demo-spec.json"
base_path = "/tmp/parity0"
[network]
port = 30300
[rpc]
port = 8540
apis = ["web3", "eth", "net", "personal", "parity", "parity_set", "traces", "rpc", "parity_accounts"]
interface = "192.168.1.1"
[ui]
port = 8180
[dapps]
port = 8080
[account]
password = ["node.pwds"]
[mining]
engine_signer = "0x00Bd138aBD70e2F00903268F3Db08f2D25677C9e"
reseal_on_txs = "none"
同样 node1.toml 修改如下:
[parity]
chain = "demo-spec.json"
base_path = "/tmp/parity1"
[network]
port = 30301
[rpc]
port = 8541
apis = ["web3", "eth", "net", "personal", "parity", "parity_set", "traces", "rpc", "parity_accounts"]
interface = "192.168.1.1"
[ui]
port = 8181
[dapps]
port = 8081
[account]
password = ["node.pwds"]
[mining]
engine_signer = "0x00Aa39d30F0D20FF03a22cCfc30B7EfbFca597C2"
reseal_on_txs = "none"