本文主要是介绍如何在Geth中搭建P2P多节点以太坊私链:详细教程与实操步骤,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
系列文章目录
geth以太坊私链开发模式🚪
geth以太坊私链P2P模式🚪
文章目录
- 系列文章目录
- 前言
- 一、P2P 多节点模式与开发模式的区别
- 二、下载geth以太坊客户端
- 三、私链配置
- 3.1 生成创世文件
- 3.2 引导结点配置
- 3.3 成员结点配置
- 3.4 连接两个结点
- 3.4.1 获取引导结点的Enode信息
- 3.4.2 连接成员结点到引导结点
- 3.4.3 验证连接
- 3.4.4 同步和挖矿
- 总结
前言
在以太坊开发过程中,开发者通常会使用私链进行测试。与单节点开发模式不同,多节点的 P2P 网络能够更好地模拟真实的以太坊网络环境,帮助开发者测试网络行为、节点间的通信以及共识机制。本篇博客将带你一步步搭建一个基于 Geth 的 P2P 多节点私链网络。
一、P2P 多节点模式与开发模式的区别
P2P 多节点模式是一种更接近真实以太坊网络的配置方式。在这种模式下,多个节点通过点对点(Peer-to-Peer, P2P)网络相互连接,每个节点都独立运行,并通过网络协议进行通信和数据同步。相比之下,开发模式是一种单节点模式,通常用于快速开发和调试,虽然简便,但无法模拟真实的多节点网络行为
-
网络规模:
开发模式:仅需一个节点即可运行,适用于简单的开发和测试。
P2P 多节点模式:涉及多个节点,节点之间通过 P2P 方式通信,能够更好地模拟以太坊主网环境。 -
网络拓扑:
开发模式:没有 P2P 网络,所有操作在单节点上完成。
P2P 多节点模式:节点之间构成分布式网络,数据通过 P2P 协议传播和同步。 -
挖矿和共识:
开发模式:默认无需挖矿,交易会自动被确认。
P2P 多节点模式:支持多节点参与挖矿,模拟真实的共识机制,如工作量证明(PoW)
搭建多节点网络的意义
搭建 P2P 多节点网络对开发者和测试人员有重要意义:
-
真实环境模拟:通过多节点网络,可以模拟真实的区块链网络行为,包括节点间的通信延迟、数据同步、共识达成等。这对于测试分布式应用和验证区块链协议的健壮性至关重要。
-
网络行为测试:在多节点环境下,可以观察网络中的节点如何处理交易、同步区块和达成共识。这种测试有助于发现单节点模式无法暴露的潜在问题,如网络分叉、节点分裂和数据不一致。
-
性能调优:通过搭建多节点网络,开发者可以测试和调优区块链网络的性能,包括出块时间、交易吞吐量和网络延迟等,以确保在生产环境中达到最佳表现。
综上所述,P2P 多节点模式不仅适合用于更复杂的测试场景,还为模拟真实以太坊网络提供了必要的环境支持。这对于开发、测试和最终部署区块链应用都是不可或缺的一部分。
二、下载geth以太坊客户端
geth官方文档🚪
使用最新版本geth客户端时,当执行personal.unlockAccount()
或在程序中调用personal_unlockAccount
接口时,会出现:account unlock with HTTP access is forbidden
异常。
geth解锁账户Block sealing failed err="authentication needed: password or unlock"
,或者是提示personal
不存在等问题,是因为最新版geth已经淘汰了personal
模块解锁账户以及使用puppeth
生成创世文件,新版本geth,出于安全考虑,默认禁止了HTTP通道解锁账户,而是使用以下命令解锁账户,相关issue🚪
--allow-insecure-unlock
所以降级下载1.10.26
版本的geth客户端,解压压缩包,将geth以及puppeth工具放到环境变量里以供使用,下面我用的是linux安装的方式
windows版本的下载安装geth的方式在我之前的博客🚪里有,可以看一下
wget https://gethstore.blob.core.windows.net/builds/geth-alltools-linux-amd64-1.10.26-e5eb32ac.tar.gz
tar -xzf geth-alltools-linux-amd64-1.10.26-e5eb32ac.tar.gz
cd geth-alltools-linux-amd64-1.10.26-e5eb32ac
cp geth /usr/local/bin/
cp puppeth /usr/local/bin/
三、私链配置
我们将搭建一个包含 2 个节点的以太坊私链,每个节点将通过 P2P 方式相互连接。一个节点将作为引导结点,另外一个节点将作为成员节点
引导节点(Bootnode):在网络中,通常有一个或多个节点充当引导节点,被指定为其他节点用于加入网络的入口点,它们主要用于帮助新节点发现和连接到网络中的其他节点。任何节点都可以作为引导节点。其他节点将使用引导节点记录中包含的信息连接到对等网络
成员节点:这些是普通的参与节点,它们连接到网络中其他节点,进行数据同步和交易处理。在运行成员节点之前,必须使用与引导节点相同的创世文件对其进行初始化。
3.1 生成创世文件
- 创建两个存放结点的文件夹
nodeA
作为引导结点,nodeB
作为成员结点,如果想要更多成员节点加入,与nodeB
配置步骤是一样的
mkdir nodeA
mkdir nodeB
- 用
puppeth
创建创世文件,依次按照以下输入命令:
puppeth (启动工具)
privatenet (给网络命名)
2 (configure new genesis,配置创世文件)
1 (Create new genesis from scratch,创建一个新的创世文件)
1 (Ethash - proof-of-work,使用工作量证明)
0x (账户前缀)
yes
1234 (链ID)
2 (Manage existing genesis,管理已存在的创世文件)
2 (Export genesis configurations,导出创世文件)
直接回车保存文件
最后关闭命令行窗口会看到出现privatenet.json
创世文件
3.2 引导结点配置
- 初始化引导结点
geth --datadir /root/nodeA/data init privatenet.json
- 创建账户
在nodeA
文件夹根目录下先创建一个password.txt
以存放账户的密码,输入以下命令后会要求你输入密码及确认密码,创建完成后,会在你的nodeA/data/ketstore
文件夹下多出一个key
私钥文件,这就是生成的账户的私钥
geth account new --datadir /root/nodeA/data --password password.txt
- 启动引导节点
这个命令用于启动 Geth(Go Ethereum)节点,并附带了一系列参数来配置节点的行为。以下是每个参数的解释:
geth --datadir /root/nodeA/data --networkid 1234 --syncmode full --nodiscover --http --http.addr 0.0.0.0 --http.port 8888 --http.api personal,admin,eth,net,web3,miner --http.corsdomain "*" --ws --ws.api eth,web3,net --ws.origins "*" --ws.addr "127.0.0.1" --ws.port 8546 --mine --miner.threads 1 --port 30303 --allow-insecure-unlock --unlock "0x36f3689a4D30fB7A98151e50ABbB37b5da52064f" --password password.txt
主要参数和其含义:
--datadir /root/nodeA/data
:指定 Geth 的数据目录,用于存储区块链数据、密钥库等。--networkid 1234
:指定网络ID。1234 是自定义网络ID,用于区分不同的以太坊网络。只有相同 networkid 的节点才会互相连接。--syncmode full
:指定同步模式。full 模式表示节点将下载并验证整个区块链。--nodiscover
: 禁止节点发现其他节点。该节点将不加入到以太坊的主网络中,也不会自动发现和连接到其他节点,需要手动进行添加。--http
:启用 HTTP-RPC 服务器,允许通过 HTTP 请求与节点交互。--http.addr 0.0.0.0
:HTTP 服务器绑定的地址。0.0.0.0 表示允许任何IP地址的请求访问。--http.port 8888
:指定 HTTP 服务器的端口号为 8888。--http.api personal,admin,eth,net,web3,miner
:启用 HTTP API 接口,允许访问 personal, admin, eth, net, web3, miner 模块。--http.corsdomain "*"
:设置允许的跨域资源共享(CORS)域名。* 表示允许所有域名访问。--ws
:启用 WebSocket-RPC 服务器。--ws.api eth,web3,net
:启用 WebSocket API 接口,允许访问 eth, web3, net 模块。--ws.origins "*"
:设置 WebSocket 允许的来源。* 表示允许所有来源。--ws.addr "127.0.0.1"
:WebSocket 服务器绑定的地址。127.0.0.1 表示仅允许本地访问。--ws.port 8546
:指定 WebSocket 服务器的端口号为 8546。--mine
:启动挖矿。- –miner.threads 1:设置挖矿时使用的线程数为 1。这是CPU挖矿的线程数量。
--port 30303
:设置用于 P2P 网络的监听端口,默认是 30303。--allow-insecure-unlock
:允许在启动时解锁账户。这在启用 HTTP 或 WebSocket 时可能存在安全隐患,因此被标记为不安全。--unlock "0x36f3689a4D30fB7A98151e50ABbB37b5da52064f"
:解锁指定的以太坊账户(通过其地址),以便能够进行操作,如签署交易,该地址需要换成刚才创建的账户地址。--password password.txt
: 指定包含解锁账户密码的文件路径。Geth 会读取这个文件并使用其中的密码解锁上面设置的账户0x36f3689a4D30fB7A98151e50ABbB37b5da52064f
3.3 成员结点配置
使用相同的 genesis.json
文件启动其他节点。配置节点之间的 P2P 连接,使用 enode
地址互联
- 初始化成员结点
将nodeA的创世文件给复制到nodeB里面
cp /root/nodeA/privatenet.json /root/nodeB/
geth --datadir /root/nodeB/data init privatenet.json
- 创建账户
与之前的创建账户一样,同样需要一个password.txt
,为了方便也可以直接使用同一个密码,同样在nodeB/data/ketstore
文件下会生成一份新账户的密钥
geth account new --datadir /root/nodeB/data --password password.txt
- 启动成员节点,启动第二个结点时要注意以下几点:
- 确保每个节点的
datadir
路径不同,例如/root/nodeB/data
- 确保网络ID一致(在这个例子中为1234),以便节点可以连接到同一个私有网络
- 每个结点的端口都应该不同,以避免端口冲突
在windows系统中同一台电脑启动第二个结点可能会出现Fatal: Error starting protocol stack: Access is denied.
报错,在linux的ubuntu中没出现该情况,在windows启动命令中需要再加一个--ipcdisable
参数才可以,相关issue🚪
geth --datadir /root/nodeB/data --networkid 1234 --syncmode full --nodiscover --http --http.addr 0.0.0.0 --http.port 8889 --http.api personal,admin,eth,net,web3,miner --http.corsdomain "*" --ws --ws.api eth,web3,net --ws.origins "*" --ws.addr "127.0.0.1" --ws.port 8547 --mine --miner.threads 1 --port 30304 --allow-insecure-unlock --unlock "0x9888A379998147f65F478D98a2E09d29a39b7038" --password password.txt --authrpc.port 8552
3.4 连接两个结点
对两个刚才启动的窗口再开一个额外的界面,在nodeA和nodeB中输入以下命令即可打开geth控制台
geth attach geth.ipc
3.4.1 获取引导结点的Enode信息
首先,需要获取第一个节点的Enode地址,这是一个唯一标识节点的字符串,在Geth控制台中输入以下命令:
admin.nodeInfo.enode
它会返回类似以下格式的字符串:
enode://<node-id>@<ip>:<port>?discport=<port>
其中:
<node_id>
是节点的唯一标识符。<ip>
是第一个节点的 IP 地址。30303
是 Geth 设置的默认 P2P 端口。
3.4.2 连接成员结点到引导结点
在第二个节点的geth控制台中,将第一个节点的Enode信息替换到admin.addPeer()
中,输入以下命令将第二个节点连接到第一个节点,使第二个节点成为第一个节点的对等节点
admin.addPeer("enode://<node-id>@<ip>:<port>?discport=<port>")
通常情况下,只需要成员节点连接到引导节点即可。引导节点不需要主动连接到成员节点。一旦成员节点连接到引导节点,网络中的其他节点也可以通过引导节点发现该成员节点。
- 一台电脑上连接结点
在上面admin.addPeer
命令中<ip>
地址设置127.0.0.1
,也就是本地回环地址,例如:
admin.addPeer("enode://8d27d6c3d8be61ef0ad1eeed258ef6b156f287125df96f554d349f2ce50eb5b2b6d2a07148668ee3af364ad7c0192fec04f5d2f6fe3782e58943c6efcfc460b1@127.0.0.1:30303?discport=0")
- 多台电脑上连接结点
如果你的两台主机是在同一个局域网内,那么使用局域网地址是可以的。但如果这两台主机处于不同的网络环境下,例如在不同的地理位置或通过互联网相连,那么你需要使用公网地址来实现互联。
- 局域网:
在每台主机上,运行ifconfig
(Linux/macOS)或ipconfig
(Windows)命令来获取局域网(LAN) IP 地址
得到局域网地址为192.168.0.9,在成员结点连接从127.0.0.1换为局域网地址
admin.addPeer("enode://<node_id>@192.168.1.9:30303")
- 公网:
你可以直接访问获取公网ip地址网站🚪获取或者服务器终端上使用curl
命令获取公网ip:
curl icanhazip.com
在建立连接之前确保能够访问到公网ip下的30303端口,可以看到局域网的30303端口是可以访问到,而公网ip可以访问到,但是30303端口访问不到,这是因为存在NAT网络地址转换,由于主机是在内网中,直接用公网ip+端口号
访问不到自己的电脑,要在路由器上做端口映射才能让服务器访问到自己的电脑
NAT(网络地址转换):大多数家庭和公司网络使用 NAT,多个设备共享一个公网 IP 地址。NAT 会阻止外部的访问请求直接到达内网设备,除非配置了端口映射(Port Forwarding)。
虚拟映射(端口映射):通过路由器的端口映射功能,你可以将某个外部端口的请求映射到局域网内设备的特定端口。这样,外部用户通过访问你的公网 IP 和指定的端口号,就可以访问到内网的服务器。
端口映射方法:首先登录到你网络的路由器管理界面🚪,在路由器管理界面中,找到端口转发(Port Forwarding)或虚拟服务器(Virtual Server)的设置选项,添加映射规则为外部端口:30303(公网 IP 访问的端口),内部 IP:192.168.0.9(你的 Geth 服务器的局域网 IP),内部端口:30303(Geth 使用的端口),具体教程🚪
最后在成员结点中将ip地址换为公网ip
admin.addPeer("enode://<node_id>@116.234.145.41:30303")
3.4.3 验证连接
要验证两个节点是否成功连接,可以在任一节点上运行以下命令:
- 这个命令会返回一个列表,显示当前节点已连接的所有对等节点的详细信息。如果看到另一个节点的详细信息,说明它们已经成功连接。
admin.peers
- 这个命令会返回当前节点的对等节点(peers)数量。如果两个节点连接成功,这个值应该大于 0。
net.peerCount
3.4.4 同步和挖矿
当两个节点连接后,它们会开始同步区块链数据,并且可以一起参与挖矿。你可以在两个节点上运行以下命令来检查挖矿和同步状态:
eth.syncing
eth.mining
这两个命令可以帮助你确保节点正在同步区块数据并且正在进行挖矿
总结
通过本文,我们详细介绍了如何在Geth环境中搭建一个P2P多节点的以太坊私链网络,并深入探讨了P2P多节点模式在开发和测试中的重要性。文章从Geth客户端的下载与配置开始,逐步讲解了私链的配置、多个节点的创建以及节点之间的连接。我们还阐述了P2P多节点模式在模拟真实以太坊网络环境中的优势,并提供了实际操作步骤和代码示例。希望这篇文章能帮助你更好地理解和使用P2P多节点以太坊网络。如果你有任何疑问或建议,欢迎在评论区留言讨论🌹
这篇关于如何在Geth中搭建P2P多节点以太坊私链:详细教程与实操步骤的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!