0%

DevRecord-BNBSmartChain私有链初步搭建

Pre:

预期效果:在本地私有网络搭建起Bsc全节点,并且验证者节点在白名单内,可以正常打包出块,用户之间可以正常转账。

依赖环境:

1
2
# 安装基础工具
yum update -y && yum install git bzip2 gcc-c++ ntp epel-release nodejs -y

安装go:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
# Centos7安装方法

# 下载文件,国内
wget https://golang.google.cn/dl/go1.19.linux-amd64.tar.gz
# 解压
tar -zxf go1.19.linux-amd64.tar.gz -C /usr/local
# 配置环境变量
vim /etc/profile
# 末尾添加以下配置

#golang env config
export GO111MODULE=on
export GOROOT=/usr/local/go
export GOPATH=/home/gopath
export PATH=$PATH:$GOROOT/bin:$GOPATH/bin

# 切换到/home目录
cd /home
# 创建gopath文件夹,后面开发和编译过程中用go get安装第三方包会用到
mkdir gopath

# 使变量配置生效
source /etc/profile
# 并查看golang的版本
go version

# GO设置代理环境变量,再拉去golang.org的时候就不需要墙了。
go env -w GOPROXY=https://goproxy.cn,direct

geth安装

1
2
# 把智能链 [BNB Smart Chain](https://github.com/bnb-chain/bsc)的代码`git clone`下来 
git clone https://github.com/bnb-chain/bsc.git
1
2
3
# git设置代理
git config --global http.proxy http://192.168.2.135:7890
git config --global https.proxy http://192.168.2.135:7890
1
2
# 进入bsc项目文件夹,进行源码构建
make all
1
2
3
4
# 进入geth所在目录
/Users/chanjerry/Documents/GitHub/blockchain/bsc-node/bsc/build/bin
# 看看geth能否正常运行
./geth --help

至此,geth客户端就能够正常使用了

创建创世区块的json配置文件:

Bsc主网的json配置文件:

先参考一下bsc主网的json配置文件

1
2
3
4
5
6
# 下载主网配置压缩包
wget $(curl -s https://api.github.com/repos/bnb-chain/bsc/releases/latest |grep browser_ |grep mainnet |cut -d\" -f4)
# 解压
unzip mainnet.zip
# 打开genesis.json
vim genesis.json

genesis.json文件用于配置生成以太坊私链网络的创世区块,当我们需要去创建一个创世区块时,我们可以通过修改genesis.json文件内的初始参数将这些数据写入创世区块。
20220804102657

参考以太坊私链搭建(二)——genesis.json字段解读

alloc: 预定义的钱包列表,可以通过该字段预先在指定钱包地址内预存一定数量得原生代币。这是以太坊预售期间所执行得特定功能。

bsc主网在创世区块里会创建一系列的系统合约。
参考:

系统合约列表:

  • 0xffffFFFfFFffffffffffffffFfFFFfffFFFfFFfE

  • 0x0000000000000000000000000000000000001000 BSCValidatorSet 管理验证者节点地址列表(查询or更新),处理来自信标链的数据包

  • 0x0000000000000000000000000000000000001001 SlashIndicator

  • 0x0000000000000000000000000000000000001002 SystemReward 中继者维护系统合约的激励机制。他们将从系统奖励合约中获得奖励

  • 0x0000000000000000000000000000000000001003 TendermintLightClient

  • 0x0000000000000000000000000000000000001004 TokenHub 跨链代币转移

  • 0x0000000000000000000000000000000000001005 RelayerIncentivize

  • 0x0000000000000000000000000000000000001006 RelayerHub 管理 bsc-relayer 的权限。想要运行 bsc-relayer 的人必须调用合约来存入一些 BNB 以获得授权。

  • 0x0000000000000000000000000000000000001007 GovHub 治理合约,处理来自 BC 的治理包

  • 0x0000000000000000000000000000000000001008 TokenManager 在两条链上绑定和解除绑定代币

  • 0x0000000000000000000000000000000000002000 CrossChain 跨链包预处理,通过 emit 事件发送跨链包到 BC。包预处理包括序列验证和默克尔证明验证

  • b005741528b86F5952469d80A8614591E3c5B632 初始地址1 余额500000000000000000000Wei/500Ether

  • 446AA6E0DC65690403dF3F127750da1322941F3e 初始地址2 余额500Ether

自定义创世区块的json配置文件:

参考创始区块的系统合约github的readme文件。

how to generate genesis file.

  1. Edit init_holders.js file to alloc the initial BNB holder. 初始 BNB 持有者

  2. Edit validators.js file to alloc the initial validator set. 初始化验证者列表

  3. Edit generate-validatorset.js file to change fromChainId and toChainId,

  4. Edit generate-tokenhub.js file to change refundRelayReward, minimumRelayFee and maxGasForCallingBEP20.

  5. Edit generate-tendermintlightclient.js file to change chainID and initConsensusStateBytes.

  6. run node generate-genesis.js will generate genesis.json

solc替代solcjs:

参考:Solc “bin-runtime” not a command?
generate-genesis.js里面做的主要工作是 使用solc编译合约,正则匹配提取solc编译合约后的Binary of the runtime part,应该是用户实际交易调用这个新合约时需要执行的字节码(即运行时字节码)

初次运行node generate-genesis.js命令时会报错,把输出报错的代码的注释去掉

1
2
3
ls.stderr.on("data", data => {
console.log(`stderr: ${data}`) // 去掉注释
})

报错会提示你的solc没有bin-runtime这个参数命令,
npm装的是solcjs,需要自己重装一个solc。参考:Ubuntu20.04+solc+solc-select安装/使用记录
选择装solc-selectsolc-select是一个基于python的轻量化solc版本管理工具。

安装方法如下:

1
2
3
4
pip install solc-select
# 将py第三方包的可执行文件加入到环境变量中
vim /etc/profile
export PATH=/usr/local/python3/bin:$PATH

使用方法如下:

1
2
3
4
5
# 安装所有可用版本的solc,也可以指定版本
solc-select install 0.6.4
solc-select install [版本号]
# 切换环境变量中的solc版本
solc-select use [版本号]

solc重装以后,主要先修改这两个文件

  1. Edit init_holders.js file to alloc the initial BNB holder. 初始 BNB 持有者

  2. Edit validators.js file to alloc the initial validator set. 初始化验证者列表

init_holders.js可不改,修改validators.js的地址为我们自己的钱包地址(矿工钱包),这样我们的地址就在初始化验证者列表里面,可以通过验证,挖矿打包出块了。
运行命令node generate-genesis.js,生成我们自定义的创始区块配置文件genesis.json
如果不在初始化验证者列表里加入我们的矿工钱包地址,会出现报错信息:unauthorized validator无效的验证者,无法正常打包出块。

1
2
3
4
5
6
7
8
> miner.start(1)
INFO [08-03|15:46:30.837] Transaction pool price threshold updated price=1,000,000,000
null
> INFO [08-03|15:46:30.839] Stored checkpoint snapshot to disk number=0 hash=66f7da..3b9e65
ERROR[08-03|15:46:30.840] init contract failed
ERROR[08-03|15:46:30.840] slash validator failed block hash=f7d1f8..3b0582 address=0x9fB29AAc15b9A4B7F17c3385939b007540f4d791
INFO [08-03|15:46:30.840] Commit new mining work number=1 sealhash=b8fc50..fefd87 uncles=0 txs=0 gas=0 elapsed=2.135ms
WARN [08-03|15:46:30.840] Block sealing failed err="unauthorized validator"

运行节点:

参考文档本地 BNB 智能链网络

创建节点文件夹:

创建两个空文件夹来放节点的数据

1
2
/Users/chanjerry/Documents/GitHub/blockchain/bsc-node/private_network/node1
/Users/chanjerry/Documents/GitHub/blockchain/bsc-node/private_network/node2

初始化以太坊节点:

通过创始区块json配置文件,来初始化以太坊节点

1
./geth --datadir /Users/chanjerry/Documents/GitHub/blockchain/bsc-node/private_network/node1 init /Users/chanjerry/Documents/GitHub/blockchain/bsc-node/private_network/genesis.json

启动以太坊节点:

1
./geth --datadir /Users/chanjerry/Documents/GitHub/blockchain/bsc-node/private_network/node1 --networkid 714 console

初始化另一个以太坊节点:

1
./geth --datadir /Users/chanjerry/Documents/GitHub/blockchain/bsc-node/private_network/node2 init /Users/chanjerry/Documents/GitHub/blockchain/bsc-node/private_network/genesis.json

启动第二个以太坊节点:

1
./geth --datadir /Users/chanjerry/Documents/GitHub/blockchain/bsc-node/private_network/node2 --port 30304 --nodiscover --networkid 714 console

导入钱包地址:

通过私钥导入两个钱包地址:1.初始持币者钱包 2.矿工钱包

1
2
# 在geth console里,通过私钥导入钱包
web3.personal.importRawKey("私钥", "123456(密码)")

导入成功,可查看已有账户:

1
2
3
> eth.accounts

["0x67970d4988a31fbc379add2be5c529bf015bb032", "0xabe904f6a2661f36c8abd3c5dbaeff2c8214cac7", "0x9fb29aac15b9a4b7f17c3385939b007540f4d791"]

开始挖矿:

1
./geth console --port "30304" --cache 18000 --datadir  "/Users/chanjerry/Documents/GitHub/blockchain/bsc-node/private_network/node2" --mine  --miner.threads=4  --miner.etherbase=0xABe904f6A2661F36C8ABD3c5DBAEFF2C8214cAC7 --allow-insecure-unlock --unlock 0xABe904f6A2661F36C8ABD3c5DBAEFF2C8214cAC7 --http --http.corsdomain * 

查看区块数是否增长:

1
2
3
> eth.blockNumber

5866

将一个节点连接到另一个节点:

1
2
# 在一个 geth 控制台中:
admin.nodeInfo.enode
1
2
# 在另一个控制台中:
admin.addPeer( <the enode value from the first console> )

这一步我没连接好,后面只用到了第二个节点就能正常打包出块,用户间能正常转账。

用户间转账:

geth里转账:

1
2
# geth console里运行转账命令
eth.sendTransaction({from: "0x9fb29aac15b9a4b7f17c3385939b007540f4d791", to: "0xABe904f6A2661F36C8ABD3c5DBAEFF2C8214cAC7", value: web3.toWei(10, "ether")})

输出信息:

1
2
INFO [08-03|16:45:43.009] Submitted transaction                    hash=0xab6a5a39a3381048f58fd53fec3b757fbdb62d9a256e548266b7cf2253021fb0 from=0x9fB29AAc15b9A4B7F17c3385939b007540f4d791 nonce=2 recipient=0xABe904f6A2661F36C8ABD3c5DBAEFF2C8214cAC7 value=10,000,000,000,000,000,000
"0xab6a5a39a3381048f58fd53fec3b757fbdb62d9a256e548266b7cf2253021fb0"

查看tx信息:

1
eth.getTransaction('0xab6a5a39a3381048f58fd53fec3b757fbdb62d9a256e548266b7cf2253021fb0')
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
{
blockHash: "0x5c93aa965f19bdd1840a11832a82f5380d0d8354adfc2c1ae2ce39b0711d68fb",
blockNumber: 411,
from: "0x9fb29aac15b9a4b7f17c3385939b007540f4d791",
gas: 21000,
gasPrice: 1000000000,
hash: "0xab6a5a39a3381048f58fd53fec3b757fbdb62d9a256e548266b7cf2253021fb0",
input: "0x",
nonce: 2,
r: "0xdaffdbafe1a4014796af9b8f39369421b9b3480f43a8edd038b1f25bad98a1a5",
s: "0x679648136c1703aec1c43b4e29cdf1f1ea6e01453eda5581c93536386b01ec3f",
to: "0xabe904f6a2661f36c8abd3c5dbaeff2c8214cac7",
transactionIndex: 0,
type: "0x0",
v: "0x5b8",
value: 10000000000000000000
}

转账成功

metamask里转账:

或者用小狐狸钱包连接本地节点,然后进行转账:
配置好chain id信息:
20220803165545
能够转账成功:
20220803165559

矿工暂时未能获得挖矿奖励,接下来要继续探索一下

Refs: