本文主要针对platon网络,依据部分代码片段+部分网络资料做简略分析,仅限于个人理解,不代表真实网络构成。
platon网络部分我主要分四个模块来解析
1、底层p2p网络
2、引导网络bootnode
3、网络标识networkid
4、链标识chainid
一、底层p2p网络
1. platon特色之链上链下分工
PlatON网络严格来说并不是一条区块链,而是一个由链上+链下部分组成的分工网络。链上部分,负责执行区块链共识算法,记账和验证。
而链下部分则是一个P2P网络,又称对等网络,即对等计算机网络,是一种在对等者(Peer)之间分配任务和工作负载的分布式应用架构,是对等计算模型在应用层形成的一种组网或网络形式。“Peer”在英语里有“对等者、伙伴、对端”的意义。因此,从字面上,P2P可以理解为对等计算或对等网络。国内一些媒体将P2P翻译成“点对点”或者“端对端”,学术界则统一称为对等网络(Peer-to-peer networking)或对等计算(Peer-to-peer computing)。
在 p2p 通信链路的建立过程中,第一步就是协商共享密钥,该小节说明下密钥的生成过程。
迪菲-赫尔曼密钥交换
p2p 网络中使用到的是「迪菲-赫尔曼密钥交换」技术[1]。迪菲-赫尔曼密钥交换(英语:Diffie–Hellman key exchange,缩写为D-H) 是一种安全协议。它可以让双方在完全没有对方任何预先信息的条件下通过不安全信道创建起一个密钥。
简单来说,链接的两方生成随机的私钥,通过随机的私钥得到公钥。然后双方交换各自的公钥,这样双方都可以通过自己随机的私钥和对方的公钥来生成一个同样的共享密钥(shared-secret)。后续的通讯使用这个共享密钥作为对称加密算法的密钥。其中对于 A、B公私钥对满足这样的数学等式:ECDH(A私钥, B公钥) == ECDH(B私钥, A公钥)。
共享密钥生成
在 p2p 网络中由 doEncHandshake() 方法完成密钥的交换和共享密钥的生成工作
部分代码url:https://github.com/PlatONnetwork/PlatON-Go/blob/master/p2p/peer.go
[./p2p/rlpx.go]
func (t *rlpx) doEncHandshake(prv *ecdsa.PrivateKey, dial *discover.Node) (discover.NodeID, error) {
...
if dial == nil {
sec, err = receiverEncHandshake(t.fd, prv, nil)
} else {
sec, err = initiatorEncHandshake(t.fd, prv, dial.ID, nil)
}
...
t.rw = newRLPXFrameRW(t.fd, sec)
..
}
如果作为服务端监听连接,收到新连接后调用 receiverEncHandshake() 函数,若作为客户端向服务端发起请求,则调用 initiatorEncHandshake()函数;两个函数区别不大,都将交换密钥,并生成共享密钥,initiatorEncHandshake() 仅仅是作为发起数据的一端;最终执行完后,调用 newRLPXFrameRW() 创建帧处理器。
链上链下分工的好处是,将计算与块信息的验证这两个任务相分离,链下计算使区块链的工作量得以降低,因此可以使PlatON的链上工作负担相对较小,因此实现PlatON区块链的提速。
2. 链上分工
相较于以太坊在上线数年以后才进行分片,PlatON链上直接进行分片。使用分片技术,PlatON区块链形成一个主链+多个应用链的区块链系统。每条应用链对就着一个类型的服务。
分片技术可以使PlatON区块链的性能获得进一步的提升,而分工的应用链,具有更专业化、更高效率的特点。
在此基础上,主链或应用链上,节点同样进行分工:轻节点只保存区块头信息和自己相关的数据;全节点则是负责保存所有的区块数据;共识节点则是负责出块,也就是把交易数据打包成区块。
3. 链下分工
PlatON链下部分,主要负责执行计算。链下部分是一个分布式P2P网络,网络节点包含3种分工,分别是路由节点、计算节点和数据节点。
优势
计算节点负责执行计算任务;数据节点负责提供计算所需的数据,类似于预言机;路由节点可以部署在私有网络内,负责执行路由任务、执行通讯。
实例
假如某银行私有网络中部署了一个路由节点,银行需要在PlatON网络中执行换汇交易,用美元兑换人民币:
首先,该路由节点收到银行网络的请求以后,将请求发布到PlatON网络中。
其次,数据节点负责获取美元与人民币的汇率数据,然后将数据返回给计算节点。
再次,计算节点根据银行请求,计算兑换的人民币、美元的数量。
最后,PlatON区块链在该服务相应的应用链上,共识节点将此交易数据打包,并进行广播,全节点验证数据后将数据写入区块。
在此过程中,一方面,各种节点各司其职,因此可以形成较高的效率。另一方面,不同职能节点可以因分工需要配置专业化的硬件。共识节点配置大容量存储和高性能处理器,全节点着重配置大容量存储,计算节点着重配置高性能处理器等。
二、引导网络bootnode
对于bootnode,以太坊的解释是“Stripped down version of our Ethereum client implementation that only takes part in the network node discovery protocol, but does not run any of the higher level application protocols. It can be used as a lightweight bootstrap node to aid in finding peers in private networks.”
引导网络bootnode,只是做一个连接节点的基本功能,只是做节点发现不做其他的验证或更高层的应用协议。每个node被enode唯一标识,enode identifier来源一个Key。以太坊节点启动时需要告知至少一个节点才可以接入整个以太坊网络。bootNode相当于一个第三方的中介,node在启动时会将自己的信息注册到BootNode的路由中,并且会从bootNode得到其他节点的路由信息,一旦有了对等信息后就不需要连接到bootNode。
platon在启动时需要告之至少一个对等节点,这样才能接入整个以太坊网络,bootnode相当于一个第三方的中介,node在启动时会将自己的信息注册到bootnode的路由中,并且会从bootnode得到其它节点的路由信息,一旦有了对等节点信息后就可以不需要连接bootnode。公有链的节点硬编码了一些bootnode节点地址。
三、网络标识networkid
NetworkId 主要用来在网络层标识当前的区块链网络。NetworkId 不一致的两个节点无法建立连接。这就有效避免了不通网络间通信,影响数据,同时便于区分不同链,比如区分测试网主网等。
NetworkId 无法通过配置文件指定,智能通过参数 --networkid 来指定。所以我们启动自己私链节点上需要记得加上这个参数。如果不加这个参数也不指定网络类型,默认 NetworkId 的值和platon主网一致。
写到networkid,我顺带写下节点连接过程,包括enode
该实例定义了消息的加解密和编解码处理,连接过程如下。
1)每个连接首先进行2次握手,握手过程进行加密验证。
2)生成 enode 地址。
3)通过 channel: posthandshake 通知 p2p.Server 进行本次连接有效性检查,过程如下。
如果不是静态节点或信任节点,并且超过最大 peer 连接数,则拒绝本次连接。
如果不是信任节点,但是是邻居主动请求连接的节点,则在超过邻居请求连接数量时,拒绝本次连接。
如果是重复连接或者是自身节点环回连接,则直接拒绝。
4)进行transport层的握手,发送一个RLP编码的消息,消息code是handshake-Msg(0x00)。
5)通过channel:addpeer进行添加Peer的操作,即创建一个Peer实例。
6)运行该实例,即Peer.run(),具体如下。
启动接收peer消息的监听服务。
启动定时发送ping保活消息。
运行Peer中注册的Protocol,即Protocol.Run(...)。
在协议层进行握手。向peer发送本地节点信息(协议版本号、网络ID、链总难度值、当前区块头、创世块数据),消息code为StatusMsg。
等待peer回复对端的StatusMsg,检查与本节点是否匹配。
通过newPeerCh通道通知protocolManager检查peer的区块高度,如果peer的最新高度比当前节点高,那么同步最新的区块到本地,然后向给本节点所有的peer广播最新的区块Hash
四、链标识chainid
ChainId 是EIP-155引入的一个用来区分不同 EVM 链的一个标识。如下图所示,主要作用就是避免一个交易在签名之后被重复在不同的链上提交。最开始主要是为了防止以太坊交易在以太经典网络上重放或者以太经典交易在以太坊网络上重放。在以太坊网络上是从 2675000 这个区块通过 Spurious Dragon 这个硬分叉升级激活。然后platon一开始就采用了chainid做为标示,有效避免了网络分叉。
可能有人会问,既然已经使用了networkid做标示,为啥又采用好了chainid呢?
这正是platon网络设计的巧妙优势,ChainId 是用来防止交易在不同的以太坊同构网络进行交易重放的。主要在交易签名和验证的时候使用。NetworkId 是用来标识区块链网络的。主要在节点之间握手并相互检验的时候使用。ChainId 需要在 genesis 文件中指定,NetworkId 需要在启动参数中指定。ChainId 和 NetworkId 的值不需要相同。
写在最后
PlatON是一个非常复杂的网络系统,其技术特色有很多,本人仅从中选出自己认为四个重要的、意义重大的特色进行解读。
区块链的两个弱势就是效率问题和隐私保护问题。PlatOn这种链上链下分工,将区块链验证和计算两种工作分工,可以减少区块链的工作负担,在一定程度上提升效率。而计算过程使用多方计算,以及全同态加密,可以保护用户隐私,可以说对区块链技术的应用具有一定的启发。
参考文章:https://baike.baidu.com/item/%E5%AF%B9%E7%AD%89%E7%BD%91%E7%BB%9C/5482934?fromtitle=P2P%E7%BD%91%E7%BB%9C&fromid=23162373&fr=aladdin
https://www.jinse.com/news/blockchain/988262.html
Discord 开发者社群: https://discord.com/invite/jAjFzJ3Cff
公众号: