德陽城鄉(xiāng)建設(shè)部網(wǎng)站首頁網(wǎng)站創(chuàng)建
文章目錄
- 第一部分:libp2p 快速入門
- 一、什么是libp2p
- libp2p 發(fā)展歷程
- libp2p的特性
- p2p 網(wǎng)絡(luò)和我們熟悉的 client/server 網(wǎng)絡(luò)的區(qū)別:
- 二、Libp2p的實現(xiàn)目標(biāo)
- 三、Libp2p的用途
- 四、運行 Libp2p 協(xié)議流程
- libp2p 分為三層
- libp2p 還有一個局域網(wǎng)節(jié)點發(fā)現(xiàn)協(xié)議 mDNS
- 第二部分:使用實戰(zhàn)
- 一、基本接口
- multiaddr
- Host
- protocol.ID
- 如何封裝 libp2p?
- 二、基本使用
- 參考
第一部分:libp2p 快速入門
一、什么是libp2p
libp2p 官網(wǎng):非常重要,會解釋非常多的新概念,是學(xué)習(xí) libp2p 的第一課。
libp2p spec:這個是比官網(wǎng)更詳細(xì)的開發(fā)指導(dǎo)手冊,所有語言的實現(xiàn)都基于這個 specs。
rust-libp2p: libp2p 的 Rust 實現(xiàn)。
Libp2p是一個模塊化的網(wǎng)絡(luò)棧,通過將各種傳輸和P2P協(xié)議結(jié)合在一起,使得開發(fā)人員很容易構(gòu)建大型、健壯的P2P網(wǎng)絡(luò)。
libp2p 的產(chǎn)生是一個漫長的過程。 它是對網(wǎng)絡(luò)協(xié)議棧的深層次的挖掘, 豐富了過去點對點的協(xié)議。在過去的15年里面, 構(gòu)建大規(guī)模的點對點分布式應(yīng)用及其復(fù)雜, libp2p的目標(biāo)就是希望讓事情變得簡單。 Libp2p 設(shè)計的初衷就是為了支持未來的去中心化網(wǎng)絡(luò)協(xié)議,它的宗旨是讓開發(fā)者進(jìn)行應(yīng)用程序開發(fā)時,能確保他們的服務(wù)是可達(dá)且可用的。
如果說TCP/IP協(xié)議是互聯(lián)網(wǎng)時代網(wǎng)絡(luò)層的標(biāo)準(zhǔn),那么libp2p的愿景是希望成為區(qū)塊鏈時代,網(wǎng)絡(luò)層的標(biāo)準(zhǔn)。 雖然離這個目標(biāo)還想去甚遠(yuǎn), 但隨著ipv4地址的耗盡,以及區(qū)塊鏈浪潮的到來,這苗星星之火仿佛已經(jīng)燃起。
bp2p 包含一系列協(xié)議的實現(xiàn),這些協(xié)議共同作用,完成了:
p2p 網(wǎng)絡(luò)的傳輸層(下圖綠色):支持幾乎所有的主流傳輸協(xié)議,甚至允許不同節(jié)點間使用不同的傳輸層,比如 native 節(jié)點間優(yōu)先使用 QUIC,而 native 和 web 節(jié)點間使用 websocket。
節(jié)點發(fā)現(xiàn)(黃色,注意這里 PKI 是指基于 PKI 的節(jié)點身份):一般本地網(wǎng)絡(luò)可以使用 mDNS,大規(guī)模 p2p 網(wǎng)絡(luò)一般使用 bootstrap 來連接初始節(jié)點,然后通過 gossip 獲取更多節(jié)點信息,并通過 Kad DHT 來查找節(jié)點。
節(jié)點路由(藍(lán)色):主要使用 Kad DHT 通過多跳來路由到網(wǎng)絡(luò)中任意一個節(jié)點
內(nèi)容路由(紫色):如果點對點發(fā)送消息,可以通過 Kad DHT,如果在網(wǎng)絡(luò)中 flood,可以通過 floodsub 和 gossipsub 來對某個 topic 的內(nèi)容進(jìn)行廣播。
NAT traversal(紅色):包括主流的 hole punching 解決方案
(圖片來源:A network framework for decentralized P2P application development [2])
libp2p 發(fā)展歷程
libp2p孵化于ipfs項目, 最初libp2p是ipfs的網(wǎng)絡(luò)層實現(xiàn)。 在過去的數(shù)十年間, 構(gòu)建分布式p2p項目,一直是困擾大家的難題。 為簡化這種操作,libp2p項目應(yīng)運而生,libp2p是一組網(wǎng)絡(luò)協(xié)議套件,任何人,任何應(yīng)用都可以使用libp2p進(jìn)行構(gòu)建分布式應(yīng)用??梢哉flibp2p項目極大簡化了底層技術(shù)的開發(fā)難度,我們可以基于libp2p構(gòu)建自己的分布式系統(tǒng)。
libp2p is used by IPFS as its networking library.
libp2p被用作IPFS的網(wǎng)絡(luò)層。
libp2p 處于ipfs項目的最底層。最開始,libp2p是在ipfs項目里面的,只是ipfs項目中的一個網(wǎng)絡(luò)層模塊,大概在2017年左右, protocol lab對整個產(chǎn)品序列與技術(shù)棧進(jìn)行了重新規(guī)劃,ipfs項目被拆分成了很多個子項目,而這每一個子項目相互獨立,又各有關(guān)聯(lián)。 在整個項目發(fā)展過程中,尤其是在18年,整個項目模塊化重構(gòu),被拆的很細(xì)。而以大的產(chǎn)品類別進(jìn)行劃分,可以劃分為以下產(chǎn)品棧:
- ipfs
- libp2p
- filecoin
- ipld
ibp2p 模塊在 IPFS 中主要負(fù)責(zé)數(shù)據(jù)的傳遞功能,即路由、網(wǎng)絡(luò)、交換等。
libp2p是一套點對點的協(xié)議來發(fā)現(xiàn)節(jié)點,并連接他們,發(fā)現(xiàn)內(nèi)容,并轉(zhuǎn)移它們。
libp2p的主要功能是:
- 發(fā)現(xiàn)節(jié)點
- 連接節(jié)點
- 發(fā)現(xiàn)數(shù)據(jù)
- 傳輸數(shù)據(jù)
libp2p的特性
- Transport傳輸:
傳輸層是libp2p的基礎(chǔ),它負(fù)責(zé)數(shù)據(jù)從一個節(jié)點到另一個節(jié)點的可靠發(fā)送和接收。libp2p提供了一個可用于適配支持現(xiàn)有或未來傳輸協(xié)議的簡單的接口,從而允許libp2p應(yīng)用可以運行在不同的運行時和網(wǎng)絡(luò)環(huán)境中。最新版本的go-libp2p已支持TCP/TLS、WebSocket、QUIC傳輸層實現(xiàn)。
- Identity身份驗證:
libp2p使用公鑰作為節(jié)點身份的基礎(chǔ),這么做有兩個互補(bǔ)的用途,一是根據(jù)公鑰可以為節(jié)點提供一個全局唯一的身份ID(PeerId),二是所有節(jié)點可以用PeerId恢復(fù)出被認(rèn)證過的節(jié)點的公鑰,用于它們之間建立安全通訊。
- Security安全性:
libp2p支持將傳輸層提供的一個連接“upgrading”到一個安全加密通道中。這種方式很靈活,可以支持多種通訊加密方式。當(dāng)前l(fā)ibp2p支持TLS1.3和Noise兩種(老版本支持已棄用的Secio)。
- PeerRouting節(jié)點路由:
當(dāng)你想要向另一個節(jié)點發(fā)送一個消息時,你需要知道兩個信息:它的PeerId和它的網(wǎng)絡(luò)地址。在很多情況下我們只有對方的PeerId,我們需要一種可以找到它們的網(wǎng)絡(luò)地址的方法。節(jié)點路由是通過利用其他節(jié)點的信息發(fā)現(xiàn)目標(biāo)節(jié)點的網(wǎng)絡(luò)地址的過程。
在一個節(jié)點路由系統(tǒng)中,若我們想知道節(jié)點A的信息,我們可以向節(jié)點B請求查詢,如果節(jié)點B有節(jié)點A的信息,則我們可以獲得節(jié)點A的信息;如果節(jié)點B沒有節(jié)點A的信息,則節(jié)點B會返回給我們一個它認(rèn)為可能知道節(jié)點A的信息的節(jié)點C的信息,我們可以再向節(jié)點C請求查詢。隨著我們查詢越來越多的節(jié)點,我們不僅增加了找到節(jié)點A信息的概率,同時我們還在自己的路由表中建立了一個更完整的網(wǎng)絡(luò)視圖,這樣我們也可以為別的節(jié)點提供路由查詢服務(wù)。
當(dāng)前,libp2p的節(jié)點路由的穩(wěn)定實現(xiàn)是使用分布式哈希表(distributed hash table)基于Kademlia路由算法迭代查詢實現(xiàn)的。
- Content Discovery 內(nèi)容發(fā)現(xiàn)服務(wù):
在一些系統(tǒng)中,我們更關(guān)心的是它能為我們提供什么,而不是我們在和誰通訊。比如,我們想要一個文件,我們可以驗證這個文件的完整性,所以我們不關(guān)心從誰那拿到這個文件。
libp2p為這個場景提供了一個內(nèi)容路由接口(content routing interface),它的穩(wěn)定實現(xiàn)也是基于與節(jié)點路由中相同的KadDHT實現(xiàn)的。
- Messaging / PubSub 消息傳輸及發(fā)布訂閱:
向其他節(jié)點發(fā)送消息是大多數(shù)P2P系統(tǒng)的核心功能,而PubSub是一種非常有用的模式用于給一組訂閱者發(fā)送消息。
libp2p定義了一個可以向已訂閱指定Topic的所有節(jié)點發(fā)送消息的PubSub接口,該接口有兩種實現(xiàn):floodsub和gossipsub。默認(rèn)使用gossipsub。
p2p 網(wǎng)絡(luò)和我們熟悉的 client/server 網(wǎng)絡(luò)的區(qū)別:
p2p 網(wǎng)絡(luò)的每一個節(jié)點既是客戶端,又是服務(wù)器
p2p 網(wǎng)絡(luò)的每個節(jié)點,都(潛在)是數(shù)據(jù)的發(fā)起者和存儲者(對比:c/s 網(wǎng)絡(luò)中,server 擁有數(shù)據(jù))
p2p 網(wǎng)絡(luò)很不穩(wěn)定,節(jié)點可能進(jìn)進(jìn)出出(對比:c/s 網(wǎng)絡(luò),服務(wù)器非常穩(wěn)定,一般 SLA 都有幾個9)
p2p 網(wǎng)絡(luò)需要某種機(jī)制來實現(xiàn)節(jié)點的發(fā)現(xiàn)和查找(對比:c/s 網(wǎng)絡(luò),客戶端知道服務(wù)器在哪,如何訪問)
p2p 網(wǎng)絡(luò)(往往)需要 NAT traversal / Hole punching 等技術(shù)來允許兩個節(jié)點之間通訊。這是因為很多節(jié)點(比如說家庭網(wǎng)絡(luò))往往藏在運營商的 NAT 服務(wù)器之后。
二、Libp2p的實現(xiàn)目標(biāo)
- 支持各種各樣的傳輸方式:
- 傳輸:TCP,UDP,SCTP,UDP,uTP,QUIC,SSH,etc.
- 安全傳輸:TLS,DTLS,CurveCP,SSH
- 有效使用sockets(連接重用)
- 允許端點之間的交流可以在一個socket上復(fù)用(避免過多的握手)
- 允許端點之間通過一個協(xié)商過程使用多協(xié)議以及各自的版本
- 向后兼容
- 在現(xiàn)在的系統(tǒng)中可以運行
- 充分使用當(dāng)前網(wǎng)絡(luò)技術(shù)的能力
- 實現(xiàn)NAT轉(zhuǎn)換
- 實現(xiàn)連接中繼
- 實現(xiàn)加密通道
- 充分使用基礎(chǔ)傳輸(例如原生的流復(fù)用等)
三、Libp2p的用途
認(rèn)識Libp2p的用途
參考URL: https://baijiahao.baidu.com/s?id=1654695941739663075&wfr=spider&for=pc
-
物聯(lián)網(wǎng)
對于物聯(lián)網(wǎng)場景來說,P2P連接是很重要的一環(huán)。比如,在安防場景,安防攝像頭與手機(jī)之間最好建立直連連接。如此可以大幅度減輕中央服務(wù)器的帶寬壓力。libp2p可以幫助其完成鏈路上的連接工作,同時可以完成諸如NAT打洞(目前尚未實現(xiàn),但正在完善中)、流量及RTT統(tǒng)計、長鏈接、流式加密傳輸、服務(wù)端主動和終端通信等工作。此外,libp2p在車聯(lián)網(wǎng)領(lǐng)域也有適合的應(yīng)用場景。由于該場景中終端設(shè)備會不斷在各種網(wǎng)絡(luò)之間進(jìn)行切換,導(dǎo)致其IP地址信息不斷發(fā)生變化。**libp2p基于節(jié)點ID的鏈接方式及DHT路由發(fā)現(xiàn)機(jī)制,可以解除底層物理鏈接與上層邏輯的耦合。隨著互聯(lián)網(wǎng)的發(fā)展,應(yīng)用規(guī)模越來越大,如何有效且快速地分發(fā)信息,同時降低中心化服務(wù)器的壓力,是未來網(wǎng)絡(luò)技術(shù)發(fā)展的一個重要方向。
-
區(qū)塊鏈
在區(qū)塊鏈領(lǐng)域里面已經(jīng)有項目利用libp2p作為自己的底層服務(wù),比如之前多次提到的 Filecoin。在“區(qū)塊數(shù)據(jù)同步”“文件傳輸”節(jié)點查找”等核心環(huán)節(jié)都使用了libp2p。還有 Polkadot(波卡鏈)項目,作為可能成為區(qū)塊鏈3.0的開辟者,為了兼容現(xiàn)有的諸如以太坊等主鏈而采用異構(gòu)多鏈架構(gòu),更要考慮終端設(shè)備的復(fù)雜場景,因此選擇使用libp2p作為其底層傳輸層,利用libp2p在各個模塊中的高度抽象帶來的靈活性及可擴(kuò)展性,來避免因區(qū)塊鏈技術(shù)發(fā)展而導(dǎo)致的不兼容問題。 -
分布式消息
分布式消息系統(tǒng),可以不通過中心服務(wù)器的中轉(zhuǎn)功能,直接在節(jié)點之間建立連接,用于消息的發(fā)送和接收。去除了中心化服務(wù)器,可以有效防止單點失效、網(wǎng)絡(luò)攻擊。 -
傳輸文件
Filecoin和IPFS是基于libp2p來進(jìn)行數(shù)據(jù)傳輸?shù)?。對于點對點文件傳輸,libp2p將有非常廣泛的應(yīng)用場景。
四、運行 Libp2p 協(xié)議流程
-
運行 Libp2p 協(xié)議的節(jié)點在初始化之后需要通過各種方式發(fā)現(xiàn)更多的節(jié)點,比如 Bootstrap list、mDNS、DHT 等,這主要由發(fā)現(xiàn)模塊負(fù)責(zé)與實現(xiàn)。
-
當(dāng)發(fā)現(xiàn)更多接點后,Libp2p 會把這些獲取到的節(jié)點信息存儲在分布式記錄存儲模塊中,供以后方便使用。
-
當(dāng)上層應(yīng)用需要連接某個節(jié)點時,節(jié)點路由模塊會找到多條不同的路徑,連接管理模塊會對這些路徑進(jìn)行嘗試連接。
-
連接成功之后,上層應(yīng)用將通過內(nèi)容路由模塊與連接節(jié)點進(jìn)行內(nèi)容交互,在底層通過傳輸模塊互相傳遞數(shù)據(jù)。
下面我們具體分析一下連接的建立過程,主要包括3個步驟,包括地址解析、傳輸協(xié)議適配、雙方協(xié)商。
- 地址解析
- 傳輸協(xié)議適配
- 雙方協(xié)商
連接建立之后,libp2p 會首先進(jìn)行雙方協(xié)商,確定對方支持哪些功能。負(fù)責(zé)協(xié)商功能的是 identify 協(xié)議,它是內(nèi)置在 libp2p 的基礎(chǔ)協(xié)議,能夠交換節(jié)點的公鑰、本地監(jiān)聽地址等。
協(xié)商完成后,連接兩端的節(jié)點會找到共同支持的協(xié)議,并且初始化它們。初始化時會注冊每種協(xié)議的 handler(回調(diào)函數(shù)),當(dāng)有協(xié)議數(shù)據(jù)到達(dá)時,相應(yīng)的 handler 就會被調(diào)用。 由于多種傳輸協(xié)議會復(fù)用同一個底層連接,所以連接會被拆分成多個“流(Stream)”。
libp2p 分為三層
-
Transport 傳輸層:負(fù)責(zé)數(shù)據(jù)的傳輸。
底層網(wǎng)絡(luò)協(xié)議:支持 TCP / UDP / QUIC 等;
安全協(xié)議:支持 TLS 1.3 / Noise;
多路復(fù)用(Stream Multiplexing):支持 Yamux,mplex 從 libp2p-0.52.0 開始不再支持。 -
Protocols 協(xié)議層:負(fù)責(zé)數(shù)據(jù)的處理。
一個 P2P 節(jié)點要使用很多 Protocols,包括節(jié)點發(fā)現(xiàn)(Kademlia、Identify、Ping)、內(nèi)容發(fā)現(xiàn)(Gossipsub)、和請求響應(yīng)(Request-Response)
libp2p 定義了很多官方協(xié)議 spec,我們也可以實現(xiàn)自己的協(xié)議,這是封裝 libp2p 的方式之一。
一個 Protocol 包含兩個核心部分:Behaviour 和 BehaviourEvent。在構(gòu)造 Swarm 時需要 Behaviour;在處理 SwarmEvent 時需要處理 BehaviourEvent。 -
Swarm 控制層:負(fù)責(zé)將 Transport 和 Protocols 結(jié)合起來,相當(dāng)于 HTTP Server 中的 Controller。
libp2p 還有一個局域網(wǎng)節(jié)點發(fā)現(xiàn)協(xié)議 mDNS
第二部分:使用實戰(zhàn)
官方demo程序:https://github.com/libp2p/go-libp2p/tree/master/examples
libp2p 分為三層:transport, swarm, protocol
運行一個 P2P 節(jié)點的步驟:構(gòu)造 transport -> 構(gòu)造 protocol -> 構(gòu)造 swarm -> 運行 swarm -> 處理 swarm events
- Transport 傳輸層:負(fù)責(zé)數(shù)據(jù)的傳輸。// 相當(dāng)于 tinychain 的網(wǎng)絡(luò)層
- Protocols 協(xié)議層:負(fù)責(zé)數(shù)據(jù)的處理。// 相當(dāng)于 tinychain 的業(yè)務(wù)層,libp2p 沒有狀態(tài),所以不需要數(shù)據(jù)層
- Swarm 控制層:負(fù)責(zé)將 Transport 和 Protocols 結(jié)合起來,相當(dāng)于 HTTP Server 中的 Controller。 /
一、基本接口
multiaddr
libp2p使用了multiaddr,一個自描述的地址形式,可以理解為不同協(xié)議不同地址類型的一個封裝。這使得libp2p可以不透明的處理系統(tǒng)中的所有地址,支持網(wǎng)絡(luò)層中的各種傳輸協(xié)議。
Host
// Host is an object participating in a p2p network, which
// implements protocols or provides services. It handles
// requests like a Server, and issues requests like a Client.
// It is called Host because it is both Server and Client (and Peer
// may be confusing).
type Host interface {// ID returns the (local) peer.ID associated with this HostID() peer.ID// Peerstore returns the Host's repository of Peer Addresses and Keys.Peerstore() peerstore.Peerstore// Returns the listen addresses of the HostAddrs() []ma.Multiaddr// Networks returns the Network interface of the HostNetwork() network.Network// Mux returns the Mux multiplexing incoming streams to protocol handlersMux() protocol.Switch// Connect ensures there is a connection between this host and the peer with// given peer.ID. Connect will absorb the addresses in pi into its internal// peerstore. If there is not an active connection, Connect will issue a// h.Network.Dial, and block until a connection is open, or an error is// returned. // TODO: Relay + NAT.Connect(ctx context.Context, pi peer.AddrInfo) error// SetStreamHandler sets the protocol handler on the Host's Mux.// This is equivalent to:// host.Mux().SetHandler(proto, handler)// (Threadsafe)SetStreamHandler(pid protocol.ID, handler network.StreamHandler)// SetStreamHandlerMatch sets the protocol handler on the Host's Mux// using a matching function for protocol selection.SetStreamHandlerMatch(protocol.ID, func(string) bool, network.StreamHandler)// RemoveStreamHandler removes a handler on the mux that was set by// SetStreamHandlerRemoveStreamHandler(pid protocol.ID)// NewStream opens a new stream to given peer p, and writes a p2p/protocol// header with given ProtocolID. If there is no connection to p, attempts// to create one. If ProtocolID is "", writes no header.// (Threadsafe)NewStream(ctx context.Context, p peer.ID, pids ...protocol.ID) (network.Stream, error)// Close shuts down the host, its Network, and services.Close() error// ConnManager returns this hosts connection managerConnManager() connmgr.ConnManager// EventBus returns the hosts eventbusEventBus() event.Bus
}
protocol.ID
func DhtProtocolName(netName dtypes.NetworkName) protocol.ID {return protocol.ID("/fil/kad/" + string(netName))
}
...dht.ProtocolPrefix(build.DhtProtocolName(nn)),
//ProtocolPrefix設(shè)置附加到所有DHT協(xié)議的特定于應(yīng)用程序的前綴。例如,
///myapp/kad/1.0.0而不是/ipfs/kad/1.0.0。前綴的格式應(yīng)為/myapp。
//
//默認(rèn)為默認(rèn)dht.DefaultPrefix (dht包下 const DefaultPrefix protocol.ID = “/ipfs”)
如何封裝 libp2p?
自定義 protocol:工作量很大,可能要重新實現(xiàn)官方已提供的 protocols
自定義 swarm event handlers:較簡單,找到要處理哪些 evnets,問題就解決了一半
二、基本使用
官方demo:https://github.com/libp2p/go-libp2p/tree/master/examples/libp2p-host
創(chuàng)建 libp2p 主機(jī)
// To construct a simple host with all the default settings, just use `New`
h, err := libp2p.New()
if err != nil {panic(err)
}
defer h.Close()fmt.Printf("Hello World, my p2p hosts ID is %s\n", h.ID())
如果您想對配置進(jìn)行更多控制,則可以為構(gòu)造函數(shù)指定一些選項。有關(guān)構(gòu)造函數(shù)支持的所有配置的完整列表,請參閱文檔中的不同選項 。
在此片段中,我們設(shè)置了許多有用的選項,例如自定義ID并啟用路由。這將提高同伴在NAT’ED環(huán)境上的可發(fā)現(xiàn)性和可達(dá)到性:
// Set your own keypair
priv, _, err := crypto.GenerateKeyPair(crypto.Ed25519, // Select your key type. Ed25519 are nice short-1, // Select key length when possible (i.e. RSA).
)
if err != nil {panic(err)
}var idht *dht.IpfsDHTh2, err := libp2p.New(// Use the keypair we generatedlibp2p.Identity(priv),// Multiple listen addresseslibp2p.ListenAddrStrings("/ip4/0.0.0.0/tcp/9000", // regular tcp connections"/ip4/0.0.0.0/udp/9000/quic", // a UDP endpoint for the QUIC transport),// support TLS connectionslibp2p.Security(libp2ptls.ID, libp2ptls.New),// support Noise connectionslibp2p.Security(noise.ID, noise.New),// support QUIClibp2p.Transport(libp2pquic.NewTransport),// support any other default transports (TCP)libp2p.DefaultTransports,// Let's prevent our peer from having too many// connections by attaching a connection manager.libp2p.ConnectionManager(connmgr.NewConnManager(100, // Lowwater400, // HighWater,time.Minute, // GracePeriod)),// Attempt to open ports using uPNP for NATed hosts.libp2p.NATPortMap(),// Let this host use the DHT to find other hostslibp2p.Routing(func(h host.Host) (routing.PeerRouting, error) {idht, err = dht.New(ctx, h)return idht, err}),// Let this host use relays and advertise itself on relays if// it finds it is behind NAT. Use libp2p.Relay(options...) to// enable active relays and more.libp2p.EnableAutoRelay(),
)
if err != nil {panic(err)
}
defer h2.Close()fmt.Printf("Hello World, my second hosts ID is %s\n", h2.ID())
參考
參考資料:libp2p-specifications : https://github.com/libp2p/specs
為什么 ETH2.0 要選擇 libp2p ?
參考URL: https://blog.csdn.net/shangsongwww/article/details/89428696
libp2p 替代方案調(diào)研
參考URL: https://www.jianshu.com/p/214ec5f54bbd
參考資料:libp2p-specifications : https://github.com/libp2p/specs
Libp2p學(xué)習(xí)(一)
參考URL: https://www.cnblogs.com/YuzhouQiang/p/10593160.html
IPFS世界的物流系統(tǒng):libp2p
參考URL: https://blog.csdn.net/IPFS_Newb/article/details/83186581
長安鏈P2P網(wǎng)絡(luò)技術(shù)介紹(2):初識LibP2P
參考URL: https://cloud.tencent.com/developer/article/1988253
網(wǎng)絡(luò)協(xié)議十二之P2P協(xié)議
參考URL: https://www.cnblogs.com/SuoLiweng/articles/16574502.html
[推薦]06 | libp2p: 需求分析與封裝思路
參考URL: https://zhuanlan.zhihu.com/p/643357754
【go-libp2p學(xué)習(xí)筆記】使用go-libp2p搭建中轉(zhuǎn)服務(wù)器(circuit relay server)
參考URL: https://blog.csdn.net/Cake_C/article/details/127630718
[推薦]探索 libp2p:基本知識
參考URL: https://cloud.tencent.com/developer/article/1836307