Substrate 区块链网络的简单使用
这个是完全按照 Substrate 的官方文档 Build A Blockchain 来走的。如果你英语还行,就直接去看原文吧,说不定还能跟上更新。
打开你的命令行,咱们开整!
你都看这篇文章了,我就假设前置需求你都完成了
克隆两个git仓库
找一个合适的目录,克隆两个项目。
第一个是
git clone https://github.com/substrate-developer-hub/substrate-node-template
这个是 Substrate 区块链的节点模板,是一个rust项目,我们的工作都是基于它的。
第二个是
git clone https://github.com/substrate-developer-hub/substrate-front-end-template
这个是一个前端项目,体验的时候用的。如果你不像体验,那后续提到跟这个项目相关的操作都可以跳过。
本地启动节点
进入rust项目的目录
cd substrate-node-template
进行打包(一定要用release模式)
cargo build --release
这个可能会受到网络因素影响,建议爬到梯子上。
顺利的话,10分钟左右打包完毕。
然后到target/release
下面执行
./node-template --dev
--dev
的目的是每次停掉节点,数据会被还原,不会被持久化。
启动后的输出应该差不多这样
启动前端项目
前端项目是一个react项目,需要用到nodejs和yarn。
安装nodeJs
从 https://nodejs.org/en 下载nodeJs安装包进行安装。安装后在命令行执行
nvm install 22
这一步对网络要求很高,期间可能遇到各种问题,请自行AI解决。安装好以后通过
node --version
查看node版本。
安装yarn
在命令行执行
corepack enable
即可。使用yarn --version
看版本。
启动项目
到前端项目目录
cd substrate-front-end-template
先后执行
yarn install
yarn start
这样会打开一个浏览器页面,跟我们上面启动的rust项目通信并更新网友数据。
你想体验就转个帐吧,在 Transfer 板块找到一个目标账户,输入金额试一下。
我估计第一次体验你会失败,因为转账金额有限制:系统里都是津巴布韦富豪,所以转账金额最少要1000000000000个单位。
现在把两个项目都停掉吧。
出块和确认
我们继续尝试在区块链网络中节点的出块和确认块。
上面在启动体验项目时,系统自动创建了几个账户。我们先用其中的两个体验账户看一下:alice 和 bob。
启动Alice的节点
先把之前的数据清理掉,一定要记得:
./node-template purge-chain --base-path /tmp/alice --chain local -y
然后执行
./node-template \
--base-path /tmp/alice \
--chain local \
--alice \
--port 30333 \
--rpc-port 9945 \
--node-key 0000000000000000000000000000000000000000000000000000000000000001 \
--telemetry-url "wss://telemetry.polkadot.io/submit/ 0" \
--validator
可以看到它的peer是0(图中红框)
启动Bob节点
新开一个命令行,还是切到相同的目录,执行
./node-template purge-chain --base-path /tmp/bob --chain local -y
./node-template \
--base-path /tmp/bob \
--chain local \
--bob \
--port 30334 \
--rpc-port 9946 \
--telemetry-url "wss://telemetry.polkadot.io/submit/ 0" \
--validator \
--bootnodes /ip4/127.0.0.1/tcp/30333/p2p/12D3KooWEyoppNCUx8Yx66oV9fJnriXwCcXwDDUA2kj6vnc6iDEp
注意最下面的地址指向的是Alice节点的IP、端口和ID(上面图中用箭头指的地方)。
启动后你会发现两个节点都会有1个peer了。并且随着时间流逝,出块数量best
快速增加,被确认过的块的数量finalized
紧随其后,落后两个块。
节点的重启
虽然bob是将alice当初了boot node,但是启动后他俩是对等的。
这时候你随便停掉一个,另一个都不受影响,只是peers变成0,区块数不再变化。
重新启动这个停掉的,两个又恢复如初。
我想强调的是你重启Alice不会影响Bob,毕竟你已经知道Bob没启动时也没影响Alice。
加入自定义节点
重点来了:现在我们要定义自己的点对点网络节点。
预定义的那几个账户是怎么来的我们不知道还,所以这里我们自己生成两个节点。
Substrate 中的账户需要两个关键密钥,一个是用来出块(挖矿)的,叫auro
; 一个是用来确认块的,叫grandpa
。我们来生成这两个公钥。
生成公钥
还是在rust项目中执行
./node-template key generate --scheme Sr25519 --password-interactive
这时候需要输入一个私钥,你自己记住就行。然后会生成类似这样的
Secret phrase: pig giraffe ceiling enter weird liar orange decline behind total despair fly
Secret seed: 0x0087016ebbdcf03d1b7b2ad9a958e14a43f2351cd42f2f0a973771b90fb0112f
Public key (hex): 0x1a4cc824f6585859851f818e71ac63cf6fdc81018189809814677b2a4699cf45
Account ID: 0x1a4cc824f6585859851f818e71ac63cf6fdc81018189809814677b2a4699cf45
Public key (SS58): 5CfBuoHDvZ4fd8jkLQicNL8tgjnK8pVG9AiuJrsNrRAx6CNW
SS58 Address: 5CfBuoHDvZ4fd8jkLQicNL8tgjnK8pVG9AiuJrsNrRAx6CNW
这里面最关键的是第一个和最后一个字段。
第一个字段?那一串单词?……
没错就他
接下来用第一个字段secret phase
来生成第二个公钥
./node-template key inspect --password-interactive --scheme Ed25519 "pig giraffe ceiling enter weird liar orange decline behind total despair fly"
千万记得换成你自己的phase
Secret phrase `pig giraffe ceiling enter weird liar orange decline behind total despair fly` is account:
Secret seed: 0x0087016ebbdcf03d1b7b2ad9a958e14a43f2351cd42f2f0a973771b90fb0112f
Public key (hex): 0x2577ba03f47cdbea161851d737e41200e471cd7a31a5c88242a527837efc1e7b
Public key (SS58): 5CuqCGfwqhjGzSqz5mnq36tMe651mU9Ji8xQ4JRuUTvPcjVN
Account ID: 0x2577ba03f47cdbea161851d737e41200e471cd7a31a5c88242a527837efc1e7b
SS58 Address: 5CuqCGfwqhjGzSqz5mnq36tMe651mU9Ji8xQ4JRuUTvPcjVN
最后一行就是第二个公钥。
然后重复一遍,用同样的方法再生成一组公钥给第二个账户。
假设生成好了以后,第二个账户的两个公钥是
auro: 111111111111111111111111111111111
grandpa: 22222222222222222222222222222222222
修改链的规格
准备好了多个账户以后,由于都是可信节点,需要把他们加入到链规格定义中。
首先到处之前的链规格:
./node-template build-spec --disable-default-bootnode --chain local > my.json
这会在当前目录生成一个文件my.json
。打开它然后定位关键字“auro”,把里面的账户改成前面的两个auro公钥:
"aura": { "authorities": [
"5CfBuoHDvZ4fd8jkLQicNL8tgjnK8pVG9AiuJrsNrRAx6CNW",
"111111111111111111111111111111111"
]
},
定位到关键字“grandpa”,同样修改成第二个公钥:
"grandpa": {
"authorities": [
[
"5CuqCGfwqhjGzSqz5mnq36tMe651mU9Ji8xQ4JRuUTvPcjVN",
1
],
[
"22222222222222222222222222222222222",
1
]
]
},
保存后执行
./node-template build-spec --chain=my.json --raw --disable-default-bootnode > myRaw.json
这样我们的自定义规格myRaw.json
就生成好了。
这个文件发给其他可信节点,大家就可以组建私链了
启动节点
启动第一个节点
./node-template \
--base-path /tmp/node01 \
--chain ./myRaw.json \
--port 30333 \
--rpc-port 9945 \
--telemetry-url "wss://telemetry.polkadot.io/submit/ 0" \
--validator \
--rpc-methods Unsafe \
--name MyNode01 \
--password-interactive
这样会在tmp/node01
下面生成数据,但是并不是出块。
要想出块需要把公钥存进keystore。
把公钥存进keystore
使用前面的secret phase
把公钥存进去
./node-template key insert --base-path /tmp/node01 \
--chain myRaw.json \
--scheme Sr25519 \
--suri "pig giraffe ceiling enter weird liar orange decline behind total despair fly" \
--password-interactive \
--key-type aura
输入生成公钥的私钥即可。继续
./node-template key insert \
--base-path /tmp/node01 \
--chain myRaw.json \
--scheme Ed25519 \
--suri "pig giraffe ceiling enter weird liar orange decline behind total despair fly" \
--password-interactive \
--key-type gran
同样输入私钥。这样两个公钥都存好了。
重启节点
存好后重启节点令其生效。
加入节点
第二个节点也要把auro和grandpa存到keystore中。然后启动:
./node-template \
--base-path /tmp/node02 \
--chain ./myRaw.json \
--port 30334 \
--rpc-port 9946 \
--telemetry-url "wss://telemetry.polkadot.io/submit/ 0" \
--validator \
--rpc-methods Unsafe \
--name MyNode02 \
--bootnodes /ip4/127.0.0.1/tcp/30333/p2p/12D3KooWLmrYDLoNTyTYtRdDyZLWDe1paxzxTw5RgjmHLfzW96SX \
--password-interactive
输入自己的私钥即可。