真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

go語言libp2p,Go語言圣經(jīng)

如何看待go語言泛型的最新設(shè)計(jì)?

Go 由于不支持泛型而臭名昭著,但最近,泛型已接近成為現(xiàn)實(shí)。Go 團(tuán)隊(duì)實(shí)施了一個(gè)看起來比較穩(wěn)定的設(shè)計(jì)草案,并且正以源到源翻譯器原型的形式獲得關(guān)注。本文講述的是泛型的最新設(shè)計(jì),以及如何自己嘗試泛型。

專注于為中小企業(yè)提供成都做網(wǎng)站、網(wǎng)站設(shè)計(jì)服務(wù),電腦端+手機(jī)端+微信端的三站合一,更高效的管理,為中小企業(yè)環(huán)江免費(fèi)做網(wǎng)站提供優(yōu)質(zhì)的服務(wù)。我們立足成都,凝聚了一批互聯(lián)網(wǎng)行業(yè)人才,有力地推動(dòng)了上1000家企業(yè)的穩(wěn)健成長,幫助中小企業(yè)通過網(wǎng)站建設(shè)實(shí)現(xiàn)規(guī)模擴(kuò)充和轉(zhuǎn)變。

例子

FIFO Stack

假設(shè)你要?jiǎng)?chuàng)建一個(gè)先進(jìn)先出堆棧。沒有泛型,你可能會(huì)這樣實(shí)現(xiàn):

type?Stack?[]interface{}func?(s?Stack)?Peek()?interface{}?{

return?s[len(s)-1]

}

func?(s?*Stack)?Pop()?{

*s?=?(*s)[:

len(*s)-1]

}

func?(s?*Stack)?Push(value?interface{})?{

*s?=?

append(*s,?value)

}

但是,這里存在一個(gè)問題:每當(dāng)你 Peek 項(xiàng)時(shí),都必須使用類型斷言將其從 interface{} 轉(zhuǎn)換為你需要的類型。如果你的堆棧是 *MyObject 的堆棧,則意味著很多 s.Peek().(*MyObject)這樣的代碼。這不僅讓人眼花繚亂,而且還可能引發(fā)錯(cuò)誤。比如忘記 * 怎么辦?或者如果您輸入錯(cuò)誤的類型怎么辦?s.Push(MyObject{})` 可以順利編譯,而且你可能不會(huì)發(fā)現(xiàn)到自己的錯(cuò)誤,直到它影響到你的整個(gè)服務(wù)為止。

通常,使用 interface{} 是相對(duì)危險(xiǎn)的。使用更多受限制的類型總是更安全,因?yàn)榭梢栽诰幾g時(shí)而不是運(yùn)行時(shí)發(fā)現(xiàn)問題。

泛型通過允許類型具有類型參數(shù)來解決此問題:

type?Stack(type?T)?[]Tfunc?(s?Stack(T))?Peek()?T?{

return?s[len(s)-1]

}

func?(s?*Stack(T))?Pop()?{

*s?=?(*s)[:

len(*s)-1]

}

func?(s?*Stack(T))?Push(value?T)?{

*s?=?

append(*s,?value)

}

這會(huì)向 Stack 添加一個(gè)類型參數(shù),從而完全不需要 interface{}?,F(xiàn)在,當(dāng)你使用 Peek() 時(shí),返回的值已經(jīng)是原始類型,并且沒有機(jī)會(huì)返回錯(cuò)誤的值類型。這種方式更安全,更容易使用。(譯注:就是看起來更丑陋,^-^)

此外,泛型代碼通常更易于編譯器優(yōu)化,從而獲得更好的性能(以二進(jìn)制大小為代價(jià))。如果我們對(duì)上面的非泛型代碼和泛型代碼進(jìn)行基準(zhǔn)測(cè)試,我們可以看到區(qū)別:

type?MyObject?struct?{

X?

int

}

var?sink?MyObjectfunc?BenchmarkGo1(b?*testing.B)?{

for?i?:=?0;?i??b.N;?i++?{

var?s?Stack

s.Push(MyObject{})

s.Push(MyObject{})

s.Pop()

sink?=?s.Peek().(MyObject)

}

}

func?BenchmarkGo2(b?*testing.B)?{

for?i?:=?0;?i??b.N;?i++?{

var?s?Stack(MyObject)

s.Push(MyObject{})

s.Push(MyObject{})

s.Pop()

sink?=?s.Peek()

}

}

結(jié)果:

BenchmarkGo1BenchmarkGo1-16?????12837528?????????87.0?ns/op???????48?B/op????????2?allocs/opBenchmarkGo2BenchmarkGo2-16?????28406479?????????41.9?ns/op???????24?B/op????????2?allocs/op

在這種情況下,我們分配更少的內(nèi)存,同時(shí)泛型的速度是非泛型的兩倍。

合約(Contracts)

上面的堆棧示例適用于任何類型。但是,在許多情況下,你需要編寫僅適用于具有某些特征的類型的代碼。例如,你可能希望堆棧要求類型實(shí)現(xiàn) String() 函數(shù)

IPFS(四) 源碼解讀之-p2p

package p2p

import (

"context"

"errors"

"time"

net "gx/ipfs/QmPjvxTpVH8qJyQDnxnsxF9kv9jezKD1kozz1hs3fCGsNh/go-libp2p-net"

manet "gx/ipfs/QmV6FjemM1K8oXjrvuq3wuVWWoU2TLDPmNnKrxHzY3v6Ai/go-multiaddr-net"

ma "gx/ipfs/QmYmsdtJ3HsodkePE3eU3TsCaP2YvPZJ4LoXnNkDE5Tpt7/go-multiaddr"

pro "gx/ipfs/QmZNkThpqfVXs9GNbexPrfBbXSLNYeKrE7jwFM2oqHbyqN/go-libp2p-protocol"

pstore "gx/ipfs/QmZR2XWVVBCtbgBWnQhWk2xcQfaR3W8faQPriAiaaj7rsr/go-libp2p-peerstore"

p2phost "gx/ipfs/Qmb8T6YBBsjYsVGfrihQLfCJveczZnneSBqBKkYEBWDjge/go-libp2p-host"

peer "gx/ipfs/QmdVrMn1LhB4ybb8hMVaMLXnA8XRSewMnK6YqXKXoTcRvN/go-libp2p-peer"

)

//P2P結(jié)構(gòu)保存當(dāng)前正在運(yùn)行的流/監(jiān)聽器的信息

// P2P structure holds information on currently running streams/listeners

type P2P struct {

//監(jiān)聽器

Listeners ListenerRegistry

//數(shù)據(jù)流

Streams StreamRegistry

//節(jié)點(diǎn)ID

identity peer.ID

//節(jié)點(diǎn)地址

peerHost p2phost.Host

//一個(gè)線程安全的對(duì)等節(jié)點(diǎn)存儲(chǔ)

peerstore pstore.Peerstore

}

//創(chuàng)建一個(gè)新的p2p結(jié)構(gòu)

// NewP2P creates new P2P struct

//這個(gè)新的p2p結(jié)構(gòu)不包含p2p結(jié)構(gòu)中的監(jiān)聽器和數(shù)據(jù)流

func NewP2P(identity peer.ID, peerHost p2phost.Host, peerstore pstore.Peerstore) *P2P {

return P2P{

identity: identity,

peerHost: peerHost,

peerstore: peerstore,

}

}

//新建一個(gè)數(shù)據(jù)流 工具方法 構(gòu)建一個(gè)有節(jié)點(diǎn)id,內(nèi)容和協(xié)議的流

func (p2p P2P) newStreamTo(ctx2 context.Context, p peer.ID, protocol string) (net.Stream, error) {

//30s 后會(huì)自動(dòng)timeout

ctx, cancel := context.WithTimeout(ctx2, time.Second 30) //TODO: configurable?

defer cancel()

err := p2p.peerHost.Connect(ctx, pstore.PeerInfo{ID: p})

if err != nil {

return nil, err

}

return p2p.peerHost.NewStream(ctx2, p, pro.ID(protocol))

}

//對(duì)話為遠(yuǎn)程監(jiān)聽器創(chuàng)建新的P2P流

//創(chuàng)建一個(gè)新的p2p流實(shí)現(xiàn)對(duì)對(duì)話的監(jiān)聽

// Dial creates new P2P stream to a remote listener

//Multiaddr是一種跨協(xié)議、跨平臺(tái)的表示格式的互聯(lián)網(wǎng)地址。它強(qiáng)調(diào)明確性和自我描述。

//對(duì)內(nèi)接收

func (p2p P2P) Dial(ctx context.Context, addr ma.Multiaddr, peer peer.ID, proto string, bindAddr ma.Multiaddr) ( ListenerInfo, error) {

//獲取一些節(jié)點(diǎn)信息 network, host, nil

lnet, _, err := manet.DialArgs(bindAddr)

if err != nil {

return nil, err

}

//監(jiān)聽信息

listenerInfo := ListenerInfo{

//節(jié)點(diǎn)身份

Identity: p2p.identity,

////應(yīng)用程序協(xié)議標(biāo)識(shí)符。

Protocol: proto,

}

//調(diào)用newStreamTo 通過ctx(內(nèi)容) peer(節(jié)點(diǎn)id) proto(協(xié)議標(biāo)識(shí)符) 參數(shù)獲取一個(gè)新的數(shù)據(jù)流

remote, err := p2p.newStreamTo(ctx, peer, proto)

if err != nil {

return nil, err

}

//network協(xié)議標(biāo)識(shí)

switch lnet {

//network為"tcp", "tcp4", "tcp6"

case "tcp", "tcp4", "tcp6":

//從監(jiān)聽器獲取新的信息 nla.Listener, nil

listener, err := manet.Listen(bindAddr)

if err != nil {

if err2 := remote.Reset(); err2 != nil {

return nil, err2

}

return nil, err

}

//將獲取的新信息保存到listenerInfo

listenerInfo.Address = listener.Multiaddr()

listenerInfo.Closer = listener

listenerInfo.Running = true

//開啟接受

go p2p.doAccept(listenerInfo, remote, listener)

default:

return nil, errors.New("unsupported protocol: " + lnet)

}

return listenerInfo, nil

}

//

func (p2p *P2P) doAccept(listenerInfo *ListenerInfo, remote net.Stream, listener manet.Listener) {

//關(guān)閉偵聽器并刪除流處理程序

defer listener.Close()

//Returns a Multiaddr friendly Conn

//一個(gè)有好的 Multiaddr 連接

local, err := listener.Accept()

if err != nil {

return

}

stream := StreamInfo{

//連接協(xié)議

Protocol: listenerInfo.Protocol,

//定位節(jié)點(diǎn)

LocalPeer: listenerInfo.Identity,

//定位節(jié)點(diǎn)地址

LocalAddr: listenerInfo.Address,

//遠(yuǎn)程節(jié)點(diǎn)

RemotePeer: remote.Conn().RemotePeer(),

//遠(yuǎn)程節(jié)點(diǎn)地址

RemoteAddr: remote.Conn().RemoteMultiaddr(),

//定位

Local: local,

//遠(yuǎn)程

Remote: remote,

//注冊(cè)碼

Registry: p2p.Streams,

}

//注冊(cè)連接信息

p2p.Streams.Register(stream)

//開啟節(jié)點(diǎn)廣播

stream.startStreaming()

}

//偵聽器將流處理程序包裝到偵聽器中

// Listener wraps stream handler into a listener

type Listener interface {

Accept() (net.Stream, error)

Close() error

}

//P2PListener保存關(guān)于偵聽器的信息

// P2PListener holds information on a listener

type P2PListener struct {

peerHost p2phost.Host

conCh chan net.Stream

proto pro.ID

ctx context.Context

cancel func()

}

//等待偵聽器的連接

// Accept waits for a connection from the listener

func (il *P2PListener) Accept() (net.Stream, error) {

select {

case c := -il.conCh:

return c, nil

case -il.ctx.Done():

return nil, il.ctx.Err()

}

}

//關(guān)閉偵聽器并刪除流處理程序

// Close closes the listener and removes stream handler

func (il *P2PListener) Close() error {

il.cancel()

il.peerHost.RemoveStreamHandler(il.proto)

return nil

}

// Listen創(chuàng)建新的P2PListener

// Listen creates new P2PListener

func (p2p P2P) registerStreamHandler(ctx2 context.Context, protocol string) ( P2PListener, error) {

ctx, cancel := context.WithCancel(ctx2)

list := P2PListener{

peerHost: p2p.peerHost,

proto: pro.ID(protocol),

conCh: make(chan net.Stream),

ctx: ctx,

cancel: cancel,

}

p2p.peerHost.SetStreamHandler(list.proto, func(s net.Stream) {

select {

case list.conCh - s:

case -ctx.Done():

s.Reset()

}

})

return list, nil

}

// NewListener創(chuàng)建新的p2p偵聽器

// NewListener creates new p2p listener

//對(duì)外廣播

func (p2p P2P) NewListener(ctx context.Context, proto string, addr ma.Multiaddr) ( ListenerInfo, error) {

//調(diào)用registerStreamHandler 構(gòu)造一個(gè)新的listener

listener, err := p2p.registerStreamHandler(ctx, proto)

if err != nil {

return nil, err

}

//構(gòu)造新的listenerInfo

listenerInfo := ListenerInfo{

Identity: p2p.identity,

Protocol: proto,

Address: addr,

Closer: listener,

Running: true,

Registry: p2p.Listeners,

}

go p2p.acceptStreams(listenerInfo, listener)

//注冊(cè)連接信息

p2p.Listeners.Register(listenerInfo)

return listenerInfo, nil

}

//接受流

func (p2p *P2P) acceptStreams(listenerInfo *ListenerInfo, listener Listener) {

for listenerInfo.Running {

//一個(gè)有好的 遠(yuǎn)程 連接

remote, err := listener.Accept()

if err != nil {

listener.Close()

break

}

}

//取消注冊(cè)表中的p2p偵聽器

p2p.Listeners.Deregister(listenerInfo.Protocol)

}

// CheckProtoExists檢查是否注冊(cè)了協(xié)議處理程序

// mux處理程序

// CheckProtoExists checks whether a protocol handler is registered to

// mux handler

func (p2p *P2P) CheckProtoExists(proto string) bool {

protos := p2p.peerHost.Mux().Protocols()

for _, p := range protos {

if p != proto {

continue

}

return true

}

return false

}

區(qū)塊鏈技術(shù)想要快速入門,一般涉及哪些編程語言?

任何一門計(jì)算機(jī)語言,都能在特定某個(gè)領(lǐng)域的應(yīng)用中,實(shí)現(xiàn)區(qū)塊鏈技術(shù);

具體使用哪一門語言,完全看我們相應(yīng)領(lǐng)域行業(yè)企業(yè)項(xiàng)目的技術(shù)要求,以及更關(guān)鍵的:跟已有信息系統(tǒng)的有效對(duì)接聯(lián)通。

區(qū)塊鏈具有自下而上生成記錄,生成兩方或多方合同類記錄,加入第三方確認(rèn)機(jī)制,分布存儲(chǔ),……等特點(diǎn);

從而讓它相比集中式的存儲(chǔ)運(yùn)算而言,變得更為可信。

常見的總統(tǒng)投票,就非常適合以區(qū)塊鏈技術(shù)重新架構(gòu);采用區(qū)塊鏈技術(shù)的投票系統(tǒng),能夠避免哪一家技術(shù)公司、某一個(gè)關(guān)鍵技術(shù)人員,操縱選票統(tǒng)計(jì)結(jié)果的可能。

像我們的法院證據(jù),也特別適合采用區(qū)塊鏈技術(shù)重新架構(gòu)開發(fā)。

其實(shí)像當(dāng)前我們各類互聯(lián)網(wǎng)時(shí)代的“版權(quán)系統(tǒng)”,它們中一些就是采用區(qū)塊鏈技術(shù)架構(gòu)而來,只不過,目前我們的新聞出版局、專利局(或者更廣義地被稱作“專家評(píng)委”),都尚未接入這些由互聯(lián)網(wǎng)公司創(chuàng)新而來的版權(quán)平臺(tái)。

我們耳熟能詳 的“法大大”(雖然名字不甚好聽、甚至乍一聽來有些讓人“摸不著頭腦”),它也其實(shí)正準(zhǔn)備采用最新的區(qū)塊鏈技術(shù)重新架構(gòu);采用區(qū)塊鏈技術(shù)的合同平臺(tái),因?yàn)樽兊酶涌尚?,也才能更便于互?lián)網(wǎng)時(shí)代人們簽訂各類商務(wù)合同。

還有像我們的“征信系統(tǒng)”,也非常適合以區(qū)塊鏈技術(shù)加以改造。能夠讓它更有說服力,而不致于出現(xiàn)一家單位、乃至隨意某個(gè)關(guān)鍵技術(shù)人員,能隨意往其中添加“征信污點(diǎn)數(shù)據(jù)”的情況。

還有像我們的P2P貸款,如果能夠以區(qū)塊鏈技術(shù)重新架構(gòu)的話,也能夠變得更加可信,而不致于出現(xiàn)違約、卷款跑路這樣的失信情況。

IPFS 一個(gè)分布式系統(tǒng),用于存儲(chǔ)和訪問文件、網(wǎng)站、應(yīng)用程序和數(shù)據(jù)

《開源精選》是我們分享Github、Gitee等開源社區(qū)中優(yōu)質(zhì)項(xiàng)目的欄目,包括技術(shù)、學(xué)習(xí)、實(shí)用與各種有趣的內(nèi)容。本期推薦的IPFS 是一個(gè)分布式系統(tǒng),用于存儲(chǔ)和訪問文件、網(wǎng)站、應(yīng)用程序和數(shù)據(jù)。

而且,當(dāng)您使用 IPFS 時(shí),您不只是從其他人那里下載文件——您的計(jì)算機(jī)也有助于分發(fā)它們。當(dāng)您在幾個(gè)街區(qū)外的朋友需要相同的 Wikipedia 頁面時(shí),他們可能會(huì)像從您的鄰居或任何使用 IPFS 的人那里一樣從您那里獲得它。

IPFS 不僅可以用于網(wǎng)頁,還可以用于計(jì)算機(jī)可能存儲(chǔ)的任何類型的文件,無論是文檔、電子郵件,甚至是數(shù)據(jù)庫記錄。

可以從不由一個(gè)組織管理的多個(gè)位置下載文件:

最后一點(diǎn)實(shí)際上是 IPFS 的全名: InterPlanetary File System 。我們正在努力建立一個(gè)系統(tǒng),該系統(tǒng)可以在不連貫或相隔很遠(yuǎn)的地方工作,就像行星一樣。雖然這是一個(gè)理想主義的目標(biāo),但它讓我們努力工作和思考,幾乎我們?yōu)閷?shí)現(xiàn)這一目標(biāo)而創(chuàng)造的一切在家里也很有用。

IPFS 是一個(gè)點(diǎn)對(duì)點(diǎn) (p2p) 存儲(chǔ)網(wǎng)絡(luò)??梢酝ㄟ^位于世界任何地方的對(duì)等點(diǎn)訪問內(nèi)容,這些對(duì)等點(diǎn)可能會(huì)傳遞信息、存儲(chǔ)信息或兩者兼而有之。IPFS 知道如何使用其內(nèi)容地址而不是其位置來查找您要求的內(nèi)容。

理解 IPFS 的三個(gè)基本原則:

這三個(gè)原則相互依賴,以啟用 IPFS 生態(tài)系統(tǒng)。讓我們從 內(nèi)容尋址 和內(nèi)容的唯一標(biāo)識(shí)開始。

互聯(lián)網(wǎng)和您的計(jì)算機(jī)上都存在這個(gè)問題!現(xiàn)在,內(nèi)容是按位置查找的,例如:

相比之下,每條使用 IPFS 協(xié)議的內(nèi)容都有一個(gè) 內(nèi)容標(biāo)識(shí)符 ,即 CID,即其 哈希值 。散列對(duì)于它所來自的內(nèi)容來說是唯一的,即使它與原始內(nèi)容相比可能看起來很短。

有向無環(huán)圖 (DAG)

IPFS 和許多其他分布式系統(tǒng)利用稱為有向無環(huán)圖的數(shù)據(jù)結(jié)構(gòu) (打開新窗口),或 DAG。具體來說,他們使用 Merkle DAG ,其中每個(gè)節(jié)點(diǎn)都有一個(gè)唯一標(biāo)識(shí)符,該標(biāo)識(shí)符是節(jié)點(diǎn)內(nèi)容的哈希。

IPFS 使用針對(duì)表示目錄和文件進(jìn)行了優(yōu)化的 Merkle DAG,但您可以通過多種不同的方式構(gòu)建 Merkle DAG。例如,Git 使用 Merkle DAG,其中包含許多版本的存儲(chǔ)庫。

為了構(gòu)建內(nèi)容的 Merkle DAG 表示,IPFS 通常首先將其拆分為 塊 。將其拆分為塊意味著文件的不同部分可以來自不同的來源并可以快速進(jìn)行身份驗(yàn)證。

分布式哈希表 (DHT)

要查找哪些對(duì)等方正在托管您所追求的內(nèi)容( 發(fā)現(xiàn) ),IPFS 使用分布式哈希表或 DHT。哈希表是值鍵的數(shù)據(jù)庫。 分布式 哈希表是一種表在分布式網(wǎng)絡(luò)中的所有對(duì)等方之間拆分的表。要查找內(nèi)容,您需要詢問這些同行。

libp2p項(xiàng)目 (打開新窗口)是 IPFS 生態(tài)系統(tǒng)的一部分,它提供 DHT 并處理對(duì)等點(diǎn)之間的連接和交談。

一旦你知道你的內(nèi)容在哪里(或者更準(zhǔn)確地說,哪些對(duì)等點(diǎn)正在存儲(chǔ)構(gòu)成你所追求的內(nèi)容的每個(gè)塊),你就可以再次使用 DHT 來查找這些對(duì)等點(diǎn)的當(dāng)前位置( 路由 )。因此,要獲取內(nèi)容,請(qǐng)使用 libp2p 查詢 DHT 兩次。

然而,這確實(shí)意味著 IPFS 本身并沒有明確保護(hù) 有關(guān) CID 和提供或檢索它們的節(jié)點(diǎn)的知識(shí)。這不是分布式網(wǎng)絡(luò)所獨(dú)有的。在 d-web 和 legacy web 上,流量和其他元數(shù)據(jù)都可以通過可以推斷出很多關(guān)于網(wǎng)絡(luò)及其用戶的方式進(jìn)行監(jiān)控。下面概述了這方面的一些關(guān)鍵細(xì)節(jié),但簡而言之:雖然 節(jié)點(diǎn)之間 的 IPFS 流量是加密的,但這些節(jié)點(diǎn)發(fā)布到 DHT 的元數(shù)據(jù)是公開的。節(jié)點(diǎn)宣布對(duì) DHT 功能至關(guān)重要的各種信息——包括它們的唯一節(jié)點(diǎn)標(biāo)識(shí)符 (PeerID) 和它們提供的數(shù)據(jù)的 CID——因此,關(guān)于哪些節(jié)點(diǎn)正在檢索和/或重新提供哪些 CID 的信息是公開的可用的。

加密

網(wǎng)絡(luò)中有兩種類型的加密: 傳輸加密 和 內(nèi)容加密 。

在兩方之間發(fā)送數(shù)據(jù)時(shí)使用傳輸加密。阿爾伯特加密文件并將其發(fā)送給萊卡,萊卡在收到文件后對(duì)其進(jìn)行解密。這會(huì)阻止第三方在數(shù)據(jù)從一個(gè)地方移動(dòng)到另一個(gè)地方時(shí)查看數(shù)據(jù)。

內(nèi)容加密用于保護(hù)數(shù)據(jù),直到有人需要訪問它。Albert 為他的每月預(yù)算創(chuàng)建了一個(gè)電子表格,并用密碼保存它。當(dāng) Albert 需要再次訪問它時(shí),他必須輸入密碼才能解密文件。沒有密碼,Laika 無法查看該文件。

IPFS 使用傳輸加密,但不使用內(nèi)容加密。這意味著您的數(shù)據(jù)在從一個(gè) IPFS 節(jié)點(diǎn)發(fā)送到另一個(gè)節(jié)點(diǎn)時(shí)是安全的。但是,如果擁有 CID,任何人都可以下載和查看該數(shù)據(jù)。缺乏內(nèi)容加密是一個(gè)有意的決定。您可以自由選擇最適合您的項(xiàng)目的方法,而不是強(qiáng)迫您使用特定的加密協(xié)議。

如果您精通命令行并且只想立即啟動(dòng)并運(yùn)行 IPFS,請(qǐng)遵循此快速入門指南。請(qǐng)注意,本指南假定您將安裝 go-ipfs,這是用 Go 編寫的參考實(shí)現(xiàn)。

ipfs將其所有設(shè)置和內(nèi)部數(shù)據(jù)存儲(chǔ)在稱為 存儲(chǔ)庫的目錄中。 在第一次使用 IPFS 之前,您需要使用以下ipfs init命令初始化存儲(chǔ)庫:

如果您在數(shù)據(jù)中心的服務(wù)器上運(yùn)行,則應(yīng)使用server配置文件初始化 IPFS。這樣做會(huì)阻止 IPFS 創(chuàng)建大量數(shù)據(jù)中心內(nèi)部流量來嘗試發(fā)現(xiàn)本地節(jié)點(diǎn):

您可能需要設(shè)置大量其他配置選項(xiàng) — 查看完整參考 (打開新窗口)更多。

后面的散列peer identity:是您節(jié)點(diǎn)的 ID,與上面輸出中顯示的不同。網(wǎng)絡(luò)上的其他節(jié)點(diǎn)使用它來查找并連接到您。如果需要,您可以隨時(shí)運(yùn)行ipfs id以再次獲取它。

現(xiàn)在,嘗試運(yùn)行在ipfs init. 那個(gè)樣子ipfs cat /ipfs/ /readme。

您應(yīng)該看到如下內(nèi)容:

您可以 探索 存儲(chǔ)庫中的其他對(duì)象。特別是quick-start顯示示例命令嘗試的目錄:

準(zhǔn)備好將節(jié)點(diǎn)加入公共網(wǎng)絡(luò)后,在另一個(gè)終端中運(yùn)行 ipfs 守護(hù)程序,并等待以下所有三行顯示您的節(jié)點(diǎn)已準(zhǔn)備好:

記下您收到的 TCP 端口。如果它們不同,請(qǐng)?jiān)谙旅娴拿钪惺褂媚摹?/p>

現(xiàn)在,切換回原來的終端。如果您已連接到網(wǎng)絡(luò),您應(yīng)該能夠在運(yùn)行時(shí)看到對(duì)等方的 IPFS 地址:

這些是 /p2p/ .

現(xiàn)在,您應(yīng)該能夠從網(wǎng)絡(luò)中獲取對(duì)象了。嘗試:

使用上述命令,IPFS 在網(wǎng)絡(luò)中搜索 CIDQmSgv...并將數(shù)據(jù)寫入spaceship-launch.jpg桌面上調(diào)用的文件中。

接下來,嘗試將對(duì)象發(fā)送到網(wǎng)絡(luò),然后在您喜歡的瀏覽器中查看它。以下示例curl用作瀏覽器,但您也可以在其他瀏覽器中打開 IPFS URL:

您可以通過轉(zhuǎn)到 來查看本地節(jié)點(diǎn)上的 Web 控制臺(tái)localhost:5001/webui。這應(yīng)該會(huì)彈出一個(gè)這樣的控制臺(tái):

Web 控制臺(tái)顯示可變文件系統(tǒng) (MFS)中的文件。MFS 是內(nèi)置于 Web 控制臺(tái)的工具,可幫助您以與基于名稱的文件系統(tǒng)相同的方式導(dǎo)航 IPFS 文件。

當(dāng)您使用CLI 命令ipfs add ...添加文件時(shí),這些文件不會(huì)自動(dòng)在 MFS 中可用。要查看您使用 CLI 添加的 IPFS 桌面中的文件,您必須將文件復(fù)制到 MFS:

—END—

開源協(xié)議:MIT License

開源地址:


當(dāng)前名稱:go語言libp2p,Go語言圣經(jīng)
鏈接分享:http://weahome.cn/article/hecsjs.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部