區塊鏈100講:詳解區塊鏈之P2P網絡

image

1

P2P網絡

若是咱們簡單來看 P2P 技術,它的應用領域已經很是普遍了,從流媒體到點對點通信、從文件共享到協同處理,多種領域都有它的身影出現。node

一樣的,P2P 的網絡協議也有不少,比較常見的有 BitTorrent、ED2K、Gnutella、Tor 等,也就是咱們常說的 BT 工具和電驢。算法

比特幣、以太坊等衆多數字貨幣都實現了屬於本身的 P2P 網絡協議,可是這種模式並不一樣於以上討論的 P2P 網絡協議,因此本講重點主要是區塊鏈技術的 P2P 技術,也就是比特幣和以太坊的 P2P 網絡。網絡

2

網絡鏈接與拓撲結構

1. 網絡鏈接tcp

除去少數支持 UDP 協議的區塊鏈項目外,絕大部分的區塊鏈項目所使用的底層網絡協議依然是 TCP/IP 協議。分佈式

因此從網絡協議的角度來看,區塊鏈實際上是基於 TCP/IP 網絡協議的,這與 HTTP 協議、SMTP 協議是處在同一層,也就是應用層。工具

在「區塊鏈的常見誤區」這篇文章中,咱們提到了「區塊鏈是否會顛覆互聯網」這一說法,若是要是認真分析的話,它顛覆的層面其實最多隻到 HTTP 協議,不能再多了。區塊鏈

以 HTTP 協議爲表明的、與服務端的交互模式在區塊鏈上被完全打破了,變動爲徹底的點對點拓撲結構,這也是以太坊提出的 Web3.0 的由來。編碼

比特幣的 P2P 網絡是一個很是複雜的結構,考慮到礦池內部的挖礦交互協議與輕節點。咱們僅僅討論全節點這種場景下的 P2P 網絡發現與路由。加密

比特幣的 P2P 網絡基於 TCP 構建,主網默認通訊端口爲 8333。操作系統

以太坊的 P2P 網絡則與比特幣不太相同,以太坊 P2P 網絡是一個徹底加密的網絡,提供 UDP 和 TCP 兩種鏈接方式,主網默認 TCP 通訊端口是 30303,推薦的 UDP 發現端口爲 30301。

2. 拓撲結構

P2P 網絡拓撲結構有不少種,有些是中心化拓撲,有些是半中心化拓撲,有些是全分佈式拓撲結構。

比特幣全節點組成的網絡是一種全分佈式的拓撲結構,節點與節點之間的傳輸過程更接近「泛洪算法」,即:交易從某個節點產生,接着廣播到臨近節點,臨近節點一傳十十傳百,直至傳播到全網。

image

全節點與 SPV 簡化支付驗證客戶端之間的交互模式,更接近半中心化的拓撲結構,也就是 SPV 節點能夠隨機選擇一個全節點進行鏈接,這個全節點會成爲 SPV 節點的代理,幫助 SPV 節點廣播交易。

3

節點發現

節點發現是任何區塊鏈節點接入區塊鏈 P2P 網絡的第一步。 這與你孤身一人去陌生地方旅遊同樣,若是沒有地圖和導航,那你只能拽附近的人問路,「拽附近的人問路」的這個動做就能夠理解成節點發現。

節點發現可分爲初始節點發現,和啓動後節點發現。初始節點發現就是說你的全節點是剛下載的,第一次運行,什麼節點數據都沒有。啓動後發現表示正在運行的錢包已經能跟隨網絡動態維護可用節點。

1. 初始節點發現

在比特幣網絡中,初始節點發現一共有兩種方式。

第一種叫作 DNS-seed,又稱 DNS 種子節點,DNS 就是中心化域名查詢服務,比特幣的社區維護者會維護一些域名。

好比 seed.bitcoin.sipa.be 這個域名就是由比特幣的核心開發者 Sipa 維護的,若是咱們經過 nslookup 會發現大約二十多個 A 紀錄的 IPv4 主機地址。

咱們經過 nc 命令嘗試鏈接域名下的某個主機的 8333 端口會發現鏈接成功,運行結構以下。

$ nc -nvv 149.202.179.35 8333found 0 associations
found 1 connections:
     1: flags=82<CONNECTED,PREFERRED>
 outif en0
 src 192.168.1.104 port 62125
 dst 149.202.179.35 port 8333
 rank info not available
 TCP aux info available
Connection to 149.202.179.35 port 8333 [tcp/*] succeeded!

第二種方式就是,代碼中硬編碼( hard-code )了一些地址,這些地址咱們稱之爲種子節點(seed-node),當全部的種子節點所有失效時,全節點會嘗試鏈接這些種子節點。

用在以太坊中,思路也大體相同,也是在代碼中硬編碼(hard-code)了一些種子節點作相似的工做。

2. 啓動後節點發現

在 Bitcoin 的網絡中,一個節點能夠將本身維護的對等節點列表 (peer list) 發送給臨近節點,因此在初始節點發現以後,你的節點要作的第一件事情就是向對方要列表:「快把你的節點列表給我複製一份。」

因此在每次須要發送協議消息的時候,它會花費固定的時間嘗試和已存的節點列表中的節點創建連接,若是有任何一個節點在超時以前能夠鏈接上,就不用去 DNS seed 獲取地址,通常來講,這種可能性很小,尤爲是全節點數目很是多的狀況下。

而在以太坊網絡中,也會維護相似的一個節點列表 (NodeTable),可是這個節點列表與比特幣的簡單維護不一樣,它採用了 P2P 網絡協議中一個成熟的算法,叫作 Kademlia 網絡,簡稱 KAD 網絡。

它使用了 DHT 來定位資源,全稱 Distributed Hash Table,中文名爲分佈式哈希表。KAD 網絡會維護一個路由表,用於快速定位目標節點。因爲 KAD 網絡基於 UDP 通訊協議,因此以太坊節點的節點發現是基於 UDP 的,若是找到節點之後,數據交互又會切換到 TCP 協議上。

3. 黑名單與長鏈接

公有區塊鏈面臨的網絡環境是很是開放的,任何人只要下載好錢包,打開運行就進入了這個 P2P 網絡,這也會帶來被攻擊的可能。

因此在比特幣的代碼中,會有一段去控制邏輯,你能夠手動將你認爲可疑的節點移除並加入禁止列表,同時去配置可信的節點。固然,以上並不屬於客戶端的標準協議的一部分,任何人均可以實現屬於本身的 P2P 網絡層。

以太坊上有針對帳戶進行的黑名單處理,可是這屬於業務層。我沒有找到很詳盡的資料,因此你有興趣的話,能夠本身嘗試一下。

不過總的來講,黑名單咱們也能夠經過操做系統的防火牆去處理,這並不算一個特別棘手的問題。

4

局域網穿透

前面咱們說到了區塊鏈的 P2P 網絡結構是一種全分佈式的拓撲結構。可是,現在咱們的網絡環境是由局域網和互聯網組成的。也就是說,當你在局域網運行一個區塊鏈節點,在公網是發現不了的,公網上的節點只能被動接受鏈接,並不能主動發起鏈接。

若是這個局域網是你能夠控制的,那麼很好說,我們只須要在 VPC 網絡中配置路由,將公網 IP 和端口映射到局域網中你的 IP 和端口便可。

這個條件是很是苛刻的,那麼到底有沒有一種方案能夠自行創建映射呢?答案是:有,就是 NAT 技術和 UPnP 協議。

NAT 技術很是常見,這裏使用的是源 NAT,簡而言之就是替換 TCP 報文中的源地址並映射到內網地址。

UPnP 是通用即插即用(Universal Plug and Play)的縮寫,它主要用於設備的智能互聯互通,全部在網絡上的設備立刻就能知道有新設備加入。

這些設備彼此之間能互相通訊,更能直接使用或者控制它,一切都不須要人工設置。有關 UPnP 的資料比較多,這裏就不贅述了,你能夠自行搜索相關的信息。

比特幣和以太坊均使用了 UPnP 協議做爲局域網穿透工具,只要局域網中的路由設備支持 NAT 網關功能、支持 UPnP 協議,便可將你的區塊鏈節點自動映射到公網上。

5

節點交互協議

一旦節點創建鏈接之後,節點之間的交互是遵循一些特定的命令,這些命令寫在消息的頭部,消息體寫的則是消息內容。

命令分爲兩種,一種是請求命令,一種是數據交互命令。

節點鏈接完成要作的第一件事情叫作握手操做。這一點在比特幣和以太坊上的流程是差很少的,就是相互問候一下,提供一些簡要信息。

好比先交換一下版本號,看看是否兼容。只是以太坊爲握手過程提供了對稱加密,而比特幣沒有。

握手完畢以後,不管交互什麼信息,都是須要保持長鏈接的,在比特幣上有 PING/PONG 這兩種類型的消息,這很明顯就是用於保持節點之間長鏈接的心跳而設計的;而在以太坊的設計中,將 PING/PONG 協議移到了節點發現的過程當中。

請求命令通常分爲發起者請求,好比比特幣中的 getaddr 命令是爲了獲取對方的可用節點列表,inv 命令則提供了數據傳輸,消息體中會包含一個數據向量。

咱們說區塊鏈最重要的功能就是同步區塊鏈,而同步區塊恰巧是最考驗 P2P 網絡能力的。 區塊同步方式分爲兩種,第一種叫作 HeaderFirst,它提供了區塊頭先同步,同步完成之後再從其餘節點得到區塊體。

第二種叫作 BlockFirst,這種區塊同步的方式比較簡單粗暴,就是從其餘節點獲取區塊必須是完整的。第一種方案提供了較好的交互過程,減輕了網絡負擔。這兩種同步方式會直接體如今節點交互協議上,他們使用的命令邏輯徹底不一樣。

內容來源:區塊鏈兄弟

原文做者:納蘭少

原文連接:http://t.cn/Re3Vt6M

image

相關文章
相關標籤/搜索
本站公眾號
   歡迎關注本站公眾號,獲取更多信息