geth测试环境搭建

参考这个这个这个这个

以太坊命令选项: 
使用命令 geth -h 可以查看geth 相关的帮助文档。这里我说几个常用的属性。
    --Identity : 节点身份标识,起个名字
    --datadir : 指定节点存在位置,“data”
    --rpc : 启用http-rpc服务器
    --rpcapi : 基于http-rpc提供的api接口。eth,net,web3,db...
    --rpcaddr : http-rpc服务器接口地址:默认“127.0.0.1”
    --rpcport : http-rpc 端口(多节点时,不要重复)
    --port : 节点端口号(多节点时,不要重复)
    --networkid : 网络标识符 随便指定一个id(确保多节点是统一网络,保持一致)


go-ethereum文档

HTTP based JSON-RPC API options:

  • --http Enable the HTTP-RPC server
  • --http.addr HTTP-RPC server listening interface (default: localhost)
  • --http.port HTTP-RPC server listening port (default: 8545)
  • --http.api API's offered over the HTTP-RPC interface (default: eth,net,web3)
  • --http.corsdomain Comma separated list of domains from which to accept cross origin requests (browser enforced)
  • --ws Enable the WS-RPC server
  • --ws.addr WS-RPC server listening interface (default: localhost)
  • --ws.port WS-RPC server listening port (default: 8546)
  • --ws.api API's offered over the WS-RPC interface (default: eth,net,web3)
  • --ws.origins Origins from which to accept WebSocket requests
  • --ipcdisable Disable the IPC-RPC server
  • --ipcapi API's offered over the IPC-RPC interface (default: admin,debug,eth,miner,net,personal,txpool,web3)
  • --ipcpath Filename for IPC socket/pipe within the datadir (explicit paths escape it)


json-rpc-specification文档


json-rpc文档

Not all of the JSON-RPC method namespaces are enabled for HTTP requests by default. Instead, they have to be whitelisted explicitly when Geth is started. Calling non-whitelisted RPC namespaces returns an RPC error with code -32602.

The default whitelist allows access to the ethnet and web3 namespaces. To enable access to other APIs like account management (personal) and debugging (debug), they must be configured using the --http.api flag. Enabling these APIs over HTTP is not recommended because access to these methods increases the attack surface.

geth --http --http.api personal,eth,net,web3
以下是在ubuntu下的步骤,有部分问题还未解决。

"listen tcp 127.0.0.1:8551: bind: address already in use"
参考这里,给不同的节点指明--authrpc.port参数即可

peer connected on snap without compatible eth support
没有解决!

环境:
geth: Version: 1.10.25-stable
ubuntu:Ubuntu 20.04.5 LTS(GNU/Linux 5.4.0-128-generic x86_64)

ubuntu:
1、初始化节点
mkdir -p $GETH_HOME/{bin,node1,node2,node3,node4}

initaddr.sh: 
#!/usr/bin/env bash
#init node1
$GETH_HOME/bin/geth --datadir $GETH_HOME/node1 account new

#init node2
if [ $? -eq 0 ] ;
then
    echo "node1 init ok!"
    $GETH_HOME/bin/geth --datadir $GETH_HOME/node2 account new
fi
#init node3
if [ $? -eq 0 ] ;
then
    echo "node2 init ok!"
    $GETH_HOME/bin/geth --datadir $GETH_HOME/node3 account new
fi
#init node4
if [ $? -eq 0 ] ;
then
    echo "node3 init ok!"
    $GETH_HOME/bin/geth --datadir $GETH_HOME/node4 account new
fi

if [ $? -eq 0 ] ;
then
    echo "node4 init ok!"
fi

运行结果如下:

[test@hst1:geth]$ bash initaddr.sh
INFO [10-21|10:12:54.848] Maximum peer count                       ETH=50 LES=0 total=50
INFO [10-21|10:12:54.849] Smartcard socket not found, disabling    err="stat /run/pcscd/pcscd.comm: no such file or directory"
Your new account is locked with a password. Please give a password. Do not forget this password.
Password:
Repeat password:

Your new key was generated

Public address of the key:   0xdA8D89eaA7e32eb9Fa47a6903FeFD4C8B534A98c
Path of the secret key file: ${YOUR_NODE1_PATH}


- You can share your public address with anyone. Others need it to interact with you.
- You must NEVER share the secret key with anyone! The key controls access to your funds!
- You must BACKUP your key file! Without the key, it's impossible to access account funds!
- You must REMEMBER your password! Without the password, it's impossible to decrypt the key!

node1 init ok!
INFO [10-21|10:13:08.959] Maximum peer count                       ETH=50 LES=0 total=50
INFO [10-21|10:13:08.960] Smartcard socket not found, disabling    err="stat /run/pcscd/pcscd.comm: no such file or directory"
Your new account is locked with a password. Please give a password. Do not forget this password.
Password:
Repeat password:

Your new key was generated

Public address of the key:   0x94Faf6Bd3D5cee102DF91515C2907e64b9099680
Path of the secret key file: ${YOUR_NODE2_PATH}

- You can share your public address with anyone. Others need it to interact with you.
- You must NEVER share the secret key with anyone! The key controls access to your funds!
- You must BACKUP your key file! Without the key, it's impossible to access account funds!
- You must REMEMBER your password! Without the password, it's impossible to decrypt the key!

node2 init ok!
INFO [10-21|10:13:25.842] Maximum peer count                       ETH=50 LES=0 total=50
INFO [10-21|10:13:25.842] Smartcard socket not found, disabling    err="stat /run/pcscd/pcscd.comm: no such file or directory"
Your new account is locked with a password. Please give a password. Do not forget this password.
Password:
Repeat password:

Your new key was generated

Public address of the key:   0xd00Fa00bE4F399a0c7D9cf8E1654800B53188719
Path of the secret key file:${YOUR_NODE3_PATH}

- You can share your public address with anyone. Others need it to interact with you.
- You must NEVER share the secret key with anyone! The key controls access to your funds!
- You must BACKUP your key file! Without the key, it's impossible to access account funds!
- You must REMEMBER your password! Without the password, it's impossible to decrypt the key!

node3 init ok!
INFO [10-21|10:13:37.842] Maximum peer count                       ETH=50 LES=0 total=50
INFO [10-21|10:13:37.842] Smartcard socket not found, disabling    err="stat /run/pcscd/pcscd.comm: no such file or directory"
Your new account is locked with a password. Please give a password. Do not forget this password.
Password:
Repeat password:

Your new key was generated

Public address of the key:   0xd5eD50A6Be0bcFe9F46c83461dCDB58b1570B904
Path of the secret key file: ${YOUR_NODE4_PATH}

- You can share your public address with anyone. Others need it to interact with you.
- You must NEVER share the secret key with anyone! The key controls access to your funds!
- You must BACKUP your key file! Without the key, it's impossible to access account funds!
- You must REMEMBER your password! Without the password, it's impossible to decrypt the key!

node4 init ok!

地址信息如下: 
node1: 0xdA8D89eaA7e32eb9Fa47a6903FeFD4C8B534A98c
node2: 0x94Faf6Bd3D5cee102DF91515C2907e64b9099680
node3: 0xd00Fa00bE4F399a0c7D9cf8E1654800B53188719
node4: 0xd5eD50A6Be0bcFe9F46c83461dCDB58b1570B904

2、创建私有网络配置,使用puppeth 
建立创世块(Genesis Block)
创世块是区块链中第一个区块(唯一无需引用前个区块的区块). 通过运行puppeth, 来生成创世区块. 运行puppeth后首先提示输入私链名称.

[test@hst1:geth]$ puppeth

+-----------------------------------------------------------+
| Welcome to puppeth, your Ethereum private network manager |
|                                                           |
| This tool lets you create a new Ethereum network down to  |
| the genesis block, bootnodes, miners and ethstats servers |
| without the hassle that it would normally entail.         |
|                                                           |
| Puppeth uses SSH to dial in to remote servers, and builds |
| its network components out of Docker containers using the |
| docker-compose toolset.                                   |
+-----------------------------------------------------------+

Please specify a network name to administer (no spaces, hyphens or capital letters please)
> prveth

Sweet, you can set this via --network=prveth next time!

INFO [10-21|10:22:49.123] Administering Ethereum network           name=prveth
WARN [10-21|10:22:49.124] No previous configurations found         path=/home/wk/.puppeth/prveth

#输入完私链名称后, 出现选择菜单. 选择2: 配置新创世块
What would you like to do? (default = stats)
 1. Show network stats
 2. Configure new genesis
 3. Track new remote server
 4. Deploy network components
> 2

What would you like to do? (default = create)
 1. Create new genesis from scratch
 2. Import already existing genesis
> 1

#出现子菜单, 选择私链的共识机制(Consensus Protocols).
# proof-of-work(PoW): 工作量证明, 通过算力证明来达成共识
# proof-of-authority(PoA): 权威证明, 通过预先设定的权威节点来负责达成共识
#这里选择PoA的认证方式, 和目前以太坊主链保持一致.
#建立创世块时, 也可以选择采用PoA方式的共识算法(不消耗计算力, 可以用于私链测试开发)

Which consensus engine to use? (default = clique)
 1. Ethash - proof-of-work
 2. Clique - proof-of-authority
> 2

# 选择PoA后, 会提示选择出块的间隔时间. 由于是用于内部测试的私链, 可以将出块时间设置较少, 这里配置200秒.
How many seconds should blocks take? (default = 15)
> 200

#允许哪些账户可以挖矿。至少选择一个前面步骤中创建的账户地址(我的建议至少两个,理由前面说了)
#这里我将4个刚才创建的账户地址全输入了,这样当节点运行时,这些账户都有权限进行挖矿
# 设置那个账号作为权威来生成块,
Which accounts are allowed to seal? (mandatory at least one)
> 0xdA8D89eaA7e32eb9Fa47a6903FeFD4C8B534A98c
> 0x94Faf6Bd3D5cee102DF91515C2907e64b9099680
> 0xd00Fa00bE4F399a0c7D9cf8E1654800B53188719
> 0xd5eD50A6Be0bcFe9F46c83461dCDB58b1570B904
> 0x

#选择是否需要初始化就给指定账号ether, 这里可以输入之前建立node1、node2账号的地址.直接回车结束输入
Which accounts should be pre-funded? (advisable at least one)
> 0xdA8D89eaA7e32eb9Fa47a6903FeFD4C8B534A98c
> 0x94Faf6Bd3D5cee102DF91515C2907e64b9099680
> 0x

#如果选 yes,那么从 0x0000000000000000000000000000000000000000 到0x00000000000000000000000000000000000000ff 这些地址都会有 1wei 的以太币。
Should the precompile-addresses (0x1 .. 0xff) be pre-funded with 1 wei? (advisable yes)
> no

# 输入私链ID, 直接输入回车,已默认随机数作为私链ID
Specify your chain/network ID if you want an explicit one (default = random)
>
INFO [10-21|10:26:51.661] Configured new genesis block

# 回到主菜单, 重新选择2
What would you like to do? (default = stats)
 1. Show network stats
 2. Manage existing genesis
 3. Track new remote server
 4. Deploy network components
> 2

# 选择导出创世块配置文件
 1. Modify existing configurations
 2. Export genesis configurations
 3. Remove genesis configuration
> 2

# 在提示创世块配置文件位置时, 直接输入回车, 默认当前目录生成创世块配置文件
Which folder to save the genesis spec into? (default = current)
  Will create prveth.json
>
INFO [10-21|10:28:03.437] Saved native genesis chain spec          path=prveth.json

What would you like to do? (default = stats)
 1. Show network stats
 2. Manage existing genesis
 3. Track new remote server
 4. Deploy network components
>

退出puppeth

prveth.json内容如下: 
{
  "config": {
    "chainId": 37373,
    "homesteadBlock": 0,
    "eip150Block": 0,
    "eip150Hash": "0x0000000000000000000000000000000000000000000000000000000000000000",
    "eip155Block": 0,
    "eip158Block": 0,
    "byzantiumBlock": 0,
    "constantinopleBlock": 0,
    "petersburgBlock": 0,
    "istanbulBlock": 0,
    "clique": {
      "period": 200,
      "epoch": 30000
    }
  },
  "nonce": "0x0",
  "timestamp": "0x63526516",
  "extraData": "0x000000000000000000000000000000000000000000000000000000000000000094faf6bd3d5cee102df91515c2907e64b9099680d00fa00be4f399a0c7d9cf8e1654800b53188719d5ed50a6be0bcfe9f46c83461dcdb58b1570b904da8d89eaa7e32eb9fa47a6903fefd4c8b534a98c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
  "gasLimit": "0x47b760",
  "difficulty": "0x1",
  "mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
  "coinbase": "0x0000000000000000000000000000000000000000",
  "alloc": {
    "94faf6bd3d5cee102df91515c2907e64b9099680": {
      "balance": "0x200000000000000000000000000000000000000000000000000000000000000"
    },
    "da8d89eaa7e32eb9fa47a6903fefd4c8b534a98c": {
      "balance": "0x200000000000000000000000000000000000000000000000000000000000000"
    }
  },
  "number": "0x0",
  "gasUsed": "0x0",
  "parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
  "baseFeePerGas": null
}

当前目录结构如下:
[test@hst1:geth]$ tree
.
├── bin
│   ├── abigen
│   ├── bootnode
│   ├── clef
│   ├── evm
│   ├── geth
│   ├── puppeth
│   └── rlpdump
├── initaddr.sh
├── node1
│   └── keystore
│       └── UTC1
├── node2
│   └── keystore
│       └── UTC2
├── node3
│   └── keystore
│       └── UTC3
├── node4
│   └── keystore
│       └── UTC4
└── prveth.json

9 directories, 13 files


3、初始化/启动私链节点
通过如下命令初始化各个节点的数据. 如下命令
initnode.sh: 
#!/usr/bin/env bash
for i in `seq 1 4`
do
    echo "node$i init start"
    $GETH_HOME/bin/geth --datadir $GETH_HOME/node$i init prveth.json
    echo "node$i init done!"
done


当前目录结构如下: 
.
├── 1.txt
├── bin
│   ├── abigen
│   ├── bootnode
│   ├── clef
│   ├── evm
│   ├── geth
│   ├── puppeth
│   └── rlpdump
├── initaddr.sh
├── initnode.sh
├── node1
│   ├── geth
│   │   ├── chaindata
│   │   │   ├── 000002.ldb
│   │   │   ├── 000005.ldb
│   │   │   ├── 000006.log
│   │   │   ├── ancient
│   │   │   │   └── chain
│   │   │   │       ├── bodies.0000.cdat
│   │   │   │       ├── bodies.cidx
│   │   │   │       ├── bodies.meta
│   │   │   │       ├── diffs.0000.rdat
│   │   │   │       ├── diffs.meta
│   │   │   │       ├── diffs.ridx
│   │   │   │       ├── FLOCK
│   │   │   │       ├── hashes.0000.rdat
│   │   │   │       ├── hashes.meta
│   │   │   │       ├── hashes.ridx
│   │   │   │       ├── headers.0000.cdat
│   │   │   │       ├── headers.cidx
│   │   │   │       ├── headers.meta
│   │   │   │       ├── receipts.0000.cdat
│   │   │   │       ├── receipts.cidx
│   │   │   │       └── receipts.meta
│   │   │   ├── CURRENT
│   │   │   ├── CURRENT.bak
│   │   │   ├── LOCK
│   │   │   ├── LOG
│   │   │   └── MANIFEST-000007
│   │   ├── lightchaindata
│   │   │   ├── 000002.ldb
│   │   │   ├── 000005.ldb
│   │   │   ├── 000006.log
│   │   │   ├── ancient
│   │   │   │   └── chain
│   │   │   │       ├── bodies.0000.cdat
│   │   │   │       ├── bodies.cidx
│   │   │   │       ├── bodies.meta
│   │   │   │       ├── diffs.0000.rdat
│   │   │   │       ├── diffs.meta
│   │   │   │       ├── diffs.ridx
│   │   │   │       ├── FLOCK
│   │   │   │       ├── hashes.0000.rdat
│   │   │   │       ├── hashes.meta
│   │   │   │       ├── hashes.ridx
│   │   │   │       ├── headers.0000.cdat
│   │   │   │       ├── headers.cidx
│   │   │   │       ├── headers.meta
│   │   │   │       ├── receipts.0000.cdat
│   │   │   │       ├── receipts.cidx
│   │   │   │       └── receipts.meta
│   │   │   ├── CURRENT
│   │   │   ├── CURRENT.bak
│   │   │   ├── LOCK
│   │   │   ├── LOG
│   │   │   └── MANIFEST-000007
│   │   ├── LOCK
│   │   └── nodekey
│   └── keystore
│       └── UTC1
├── node2
│   ├── geth
│   │   ├── chaindata
│   │   │   ├── 000001.log
│   │   │   ├── ancient
│   │   │   │   └── chain
│   │   │   │       ├── bodies.0000.cdat
│   │   │   │       ├── bodies.cidx
│   │   │   │       ├── bodies.meta
│   │   │   │       ├── diffs.0000.rdat
│   │   │   │       ├── diffs.meta
│   │   │   │       ├── diffs.ridx
│   │   │   │       ├── FLOCK
│   │   │   │       ├── hashes.0000.rdat
│   │   │   │       ├── hashes.meta
│   │   │   │       ├── hashes.ridx
│   │   │   │       ├── headers.0000.cdat
│   │   │   │       ├── headers.cidx
│   │   │   │       ├── headers.meta
│   │   │   │       ├── receipts.0000.cdat
│   │   │   │       ├── receipts.cidx
│   │   │   │       └── receipts.meta
│   │   │   ├── CURRENT
│   │   │   ├── LOCK
│   │   │   ├── LOG
│   │   │   └── MANIFEST-000000
│   │   ├── lightchaindata
│   │   │   ├── 000001.log
│   │   │   ├── ancient
│   │   │   │   └── chain
│   │   │   │       ├── bodies.0000.cdat
│   │   │   │       ├── bodies.cidx
│   │   │   │       ├── bodies.meta
│   │   │   │       ├── diffs.0000.rdat
│   │   │   │       ├── diffs.meta
│   │   │   │       ├── diffs.ridx
│   │   │   │       ├── FLOCK
│   │   │   │       ├── hashes.0000.rdat
│   │   │   │       ├── hashes.meta
│   │   │   │       ├── hashes.ridx
│   │   │   │       ├── headers.0000.cdat
│   │   │   │       ├── headers.cidx
│   │   │   │       ├── headers.meta
│   │   │   │       ├── receipts.0000.cdat
│   │   │   │       ├── receipts.cidx
│   │   │   │       └── receipts.meta
│   │   │   ├── CURRENT
│   │   │   ├── LOCK
│   │   │   ├── LOG
│   │   │   └── MANIFEST-000000
│   │   ├── LOCK
│   │   └── nodekey
│   └── keystore
│       └── UTC2
├── node3
│   ├── geth
│   │   ├── chaindata
│   │   │   ├── 000001.log
│   │   │   ├── ancient
│   │   │   │   └── chain
│   │   │   │       ├── bodies.0000.cdat
│   │   │   │       ├── bodies.cidx
│   │   │   │       ├── bodies.meta
│   │   │   │       ├── diffs.0000.rdat
│   │   │   │       ├── diffs.meta
│   │   │   │       ├── diffs.ridx
│   │   │   │       ├── FLOCK
│   │   │   │       ├── hashes.0000.rdat
│   │   │   │       ├── hashes.meta
│   │   │   │       ├── hashes.ridx
│   │   │   │       ├── headers.0000.cdat
│   │   │   │       ├── headers.cidx
│   │   │   │       ├── headers.meta
│   │   │   │       ├── receipts.0000.cdat
│   │   │   │       ├── receipts.cidx
│   │   │   │       └── receipts.meta
│   │   │   ├── CURRENT
│   │   │   ├── LOCK
│   │   │   ├── LOG
│   │   │   └── MANIFEST-000000
│   │   ├── lightchaindata
│   │   │   ├── 000001.log
│   │   │   ├── ancient
│   │   │   │   └── chain
│   │   │   │       ├── bodies.0000.cdat
│   │   │   │       ├── bodies.cidx
│   │   │   │       ├── bodies.meta
│   │   │   │       ├── diffs.0000.rdat
│   │   │   │       ├── diffs.meta
│   │   │   │       ├── diffs.ridx
│   │   │   │       ├── FLOCK
│   │   │   │       ├── hashes.0000.rdat
│   │   │   │       ├── hashes.meta
│   │   │   │       ├── hashes.ridx
│   │   │   │       ├── headers.0000.cdat
│   │   │   │       ├── headers.cidx
│   │   │   │       ├── headers.meta
│   │   │   │       ├── receipts.0000.cdat
│   │   │   │       ├── receipts.cidx
│   │   │   │       └── receipts.meta
│   │   │   ├── CURRENT
│   │   │   ├── LOCK
│   │   │   ├── LOG
│   │   │   └── MANIFEST-000000
│   │   ├── LOCK
│   │   └── nodekey
│   └── keystore
│       └── UTC3
├── node4
│   ├── geth
│   │   ├── chaindata
│   │   │   ├── 000001.log
│   │   │   ├── ancient
│   │   │   │   └── chain
│   │   │   │       ├── bodies.0000.cdat
│   │   │   │       ├── bodies.cidx
│   │   │   │       ├── bodies.meta
│   │   │   │       ├── diffs.0000.rdat
│   │   │   │       ├── diffs.meta
│   │   │   │       ├── diffs.ridx
│   │   │   │       ├── FLOCK
│   │   │   │       ├── hashes.0000.rdat
│   │   │   │       ├── hashes.meta
│   │   │   │       ├── hashes.ridx
│   │   │   │       ├── headers.0000.cdat
│   │   │   │       ├── headers.cidx
│   │   │   │       ├── headers.meta
│   │   │   │       ├── receipts.0000.cdat
│   │   │   │       ├── receipts.cidx
│   │   │   │       └── receipts.meta
│   │   │   ├── CURRENT
│   │   │   ├── LOCK
│   │   │   ├── LOG
│   │   │   └── MANIFEST-000000
│   │   ├── lightchaindata
│   │   │   ├── 000001.log
│   │   │   ├── ancient
│   │   │   │   └── chain
│   │   │   │       ├── bodies.0000.cdat
│   │   │   │       ├── bodies.cidx
│   │   │   │       ├── bodies.meta
│   │   │   │       ├── diffs.0000.rdat
│   │   │   │       ├── diffs.meta
│   │   │   │       ├── diffs.ridx
│   │   │   │       ├── FLOCK
│   │   │   │       ├── hashes.0000.rdat
│   │   │   │       ├── hashes.meta
│   │   │   │       ├── hashes.ridx
│   │   │   │       ├── headers.0000.cdat
│   │   │   │       ├── headers.cidx
│   │   │   │       ├── headers.meta
│   │   │   │       ├── receipts.0000.cdat
│   │   │   │       ├── receipts.cidx
│   │   │   │       └── receipts.meta
│   │   │   ├── CURRENT
│   │   │   ├── LOCK
│   │   │   ├── LOG
│   │   │   └── MANIFEST-000000
│   │   ├── LOCK
│   │   └── nodekey
│   └── keystore
│       └── UTC4
├── prveth.json
└── test.sh

37 directories, 198 files

4、配置P2P发现网络
>>>>>node1:

$GETH_HOME/bin/geth --http --http.addr 0.0.0.0 --http.port 18545 --http.api 'admin,debug,web3,eth,txpool,personal,clique,miner,net,engine' --http.corsdomain  "*"  --http.vhosts "*"  --datadir $GETH_HOME/node1/ --networkid 37373 --ws --ws.addr 0.0.0.0  --ws.port 18546 --ws.api 'admin,debug,web3,eth,txpool,personal,clique,miner,net,engine' --ws.origins '*'  --graphql --graphql.corsdomain "*"  --graphql.vhosts "*" --port 10303 --allow-insecure-unlock --unlock 0 --mine  --authrpc.port 18551   console  2>>node1-geth.log

To exit, press ctrl-d or type exit
> admin.nodeInfo.enode
"enode://2b1ba58f3efcc24bab471b8c4478127eb1cfbef682f70d0fe00e623ca15999a04b6a6092e2ca8f281a65b8b296bda44a94ae9e61b36b95271d4c6943e499e21c@127.0.0.1:10303"
>



>>>>>node2: 
$GETH_HOME/bin/geth --http --http.addr 0.0.0.0 --http.port 28545 --http.api 'admin,debug,web3,eth,txpool,personal,clique,miner,net,engine' --http.corsdomain  "*"  --http.vhosts "*"  --datadir $GETH_HOME/node2/ --networkid 37373 --ws --ws.addr 0.0.0.0  --ws.port 28546 --ws.api 'admin,debug,web3,eth,txpool,personal,clique,miner,net,engine' --ws.origins '*'  --graphql --graphql.corsdomain "*"  --graphql.vhosts "*" --port 20303 --allow-insecure-unlock --unlock 0 --mine  --authrpc.port 28551   console  2>>node2-geth.log

To exit, press ctrl-d or type exit
> admin.nodeInfo.enode
"enode://2991c2a46e44414a3d08ff299ba6eae6d284118b75b51b92cba5f0ecfea81822c2c4656df67efb3c2849595d7d3b22032aad8addf195264dd46daf60c98e6dc0@127.0.0.1:20303"
>

>>>>>node3: 
$GETH_HOME/bin/geth --http --http.addr 0.0.0.0 --http.port 38545 --http.api 'admin,debug,web3,eth,txpool,personal,clique,miner,net,engine' --http.corsdomain  "*"  --http.vhosts "*"  --datadir $GETH_HOME/node3/ --networkid 37373 --ws --ws.addr 0.0.0.0  --ws.port 38546 --ws.api 'admin,debug,web3,eth,txpool,personal,clique,miner,net,engine' --ws.origins '*'  --graphql --graphql.corsdomain "*"  --graphql.vhosts "*" --port 30303 --allow-insecure-unlock --unlock 0 --mine  --authrpc.port 38551   console  2>>node3-geth.log

To exit, press ctrl-d or type exit
> admin.nodeInfo.enode
"enode://38556859ab870f2cd252463ae9387af9185b4a1324babee320c0ef002dc6860b0a99a468d9f677ceec96a4edf291ca4e8effdf560c0de132907055192d1c029a@127.0.0.1:30303"
>



>>>>>node4: 

$GETH_HOME/bin/geth --http --http.addr 0.0.0.0 --http.port 48545 --http.api 'admin,debug,web3,eth,txpool,personal,clique,miner,net,engine' --http.corsdomain  "*"  --http.vhosts "*"  --datadir $GETH_HOME/node4/ --networkid 37373 --ws --ws.addr 0.0.0.0  --ws.port 48546 --ws.api 'admin,debug,web3,eth,txpool,personal,clique,miner,net,engine' --ws.origins '*'  --graphql --graphql.corsdomain "*"  --graphql.vhosts "*" --port 40303 --allow-insecure-unlock --unlock 0 --mine  --authrpc.port 48551  console  2>>node4-geth.log

To exit, press ctrl-d or type exit
> admin.nodeInfo.enode
"enode://3f71b25d54d21b2ef32b7054c2bd977cb8696716a5b29fcda3c46834ee87a565e38b6ae23863a7a0122ebe8c9b1b1d53b52ccf5338c4e8669bdee56e1e678ad8@127.0.0.1:40303"
>


static-nodes.json放到每个节点的数据目录内,文件内容如下:
[
  "enode://2b1ba58f3efcc24bab471b8c4478127eb1cfbef682f70d0fe00e623ca15999a04b6a6092e2ca8f281a65b8b296bda44a94ae9e61b36b95271d4c6943e499e21c@127.0.0.1:10303",
  "enode://2991c2a46e44414a3d08ff299ba6eae6d284118b75b51b92cba5f0ecfea81822c2c4656df67efb3c2849595d7d3b22032aad8addf195264dd46daf60c98e6dc0@127.0.0.1:20303",
  "enode://38556859ab870f2cd252463ae9387af9185b4a1324babee320c0ef002dc6860b0a99a468d9f677ceec96a4edf291ca4e8effdf560c0de132907055192d1c029a@127.0.0.1:30303",
  "enode://3f71b25d54d21b2ef32b7054c2bd977cb8696716a5b29fcda3c46834ee87a565e38b6ae23863a7a0122ebe8c9b1b1d53b52ccf5338c4e8669bdee56e1e678ad8@127.0.0.1:40303"
]

start-node1.sh:
#!/usr/bin/env bash

$GETH_HOME/bin/geth --http --http.addr 0.0.0.0 --http.port 18545 --http.api 'admin,debug,web3,eth,txpool,personal,clique,miner,net,engine' --http.corsdomain  "*"  --http.vhosts "*"  --datadir $GETH_HOME/node1/ --networkid 37373 --ws --ws.addr 0.0.0.0  --ws.port 18546 --ws.api 'admin,debug,web3,eth,txpool,personal,clique,miner,net,engine' --ws.origins '*'  --graphql --graphql.corsdomain "*"  --graphql.vhosts "*" --port 10303 --allow-insecure-unlock --unlock 0 --mine --ipcdisable --authrpc.port 18551 console  2>>node1-geth.log

start-node2.sh:
#!/usr/bin/env bash

$GETH_HOME/bin/geth --http --http.addr 0.0.0.0 --http.port 28545 --http.api 'admin,debug,web3,eth,txpool,personal,clique,miner,net,engine' --http.corsdomain  "*"  --http.vhosts "*"  --datadir $GETH_HOME/node2/ --networkid 37373 --ws --ws.addr 0.0.0.0  --ws.port 28546 --ws.api 'admin,debug,web3,eth,txpool,personal,clique,miner,net,engine' --ws.origins '*'  --graphql --graphql.corsdomain "*"  --graphql.vhosts "*" --port 20303 --allow-insecure-unlock --unlock 0 --mine  --authrpc.port 28551   console  2>>node2-geth.log


start-node3.sh:
#!/usr/bin/env bash

$GETH_HOME/bin/geth --http --http.addr 0.0.0.0 --http.port 38545 --http.api 'admin,debug,web3,eth,txpool,personal,clique,miner,net,engine' --http.corsdomain  "*"  --http.vhosts "*"  --datadir $GETH_HOME/node3/ --networkid 37373 --ws --ws.addr 0.0.0.0  --ws.port 38546 --ws.api 'admin,debug,web3,eth,txpool,personal,clique,miner,net,engine' --ws.origins '*'  --graphql --graphql.corsdomain "*"  --graphql.vhosts "*" --port 30303 --allow-insecure-unlock --unlock 0 --mine  --authrpc.port 38551   console  2>>node3-geth.log


start-node4.sh: 
#!/usr/bin/env bash

$GETH_HOME/bin/geth --http --http.addr 0.0.0.0 --http.port 48545 --http.api 'admin,debug,web3,eth,txpool,personal,clique,miner,net,engine' --http.corsdomain  "*"  --http.vhosts "*"  --datadir $GETH_HOME/node4/ --networkid 37373 --ws --ws.addr 0.0.0.0  --ws.port 48546 --ws.api 'admin,debug,web3,eth,txpool,personal,clique,miner,net,engine' --ws.origins '*'  --graphql --graphql.corsdomain "*"  --graphql.vhosts "*" --port 40303 --allow-insecure-unlock --unlock 0 --mine  --authrpc.port 48551  console  2>>node4-geth.log