P2P做爲區塊鏈網絡中去中心化的標識
P2P全稱對等式網絡(peer-to-peer),又稱點對點技術,是無中心服務器、依靠用戶羣(peers)交換信息的互聯網體系;與有中心服務器的中央網絡系統不一樣,對等網絡的每一個用戶端既是一個節點,也有服務器的功能,任何一個節點沒法直接找到其餘節點,必須依靠其戶羣進行信息交流。
優點node
- 可在網絡的中央及邊緣區域共享內容和資源。在客戶端/服務器網絡中,一般只能在網絡的中央區域共享內
- 由對等方組成的網絡易於擴展,並且比單臺服務器更加可靠。單臺服務器會受制於單點故障,或者會在網絡使用率偏高時,形爲瓶頸。
- 由對等方組成的網絡可共享處理器,整合計算資源以執行分佈式計算任務,而不僅是單純依賴一臺計算機,如一臺超級計算機。
- 用戶可直接訪問對等計算機上的共享資源。網絡中的對等方可直接在本地存儲器上共享文件,而沒必要在中央服務器上進行共享。
p2p網絡的三個特性安全
- 離散性:構成系統的節點並無任何中央式的協調機制。
- 伸縮性:即便有成千上萬個節點,系統仍然應該十分有效率。
- 容錯性:即便節點不斷地加入、離開或是中止工做,系統仍然必須達到必定的可靠度。
上面介紹P2P的時候說過,他是無中心服務器的,中心服務器就意味着,當受到攻擊的時候,中心服務器一旦宕機,整個網絡和服務就會出現問題。而P2P網絡的優點在於,每一個節點既是客戶端又是服務端,因此當受到攻擊時,任何一臺機器垮掉,也不會影響總體的服務。
區塊鏈的核心是去中心化,這和P2P網絡的觀念不約而同,因此選擇P2P的理由也就很充分。
首先看一下P2P的總體技術點:服務器
以上三點解決以後,基本就能夠實現一個簡單的P2P網絡。若是想要實現一個比較完整的P2P網絡,固然還有不少的細節須要考慮,好比說,節點發現協議,快速定位節點,安全性,節點的加入和退出機制,節點的心跳保活等。咱們主要介紹的是DHT分佈式哈希表的知識點;網絡
比特幣、以太坊、超級帳本和EOS都使用了DHT的具體實現;分佈式
鏈類型 | 使用的P2P協議 |
---|---|
區塊鏈 | Gossip協議 |
超級帳本 | Gossip協議 |
以太坊 | Kademlia協議 |
EOS | 本身實現的P2P協議 (待研究) |
比特幣學習
- 節點發現
新節點啓動後,想要參與協同運做,必須發現其餘的比特幣節點,也就是至少須要發現一個比特幣網絡中的節點,並創建聯繫。新節點找到對等體的方法:
- 種子節點:使用多個DNS服務器(比特幣節點專用)來解析比特幣節點的IP。
- 節點引薦:若是不知道DNS,則必須知道至少一個比特幣節點的IP。區塊鏈
- 節點連接
節點向peer節點發送version消息開始握手,peer節點須要檢驗版本,祕鑰等數據,驗證經過,會返回verack消息。
握手消息完成,節點發送包含本身IP地址和addr的消息給peer節點,對等節點收到,繼續向它的對等節點發出addr消息,這樣新節點的IP地址就會在P2P網絡中廣播出去(Gossip協議的Rumor-Mongering);由於網絡中,節點能夠隨時加入和離開,因此全部的節點必須在一個節點退出的時候,尋找新節點,而且在其餘節點啓動的時候,對其進行幫組。線程
超級帳本
以太坊
以太坊使用的是kademlia協議,簡稱Kad協議,具體的Kad協議在其餘的文章中介紹。本文咱們只須要知道Kad使用UDP進行節點間消息通訊,每一個節點根據與鄰居節點距離之間的距離(NodeID的差距),分別放到不一樣的桶(bucket)中,且有4種消息ip
- ping - 用於探測其餘節點是否還存在
- store - 接收者受到後,將信息中key/value對存儲在本節點
- findnode - 接受者向發送者返回 k 個它知道的與目標結點距離最近的節點
- findvalue - 和findnode 差很少,區別是若是接收者本地存在與目標結點對應的value,那麼就回復這個值給發送者。
以太坊中的P2P網絡是比較完整的,很值得學習,有發現、子協議和Nat映射等模塊。咱們主要講解的是發現模塊;
總體結構:資源
結構名 做用 Server 本地客戶端服務 Node 節點的信息 table 存儲peer節點的結構 udp 底層節點的通信協議 Server
當本地啓動一個客戶端,並配置好靜態peer節點的配置信息以後,啓動的Server會進行三個操做
- 主動發現鄰居
- ECDH密鑰創建,確認身份並進行身份驗證
- 連接已經創建,確認生層交換協議,並運行這些協議
Node
Node節點惟一的表示網絡中的一個以太坊節點,而且Node節點有以下的信息:
- IP地址
- 鏈接使用的UDP/TCP端口號
- ID:以太坊網絡中惟一標識一個節點,本質上是一個橢圓曲線公鑰(PublicKey),與Server的PrivateKey對應。一個節點的IP地址不必定是固定的,但ID是惟一的。
- 用於節點間的距離計算的sha
table
Table主要用來管理與本節點與其餘節點的鏈接的創建更新刪除:
- bucket - 全部peer按與本節點的距離遠近放在不一樣的桶(bucket)中
- refreshReq - 更新Table請求通道
Table會循環的監控並對peer節點進行刷新
- 定時(30s)啓動Peer刷新過程的定時器
- 接收其餘線程投遞到Table的刷新Peer鏈接的通知,當收到該通知時啓動更新
- 定時從新檢查以鏈接節點的有效性的定時器
udp
udp的底層接受數據包循環,負責接收其餘節點的packet,並將解析後的信息交給另外一個循環處理,這個循環處理負責控制消息的向上遞交和收發控制
節點發現的流程:
鄰居初始化
- 當一個節點啓動後,它會首先向配置的靜態節點發起鏈接,發起鏈接的過程稱爲Dial,此時的Dial須要知道IP地址,若是不知道須要有一個解析IP的過程(根據ID來解析)
創建鏈接,下面兩個都成功則加入table中:
- 祕鑰連接和確認
- 上層協議確認
探活檢測(Revalidate)
- 有效性檢測就是利用ping消息進行探活操做。Table啓動了一個定時器(0~10s),按期隨機選擇一個bucket,向其末尾的節點發送ping消息,若是對方迴應了pong,則探活成功。
更新鄰居關係
- 按期(定時器超時)或不按期(收到refreshReq)地進行更新鄰居關係(發現新鄰居),二者都調用doRefresh()方法,該方法對在網絡上查找離自身和三個隨機節點最近的若干個節點。
EOS