这篇文档,是记录自己搭建以太坊私链的过程。
安装
以太坊搭建私链的安装方式有很多,其中之一就是源码安装。
源码安装
下载go-ethereum
源码,编译:
git clone https://github.com/ethereum/go-ethereum.git
在目录下,编译:
make geth
显示:
env GO111MODULE=on go run build/ci.go install ./cmd/geth
......
......
github.com/ethereum/go-ethereum/cmd/geth
Done building.
Run "./build/bin/geth" to launch geth.
编译后的文件,在./build/bin/geth
下,会产生geth
二进制文件。
之后,配置环境变量:
export PATH=$PATH:/root/eth/go-ethereum/build/bin
即可在任意地方使用。
官网下载
在官网上,直接下载编译好的二进制文件:
初始化
在开始搭建私链之前,需要配置一个创世文件:genesis.json
,一般的配置如下所示:
{
"config": {
"chainId": 10,
"homesteadBlock": 0,
"eip150Block": 0,
"eip150Hash": "0x0000000000000000000000000000000000000000000000000000000000000000",
"eip155Block": 0,
"eip158Block": 0,
"byzantiumBlock": 0,
"constantinopleBlock": 0,
"petersburgBlock": 0,
"istanbulBlock": 0,
"ethash": {}
},
"nonce": "0x0",
"timestamp": "0x5ddf8f3e",
"extraData": "0x0000000000000000000000000000000000000000000000000000000000000000",
"gasLimit": "0x47b760",
"difficulty": "0x00200",
"mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
"coinbase": "0x0000000000000000000000000000000000000000",
"alloc": { },
"number": "0x0",
"gasUsed": "0x0",
"parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000"
}
配置好后,创建一个空的文件夹,比如datachain
,之后,一个节点的产生的数据都存储在这个目录文件下。
创建好后,开启初始化节点,运行命令:
geth --datadir ./datachain init genesis.json
# --datadir 指定数据存储的文件夹
# init 创世配置文件
显示日志:
root@cchui-virtual-machine:~/eth# geth --datadir ./datachain init genesis.json
INFO [07-26|20:32:06.444] Maximum peer count ETH=50 LES=0 total=50
INFO [07-26|20:32:06.444] Smartcard socket not found, disabling err="stat /run/pcscd/pcscd.comm: no such file or directory"
INFO [07-26|20:32:06.445] Set global gas cap cap=50,000,000
INFO [07-26|20:32:06.445] Allocated cache and file handles database=/root/eth/datachain/geth/chaindata cache=16.00MiB handles=16
INFO [07-26|20:32:06.449] Writing custom genesis block
INFO [07-26|20:32:06.449] Persisted trie from memory database nodes=0 size=0.00B time="8.341µs" gcnodes=0 gcsize=0.00B gctime=0s livenodes=1 livesize=0.00B
INFO [07-26|20:32:06.451] Successfully wrote genesis state database=chaindata hash=d3d6bb..c5304a
INFO [07-26|20:32:06.451] Allocated cache and file handles database=/root/eth/datachain/geth/lightchaindata cache=16.00MiB handles=16
INFO [07-26|20:32:06.454] Writing custom genesis block
INFO [07-26|20:32:06.454] Persisted trie from memory database nodes=0 size=0.00B time="1.497µs" gcnodes=0 gcsize=0.00B gctime=0s livenodes=1 livesize=0.00B
INFO [07-26|20:32:06.456] Successfully wrote genesis state database=lightchaindata hash=d3d6bb..c5304a
即,表示成功初始以太坊网络。
启动以太坊私链
启动
开启一个Geth
节点,输入下面的命令:
geth --identity "test Chain" --datadir ./datachain --rpc --rpcport 8547 --ws --ws.port=8546 --http.port=8548 --rpccorsdomain "*" --port 1718 --nodiscover --nat "any" --networkid 1108 --rpcapi "eth,net,web3,personal" console
# --datadir 后面跟的是你指定的工作目录
# --identity 后面跟的是你的区块链标识,随便写
# --networkid 后面跟的是你的网络id,这个是区别区块链网络的关键
# --port 和 --rpcport 你随便给一个就行,别跟在用的端口重复就行
# --nodiscover 不去发现节点
# 2>output.log 输出到这个日志里面
# --rpc --rpcport=8547 :开启RPC连接方式,并设置端口为8547
# --ws --wsport=8546 :开启WebSocket连接方式,并设置端口为8546
# --http.port=8548 : http连接,端口为8548
# --rpccorsdomain="*" :RPC允许所有跨域连接,这个设置主要是为了Remix在线连接本地开发网络
# console :Geth启动后仍可接收命令行命令,如不开启又需要使用命令行也可以通过geth attach ipc:\\.\pipe\geth.ipc方式连接到当前节点
# --ipcpath ./datachain/geth.ipc
# --rpcapi "eth,admin,web3,net,personal" 不加的话,很多rpc api是无法使用的
启动节点后,即可进入节点控制台,和节点进行交互。
创建账户
> eth.accounts
["0x471144a5fec2d48450d6e14438a448be839dcd04"]
> personal.newAccount()
Passphrase:
Repeat passphrase:
INFO [07-26|20:46:17.128] Your new key was generated address=0x487366D8E76b5aD71dfA047997681F8A3AD8B75B
WARN [07-26|20:46:17.128] Please backup your key file! path=/root/eth/datachain/keystore/UTC--2021-07-26T12-46-15.974003905Z--487366d8e76b5ad71dfa047997681f8a3ad8b75b
WARN [07-26|20:46:17.128] Please remember your password!
"0x487366d8e76b5ad71dfa047997681f8a3ad8b75b"
> eth.accounts
["0x471144a5fec2d48450d6e14438a448be839dcd04", "0x487366d8e76b5ad71dfa047997681f8a3ad8b75b"]
账户余额
> eth.getBalance(eth.accounts[0])
0
挖矿
注意,在节点第一次挖矿的时候,时间会比较长。需要进行DAG的初始化,等到DAG 进程加载到 100 时,才会开始挖矿。
> miner.start(1) ## 开启一个线程进行挖矿
INFO [07-26|20:49:45.475] Generating DAG in progress epoch=0 percentage=95 elapsed=1m13.544s
INFO [07-26|20:49:46.189] Generating DAG in progress epoch=0 percentage=96 elapsed=1m14.258s
INFO [07-26|20:49:46.901] Generating DAG in progress epoch=0 percentage=97 elapsed=1m14.969s
INFO [07-26|20:49:47.607] Generating DAG in progress epoch=0 percentage=98 elapsed=1m15.676s
INFO [07-26|20:49:48.368] Generating DAG in progress epoch=0 percentage=99 elapsed=1m16.437s
INFO [07-26|20:49:48.369] Generated ethash verification cache epoch=0 elapsed=1m16.438s
INFO [07-26|20:49:48.581] Successfully sealed new block number=1 sealhash=cfc590..c87647 hash=30c2a3..4ca68a elapsed=1m17.119s
INFO [07-26|20:49:48.581] 🔨 mined potential block number=1 hash=30c2a3..4ca68a
INFO [07-26|20:49:48.581] Commit new mining work number=2 sealhash=f57a2e..1f5426 uncles=0 txs=0 gas=0 fees=0 elapsed="137.234µs"
> miner.stop() ## 停止挖矿
多节点组网
区块链是一种P2P
的网络模型,一个节点是怪怪的。需要创建多个节点,在多节点间组网,形成区块链网络。
新节点创建需要注意:
- 新节点的
networkid
要保持一致,这里我用的是10
- 新节点使用同一个创世区块
- 如果是在同一个机器上创建多个节点,注意端口号区分
创建命令为:
节点0:
geth --identity "test Chain 0" --datadir ./chain0 --rpc --rpcport 30300 --http.port=8545 --rpccorsdomain "*" --port 20200 --nodiscover --nat "any" --networkid 10 --rpcapi "eth,net,web3,personal" console --allow-insecure-unlock
节点1:
geth --identity "test Chain 1" --datadir ./chain1 --rpc --rpcport 30301 --http.port=8546 --rpccorsdomain "*" --port 20201 --nodiscover --nat "any" --networkid 10 --rpcapi "eth,net,web3,personal" console --allow-insecure-unlock
节点2:
geth --identity "test Chain 2" --datadir ./chain2 --rpc --rpcport 30302 --http.port=8547 --rpccorsdomain "*" --port 20202 --nodiscover --nat "any" --networkid 10 --rpcapi "eth,net,web3,personal" console --allow-insecure-unlock
节点3:
geth --identity "test Chain 3" --datadir ./chain3 --rpc --rpcport 30303 --http.port=8548 --rpccorsdomain "*" --port 20203 --nodiscover --nat "any" --networkid 10 --rpcapi "eth,net,web3,personal" console --allow-insecure-unlock
创建目录,并初始化:
# 创建目录
mkdir chain0
# 初始化
geth --datadir ./chain0 init genesis.json
# 启动控制台
geth --identity "test Chain 0" --datadir ./chain0 --rpc --rpcport 30300 --http.port=8545 --rpccorsdomain "*" --port 20200 --nodiscover --nat "any" --networkid 10 --rpcapi "eth,net,web3,personal" console --allow-insecure-unlock
# 获得节点信息
> admin.nodeInfo.enode
"enode://b8942102a9bfe69a4538f157203ae7879080bb4e5faf8372afbbc0723bc59c36aa2d382c84231737baa08090f82a9d76b834a00a37b43b8e62fbfd1b3e7665a5@127.0.0.1:20200?discport=0"
以此方法,获得其他的节点信息:
"enode://b8942102a9bfe69a4538f157203ae7879080bb4e5faf8372afbbc0723bc59c36aa2d382c84231737baa08090f82a9d76b834a00a37b43b8e62fbfd1b3e7665a5@127.0.0.1:20200?discport=0"
"enode://51f09e76b78527391e3c54322da99d85fa8cbb659b1d107209f71efeab8bb787f167ea1008ff79409c9fc9fec6801e0b4bc586467364aadc05137ead561811bb@127.0.0.1:20201?discport=0"
"enode://81dad6116ff3b52741d99b9072b5d2b4d9b73f18eeb4a8981ae9c11a8f405ebdf23893c569600d64fb05e5a80fad9d678e2607230c4a01dd8a9e88bf867d78bc@127.0.0.1:20202?discport=0"
方法一
使用admin.addPeer
> admin.addPeer("enode://51f09e76b78527391e3c54322da99d85fa8cbb659b1d107209f71efeab8bb787f167ea1008ff79409c9fc9fec6801e0b4bc586467364aadc05137ead561811bb@127.0.0.1:20201?discport=0")
true
> INFO [07-31|10:31:15.588] Looking for peers peercount=0 tried=0 static=1
## 查看连接的节点:
> admin.peers
[{
caps: ["eth/65", "eth/66", "snap/1"],
enode: "enode://51f09e76b78527391e3c54322da99d85fa8cbb659b1d107209f71efeab8bb787f167ea1008ff79409c9fc9fec6801e0b4bc586467364aadc05137ead561811bb@127.0.0.1:20201?discport=0",
id: "0a5d6d6320b6cbe0b9961ddf5b50d576ee35be73d06f4387a53f395302bf204b",
name: "Geth/test Chain 1/v1.10.7-unstable-a1f16bc7-20210722/linux-amd64/go1.15.7",
network: {
inbound: false,
localAddress: "127.0.0.1:57992",
remoteAddress: "127.0.0.1:20201",
static: true,
trusted: false
},
protocols: {
eth: {
difficulty: 2048,
head: "0x46ccd2afd2b1571d47d6acd761323919d6232912225071a3451cd96166600d1d",
version: 66
},
snap: {
version: 1
}
}
}]
注意:节点0再添加节点2,如果只在节点0上添加节点2的信息,那么节点1上是不能发现节点2的。
只有节点1也添加了节点2的信息,三个节点才正式组网
节点退出后,使用admin.peers
查看,会发现节点信息也会相应的减少了。
全部节点停机后,再登陆进去,会发现没有连接信息了。需要重新添加一遍。
方法二
使用static-nodes.json
文件,在文件里写上各个节点信息。
将文件放在节点data
目录下的所在路径,即启动时–datadir
后的路径
[
"enode://b8942102a9bfe69a4538f157203ae7879080bb4e5faf8372afbbc0723bc59c36aa2d382c84231737baa08090f82a9d76b834a00a37b43b8e62fbfd1b3e7665a5@127.0.0.1:20200?discport=0",
"enode://51f09e76b78527391e3c54322da99d85fa8cbb659b1d107209f71efeab8bb787f167ea1008ff79409c9fc9fec6801e0b4bc586467364aadc05137ead561811bb@127.0.0.1:20201?discport=0",
"enode://81dad6116ff3b52741d99b9072b5d2b4d9b73f18eeb4a8981ae9c11a8f405ebdf23893c569600d64fb05e5a80fad9d678e2607230c4a01dd8a9e88bf867d78bc@127.0.0.1:20202?discport=0"
]
开启节点后,一段时间后,会有:
> INFO [08-03|14:39:25.561] Looking for peers peercount=2 tried=2 static=3
查看:
> admin.peers
[{
caps: ["eth/65", "eth/66", "snap/1"],
enode: "enode://51f09e76b78527391e3c54322da99d85fa8cbb659b1d107209f71efeab8bb787f167ea1008ff79409c9fc9fec6801e0b4bc586467364aadc05137ead561811bb@127.0.0.1:51882",
id: "0a5d6d6320b6cbe0b9961ddf5b50d576ee35be73d06f4387a53f395302bf204b",
name: "Geth/test Chain 1/v1.10.7-unstable-a1f16bc7-20210722/linux-amd64/go1.15.7",
network: {
inbound: true,
localAddress: "127.0.0.1:20200",
remoteAddress: "127.0.0.1:51882",
static: false,
trusted: false
},
protocols: {
eth: {
difficulty: 2048,
head: "0x46ccd2afd2b1571d47d6acd761323919d6232912225071a3451cd96166600d1d",
version: 66
},
snap: {
version: 1
}
}
}, {
caps: ["eth/65", "eth/66", "snap/1"],
enode: "enode://81dad6116ff3b52741d99b9072b5d2b4d9b73f18eeb4a8981ae9c11a8f405ebdf23893c569600d64fb05e5a80fad9d678e2607230c4a01dd8a9e88bf867d78bc@127.0.0.1:51886",
id: "20a2bf08b6a9a5dfbf1318567c388ad070471f23ef0c068162b369f4e84a909c",
name: "Geth/test Chain 2/v1.10.7-unstable-a1f16bc7-20210722/linux-amd64/go1.15.7",
network: {
inbound: true,
localAddress: "127.0.0.1:20200",
remoteAddress: "127.0.0.1:51886",
static: false,
trusted: false
},
protocols: {
eth: {
difficulty: 2048,
head: "0x46ccd2afd2b1571d47d6acd761323919d6232912225071a3451cd96166600d1d",
version: 66
},
snap: {
version: 1
}
}
}]
帮助
root@cchui-virtual-machine:~/eth# geth -h
总结
本文主要简述了如何搭建以太坊私有链,并通过两个简便的方法搭建多节点集群。