本文主要針對(duì)platon網(wǎng)絡(luò)存璃,依據(jù)部分代碼片段+部分網(wǎng)絡(luò)資料做簡(jiǎn)略分析驱证,僅限于個(gè)人理解撑毛,不代表真實(shí)網(wǎng)絡(luò)構(gòu)成牙躺。
platon網(wǎng)絡(luò)部分我主要分四個(gè)模塊來(lái)解析
1愁憔、底層p2p網(wǎng)絡(luò)
2、引導(dǎo)網(wǎng)絡(luò)bootnode
3孽拷、網(wǎng)絡(luò)標(biāo)識(shí)networkid
4吨掌、鏈標(biāo)識(shí)chainid
一、底層p2p網(wǎng)絡(luò)
1. platon特色之鏈上鏈下分工
PlatON網(wǎng)絡(luò)嚴(yán)格來(lái)說(shuō)并不是一條區(qū)塊鏈,而是一個(gè)由鏈上+鏈下部分組成的分工網(wǎng)絡(luò)膜宋。鏈上部分窿侈,負(fù)責(zé)執(zhí)行區(qū)塊鏈共識(shí)算法,記賬和驗(yàn)證秋茫。
而鏈下部分則是一個(gè)P2P網(wǎng)絡(luò)史简,又稱(chēng)對(duì)等網(wǎng)絡(luò),即對(duì)等計(jì)算機(jī)網(wǎng)絡(luò)肛著,是一種在對(duì)等者(Peer)之間分配任務(wù)和工作負(fù)載的分布式應(yīng)用架構(gòu)圆兵,是對(duì)等計(jì)算模型在應(yīng)用層形成的一種組網(wǎng)或網(wǎng)絡(luò)形式∈嗷撸“Peer”在英語(yǔ)里有“對(duì)等者殉农、伙伴、對(duì)端”的意義局荚。因此超凳,從字面上,P2P可以理解為對(duì)等計(jì)算或?qū)Φ染W(wǎng)絡(luò)耀态。國(guó)內(nèi)一些媒體將P2P翻譯成“點(diǎn)對(duì)點(diǎn)”或者“端對(duì)端”轮傍,學(xué)術(shù)界則統(tǒng)一稱(chēng)為對(duì)等網(wǎng)絡(luò)(Peer-to-peer networking)或?qū)Φ扔?jì)算(Peer-to-peer computing)。
在 p2p 通信鏈路的建立過(guò)程中首装,第一步就是協(xié)商共享密鑰创夜,該小節(jié)說(shuō)明下密鑰的生成過(guò)程。
迪菲-赫爾曼密鑰交換
p2p 網(wǎng)絡(luò)中使用到的是「迪菲-赫爾曼密鑰交換」技術(shù)[1]簿盅。迪菲-赫爾曼密鑰交換(英語(yǔ):Diffie–Hellman key exchange挥下,縮寫(xiě)為D-H) 是一種安全協(xié)議。它可以讓雙方在完全沒(méi)有對(duì)方任何預(yù)先信息的條件下通過(guò)不安全信道創(chuàng)建起一個(gè)密鑰桨醋。
簡(jiǎn)單來(lái)說(shuō)棚瘟,鏈接的兩方生成隨機(jī)的私鑰,通過(guò)隨機(jī)的私鑰得到公鑰喜最。然后雙方交換各自的公鑰偎蘸,這樣雙方都可以通過(guò)自己隨機(jī)的私鑰和對(duì)方的公鑰來(lái)生成一個(gè)同樣的共享密鑰(shared-secret)。后續(xù)的通訊使用這個(gè)共享密鑰作為對(duì)稱(chēng)加密算法的密鑰瞬内。其中對(duì)于 A迷雪、B公私鑰對(duì)滿(mǎn)足這樣的數(shù)學(xué)等式:ECDH(A私鑰, B公鑰) == ECDH(B私鑰, A公鑰)。
共享密鑰生成
在 p2p 網(wǎng)絡(luò)中由 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)
? ? ..
}
如果作為服務(wù)端監(jiān)聽(tīng)連接虫蝶,收到新連接后調(diào)用 receiverEncHandshake() 函數(shù)章咧,若作為客戶(hù)端向服務(wù)端發(fā)起請(qǐng)求,則調(diào)用 initiatorEncHandshake()函數(shù)能真;兩個(gè)函數(shù)區(qū)別不大赁严,都將交換密鑰扰柠,并生成共享密鑰,initiatorEncHandshake() 僅僅是作為發(fā)起數(shù)據(jù)的一端疼约;最終執(zhí)行完后卤档,調(diào)用 newRLPXFrameRW() 創(chuàng)建幀處理器。
鏈上鏈下分工的好處是程剥,將計(jì)算與塊信息的驗(yàn)證這兩個(gè)任務(wù)相分離劝枣,鏈下計(jì)算使區(qū)塊鏈的工作量得以降低,因此可以使PlatON的鏈上工作負(fù)擔(dān)相對(duì)較小织鲸,因此實(shí)現(xiàn)PlatON區(qū)塊鏈的提速舔腾。
2. 鏈上分工
相較于以太坊在上線(xiàn)數(shù)年以后才進(jìn)行分片,PlatON鏈上直接進(jìn)行分片昙沦。使用分片技術(shù)琢唾,PlatON區(qū)塊鏈形成一個(gè)主鏈+多個(gè)應(yīng)用鏈的區(qū)塊鏈系統(tǒng)载荔。每條應(yīng)用鏈對(duì)就著一個(gè)類(lèi)型的服務(wù)盾饮。
分片技術(shù)可以使PlatON區(qū)塊鏈的性能獲得進(jìn)一步的提升,而分工的應(yīng)用鏈懒熙,具有更專(zhuān)業(yè)化丘损、更高效率的特點(diǎn)。
在此基礎(chǔ)上工扎,主鏈或應(yīng)用鏈上徘钥,節(jié)點(diǎn)同樣進(jìn)行分工:輕節(jié)點(diǎn)只保存區(qū)塊頭信息和自己相關(guān)的數(shù)據(jù);全節(jié)點(diǎn)則是負(fù)責(zé)保存所有的區(qū)塊數(shù)據(jù)肢娘;共識(shí)節(jié)點(diǎn)則是負(fù)責(zé)出塊呈础,也就是把交易數(shù)據(jù)打包成區(qū)塊。
3. 鏈下分工
PlatON鏈下部分橱健,主要負(fù)責(zé)執(zhí)行計(jì)算而钞。鏈下部分是一個(gè)分布式P2P網(wǎng)絡(luò),網(wǎng)絡(luò)節(jié)點(diǎn)包含3種分工拘荡,分別是路由節(jié)點(diǎn)臼节、計(jì)算節(jié)點(diǎn)和數(shù)據(jù)節(jié)點(diǎn)。
優(yōu)勢(shì)
計(jì)算節(jié)點(diǎn)負(fù)責(zé)執(zhí)行計(jì)算任務(wù)珊皿;數(shù)據(jù)節(jié)點(diǎn)負(fù)責(zé)提供計(jì)算所需的數(shù)據(jù)网缝,類(lèi)似于預(yù)言機(jī);路由節(jié)點(diǎn)可以部署在私有網(wǎng)絡(luò)內(nèi)蟋定,負(fù)責(zé)執(zhí)行路由任務(wù)粉臊、執(zhí)行通訊。
實(shí)例
假如某銀行私有網(wǎng)絡(luò)中部署了一個(gè)路由節(jié)點(diǎn)驶兜,銀行需要在PlatON網(wǎng)絡(luò)中執(zhí)行換匯交易扼仲,用美元兌換人民幣:
首先果元,該路由節(jié)點(diǎn)收到銀行網(wǎng)絡(luò)的請(qǐng)求以后,將請(qǐng)求發(fā)布到PlatON網(wǎng)絡(luò)中犀盟。
其次而晒,數(shù)據(jù)節(jié)點(diǎn)負(fù)責(zé)獲取美元與人民幣的匯率數(shù)據(jù),然后將數(shù)據(jù)返回給計(jì)算節(jié)點(diǎn)阅畴。
再次倡怎,計(jì)算節(jié)點(diǎn)根據(jù)銀行請(qǐng)求,計(jì)算兌換的人民幣贱枣、美元的數(shù)量监署。
最后,PlatON區(qū)塊鏈在該服務(wù)相應(yīng)的應(yīng)用鏈上纽哥,共識(shí)節(jié)點(diǎn)將此交易數(shù)據(jù)打包钠乏,并進(jìn)行廣播,全節(jié)點(diǎn)驗(yàn)證數(shù)據(jù)后將數(shù)據(jù)寫(xiě)入?yún)^(qū)塊春塌。
在此過(guò)程中晓避,一方面,各種節(jié)點(diǎn)各司其職只壳,因此可以形成較高的效率俏拱。另一方面,不同職能節(jié)點(diǎn)可以因分工需要配置專(zhuān)業(yè)化的硬件吼句。共識(shí)節(jié)點(diǎn)配置大容量存儲(chǔ)和高性能處理器锅必,全節(jié)點(diǎn)著重配置大容量存儲(chǔ),計(jì)算節(jié)點(diǎn)著重配置高性能處理器等惕艳。
二搞隐、引導(dǎo)網(wǎng)絡(luò)bootnode
對(duì)于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.”
引導(dǎo)網(wǎng)絡(luò)bootnode远搪,只是做一個(gè)連接節(jié)點(diǎn)的基本功能劣纲,只是做節(jié)點(diǎn)發(fā)現(xiàn)不做其他的驗(yàn)證或更高層的應(yīng)用協(xié)議。每個(gè)node被enode唯一標(biāo)識(shí)终娃,enode identifier來(lái)源一個(gè)Key味廊。以太坊節(jié)點(diǎn)啟動(dòng)時(shí)需要告知至少一個(gè)節(jié)點(diǎn)才可以接入整個(gè)以太坊網(wǎng)絡(luò)。bootNode相當(dāng)于一個(gè)第三方的中介棠耕,node在啟動(dòng)時(shí)會(huì)將自己的信息注冊(cè)到BootNode的路由中余佛,并且會(huì)從bootNode得到其他節(jié)點(diǎn)的路由信息,一旦有了對(duì)等信息后就不需要連接到bootNode窍荧。
platon在啟動(dòng)時(shí)需要告之至少一個(gè)對(duì)等節(jié)點(diǎn)辉巡,這樣才能接入整個(gè)以太坊網(wǎng)絡(luò),bootnode相當(dāng)于一個(gè)第三方的中介蕊退,node在啟動(dòng)時(shí)會(huì)將自己的信息注冊(cè)到bootnode的路由中郊楣,并且會(huì)從bootnode得到其它節(jié)點(diǎn)的路由信息憔恳,一旦有了對(duì)等節(jié)點(diǎn)信息后就可以不需要連接bootnode。公有鏈的節(jié)點(diǎn)硬編碼了一些bootnode節(jié)點(diǎn)地址净蚤。
三钥组、網(wǎng)絡(luò)標(biāo)識(shí)networkid
NetworkId 主要用來(lái)在網(wǎng)絡(luò)層標(biāo)識(shí)當(dāng)前的區(qū)塊鏈網(wǎng)絡(luò)。NetworkId 不一致的兩個(gè)節(jié)點(diǎn)無(wú)法建立連接今瀑。這就有效避免了不通網(wǎng)絡(luò)間通信程梦,影響數(shù)據(jù),同時(shí)便于區(qū)分不同鏈橘荠,比如區(qū)分測(cè)試網(wǎng)主網(wǎng)等屿附。
NetworkId 無(wú)法通過(guò)配置文件指定,智能通過(guò)參數(shù) --networkid 來(lái)指定哥童。所以我們啟動(dòng)自己私鏈節(jié)點(diǎn)上需要記得加上這個(gè)參數(shù)挺份。如果不加這個(gè)參數(shù)也不指定網(wǎng)絡(luò)類(lèi)型,默認(rèn) NetworkId 的值和platon主網(wǎng)一致贮懈。
寫(xiě)到networkid匀泊,我順帶寫(xiě)下節(jié)點(diǎn)連接過(guò)程,包括enode
該實(shí)例定義了消息的加解密和編解碼處理错邦,連接過(guò)程如下探赫。
1)每個(gè)連接首先進(jìn)行2次握手型宙,握手過(guò)程進(jìn)行加密驗(yàn)證撬呢。
2)生成 enode 地址。
3)通過(guò) channel: posthandshake 通知 p2p.Server 進(jìn)行本次連接有效性檢查妆兑,過(guò)程如下魂拦。
如果不是靜態(tài)節(jié)點(diǎn)或信任節(jié)點(diǎn),并且超過(guò)最大 peer 連接數(shù)搁嗓,則拒絕本次連接芯勘。
如果不是信任節(jié)點(diǎn),但是是鄰居主動(dòng)請(qǐng)求連接的節(jié)點(diǎn)腺逛,則在超過(guò)鄰居請(qǐng)求連接數(shù)量時(shí)荷愕,拒絕本次連接。
如果是重復(fù)連接或者是自身節(jié)點(diǎn)環(huán)回連接棍矛,則直接拒絕安疗。
4)進(jìn)行transport層的握手,發(fā)送一個(gè)RLP編碼的消息够委,消息code是handshake-Msg(0x00)荐类。
5)通過(guò)channel:addpeer進(jìn)行添加Peer的操作,即創(chuàng)建一個(gè)Peer實(shí)例茁帽。
6)運(yùn)行該實(shí)例玉罐,即Peer.run()屈嗤,具體如下。
啟動(dòng)接收peer消息的監(jiān)聽(tīng)服務(wù)吊输。
啟動(dòng)定時(shí)發(fā)送ping比暮牛活消息。
運(yùn)行Peer中注冊(cè)的Protocol季蚂,即Protocol.Run(...)讨韭。
在協(xié)議層進(jìn)行握手。向peer發(fā)送本地節(jié)點(diǎn)信息(協(xié)議版本號(hào)癣蟋、網(wǎng)絡(luò)ID透硝、鏈總難度值、當(dāng)前區(qū)塊頭疯搅、創(chuàng)世塊數(shù)據(jù))濒生,消息code為StatusMsg。
等待peer回復(fù)對(duì)端的StatusMsg幔欧,檢查與本節(jié)點(diǎn)是否匹配罪治。
通過(guò)newPeerCh通道通知protocolManager檢查peer的區(qū)塊高度,如果peer的最新高度比當(dāng)前節(jié)點(diǎn)高礁蔗,那么同步最新的區(qū)塊到本地觉义,然后向給本節(jié)點(diǎn)所有的peer廣播最新的區(qū)塊Hash
四、鏈標(biāo)識(shí)chainid
ChainId 是EIP-155引入的一個(gè)用來(lái)區(qū)分不同 EVM 鏈的一個(gè)標(biāo)識(shí)浴井。如下圖所示晒骇,主要作用就是避免一個(gè)交易在簽名之后被重復(fù)在不同的鏈上提交。最開(kāi)始主要是為了防止以太坊交易在以太經(jīng)典網(wǎng)絡(luò)上重放或者以太經(jīng)典交易在以太坊網(wǎng)絡(luò)上重放磺浙。在以太坊網(wǎng)絡(luò)上是從 2675000 這個(gè)區(qū)塊通過(guò) Spurious Dragon 這個(gè)硬分叉升級(jí)激活洪囤。然后platon一開(kāi)始就采用了chainid做為標(biāo)示,有效避免了網(wǎng)絡(luò)分叉撕氧。
可能有人會(huì)問(wèn)瘤缩,既然已經(jīng)使用了networkid做標(biāo)示,為啥又采用好了chainid呢伦泥?
這正是platon網(wǎng)絡(luò)設(shè)計(jì)的巧妙優(yōu)勢(shì),ChainId 是用來(lái)防止交易在不同的以太坊同構(gòu)網(wǎng)絡(luò)進(jìn)行交易重放的。主要在交易簽名和驗(yàn)證的時(shí)候使用富腊。NetworkId 是用來(lái)標(biāo)識(shí)區(qū)塊鏈網(wǎng)絡(luò)的。主要在節(jié)點(diǎn)之間握手并相互檢驗(yàn)的時(shí)候使用。ChainId 需要在 genesis 文件中指定,NetworkId 需要在啟動(dòng)參數(shù)中指定易迹。ChainId 和 NetworkId 的值不需要相同。
寫(xiě)在最后
PlatON是一個(gè)非常復(fù)雜的網(wǎng)絡(luò)系統(tǒng),其技術(shù)特色有很多,本人僅從中選出自己認(rèn)為四個(gè)重要的蔚出、意義重大的特色進(jìn)行解讀岔乔。
區(qū)塊鏈的兩個(gè)弱勢(shì)就是效率問(wèn)題和隱私保護(hù)問(wèn)題掸掏。PlatOn這種鏈上鏈下分工,將區(qū)塊鏈驗(yàn)證和計(jì)算兩種工作分工靴患,可以減少區(qū)塊鏈的工作負(fù)擔(dān),在一定程度上提升效率。而計(jì)算過(guò)程使用多方計(jì)算囱挑,以及全同態(tài)加密盛末,可以保護(hù)用戶(hù)隱私,可以說(shuō)對(duì)區(qū)塊鏈技術(shù)的應(yīng)用具有一定的啟發(fā)助泽。
參考文章: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 開(kāi)發(fā)者社群:? ? https://discord.com/invite/jAjFzJ3Cff
公眾號(hào):