准备阶段
本示例使用的geth-1.13.15, 1.14版本的geth已经移除了Clique,详情可参见https://github.com/ethereum/go-ethereum/releases/tag/v1.14.0
本示例参考https://geth.ethereum.org/docs/fundamentals/private-network#creating-genesis-block
搭建并启动私链
1、构建项目结构
mkdir chaindev
cd chaindev
touch genesis.json
mkdir node1 node2
2、创建genesis.json
{
"config": {
"chainId": 8888,
"homesteadBlock": 0,
"eip150Block": 0,
"eip155Block": 0,
"eip158Block": 0,
"byzantiumBlock": 0,
"constantinopleBlock": 0,
"petersburgBlock": 0,
"istanbulBlock": 0,
"berlinBlock": 0,
"clique": {
"period": 3,
"epoch": 30000
}
},
"extraData": "0x00000000000000000000000000000000000000000000000000000000000000001e7d9b53cda80b801052171622c575f5fd7e9d3d0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
"difficulty": "0x1",
"gasLimit": "0x2625A00",
"alloc": {
"1e7d9b53cda80b801052171622c575f5fd7e9d3d": {
"balance": "1000000000000000000000"
},
"28d2b259f9aee1a34d52a028abd492bfe4f4c0c3": {
"balance": "1000000000000000000000"
}
}
}
3、为每个验证者创建账户,保存好密码和私钥
geth account new --datadir node1
geth account new --datadir node2
4、输出密码到相应文件(使用上一步保存的密码)
echo "password1" > node1/password.txt
echo "password2" > node2/password.txt
5、初始化相应验证者节点
geth init --datadir node1 genesis.json
geth init --datadir node2 genesis.json
geth init --datadir node3 genesis.json
geth init --datadir node4 genesis.json
(可选)6、删除geth目录,genesis.json作出修改后需要重新执行步骤5时需要
rm -rf node1/geth
rm -rf node2/geth
7、启动节点1
geth --datadir node1 \
--networkid 8888 \
--http --http.addr "0.0.0.0" --http.port 8545 \
--http.api "eth,net,web3,personal,admin,clique" \
--port 30303 \
--allow-insecure-unlock \
--miner.gaslimit "0x2625A00" \
--rpc.enabledeprecatedpersonal \
--cache 4096 \
--unlock "0x1e7d9b53cda80b801052171622c575f5fd7e9d3d" \
--password "node1/password.txt" \
--mine \
--miner.etherbase "0x1e7d9b53cda80b801052171622c575f5fd7e9d3d"
此时,私链已经完成启动,可以对其进行测试。
接入新本地的节点
本例中的node2将作为本地新节点接入。
8、获取enode
geth attach node1/geth.ipc
> admin.nodeInfo.enode
9、启动node2(注意端口不要冲突)
geth --datadir node2 \
--networkid 8888 \
--http --http.addr "0.0.0.0" --http.port 8546 \
--http.api "eth,net,web3,personal,admin,clique" \
--port 30304 \
--allow-insecure-unlock \
--cache 4096 \
--bootnodes "<enode>" \
--unlock "0x28d2b259f9aee1a34d52a028abd492bfe4f4c0c3" \
--password "node2/password.txt" \
--ws --ws.addr "0.0.0.0" --ws.port 8552 --ws.api "eth,net,web3,personal,admin,clique" \
--authrpc.port 8554
10、重启Javascript 控制台检查网络属性
> net.peerCount
2
> admin.peers
[{
caps: ["eth/68", "snap/1"],
enode: "<enode>",
id: "8eccb6e9091a16a549de83dd9bda13ae24f6d19990e0e9b29b503c223b9993cf",
name: "Geth/v1.13.15-stable/linux-amd64/go1.22.0",
network: {
inbound: false,
localAddress: "127.0.0.1:39848",
remoteAddress: "127.0.0.1:30303",
static: false,
trusted: false
},
protocols: {
eth: {
version: 68
},
snap: {
version: 1
}
}
}]
注意,因为防火墙端口未开放30303,此示例也是再本地运行的node2,所以修改了enode的ip为127.0.0.1
11、测试交易
接入远程节点
1、geth版本(1.13.15)
https://github.com/ethereum/go-ethereum/releases/tag/v1.13.15
为防止出现错误,建议使用相同版本,注意不要使用该版本之后的版本,那将移除Clique
2、创建项目
mkdir chaindev
cd chaindev
mkdir node1
3、创建genesis.json(保持一致)
{
"config": {
"chainId": 8888,
"homesteadBlock": 0,
"eip150Block": 0,
"eip155Block": 0,
"eip158Block": 0,
"byzantiumBlock": 0,
"constantinopleBlock": 0,
"petersburgBlock": 0,
"istanbulBlock": 0,
"berlinBlock": 0,
"clique": {
"period": 3,
"epoch": 30000
}
},
"extraData": "0x00000000000000000000000000000000000000000000000000000000000000001e7d9b53cda80b801052171622c575f5fd7e9d3d0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
"difficulty": "0x1",
"gasLimit": "0x2625A00",
"alloc": {
"1e7d9b53cda80b801052171622c575f5fd7e9d3d": {
"balance": "1000000000000000000000"
},
"28d2b259f9aee1a34d52a028abd492bfe4f4c0c3": {
"balance": "1000000000000000000000"
}
}
}
4、为node1创建账户(示例密码为1234)
geth account new --datadir node1 // password: 1234
echo "1234" > node1/password.txt
5、初始化node1
geth init --datadir node1 genesis.json
6、启动节点
A、启动一个(允许出块和验证)的节点
geth --datadir node1 \
--networkid 8888 \
--http --http.addr "0.0.0.0" --http.port 8546 \
--http.api "eth,net,web3,personal,admin,clique" \
--port 30303 \
--allow-insecure-unlock \
--cache 4096 \
--bootnodes "enode://02af1096f065550865969cd47e25f062b1db8b5e04b91e63ea77584d87e59e27cd7762547e897cbb4330944ae06ff474a94746db0d09f411b5aa222ab15acab1@40.78.123.6:30303" \
--unlock "<node1_account_address>" \
--password "node1/password.txt" \
--ws --ws.addr "0.0.0.0" --ws.port 8552 --ws.api "eth,net,web3,personal,admin,clique" \
--authrpc.port 8555 \
--mine \
--miner.gaslimit "0x2625A00" \
--miner.etherbase "<node1_account_address>"
注意,可能会遇见端口冲突,修改端口即可,还可能遇见502网关错误,可以尝试rpc: http://localhost:<port>
还需要参与POA共识,提供节点账户地址,让其它签名者达成共识,将其添加到签名者列表中
B、启动一个正常节点(仅同步和广播交易)
geth --datadir node1 \
--networkid 8888 \
--http --http.addr "0.0.0.0" --http.port 8546 \
--http.api "eth,net,web3,personal,admin,clique" \
--port 30303 \
--allow-insecure-unlock \
--cache 4096 \
--bootnodes "enode://02af1096f065550865969cd47e25f062b1db8b5e04b91e63ea77584d87e59e27cd7762547e897cbb4330944ae06ff474a94746db0d09f411b5aa222ab15acab1@40.78.123.6:30303" \
--unlock "<node1_account_address>" \
--password "node1/password.txt" \
--ws --ws.addr "0.0.0.0" --ws.port 8552 --ws.api "eth,net,web3,personal,admin,clique" \
--authrpc.port 8555
7、启动控制台查看同步区块(同步需要时间,可能需要等会儿)
geth attach node1/geth.ipc
一下是一些控制台测试命令:
发送交易
eth.sendTransaction({from: "address1", to: "address2", value: web3.toWei(1, "ether")})
检查余额(按ether)
web3.fromWei(eth.getBalance("address1"), "ether")
解锁账户
personal.unlockAccount("address1", "1234", 600)
检查节点的同步状态:
eth.syncing
创建一个新账户
personal.newAccount("1111")
查看所有账户
eth.accounts
检查节点是否连接到另一个对等节点
net.peerCount
查看区块
eth.blockNumber