Short intro to IPFS === What is IPFS? --- IPFS is a decentralized file distributing system based on peer-to-peer protocol, adding any content on it is like broadcast a unique self-describe torrent file to every peer connected and start to seed the file. Files will remain on the internet until there's no node seeding it. IPFS could be seen as a single BitTorrent swarm, exchanging objects within one Git repository. Easy instruction --- ### Useful command ``` ipfs init //initialize ipfs id //view node id ipfs add <path to Files/Folders> [-r] [-w] //add file to ipfs //-r for recursive -w for keeping directory structure ipfs cat <ipfs-path> //view file ipfs get <ipfs-path> //download file ipfs ls <ipfs-path-of-directory> //list file in directory ``` ### Going online ``` ipfs daemon //run ipfs online ipfs name publish <ipfs-path> //using ipns feature, public files to your nodeid ``` after running daemon, you can use web console http://localhost:5001/webui ### Using official gateway to view files https://ipfs.io/ipfs/<ipfs-path> https://ipfs.io/ipns/<nodeid>/[path-to-file] ### Official Demo {%youtube 8CMxDNuuAiQ %} IPFS design --- The IPFS Protocol is divided into a stack of sub-protocols: - Identities - Network - Routing - Exchange - Objects - Files - Naming reference: https://github.com/ipfs/specs ### Identities Nodes are identified by NodeId, which is a hashed public key(default RSA2048), >key generation 的計算 >[color=red] ```go type PrivateKey []byte // self-describing keys type Node struct { NodeId NodeID PubKey PublicKey PriKey PrivateKey } ``` and required PoW while establishing it.(In order to prevent sybil attack) >https://www.twcert.org.tw/assets/pdf/SybiAttack.pdf ```go difficulty = <integer parameter> n = Node{} do { n.PubKey, n.PrivKey = PKI.genKeyPair() n.NodeId = hash(n.PubKey) p = count_preceding_zero_bits(hash(n.NodeId)) } while (p < difficulty) ``` >p = count_preceding_zero_bits(hash(n.NodeId)) >why?[color=red][name=7/12討論] Upon first connecting, peers exchange public keys, and check: **hash(other.PublicKey) equals other.NodeId**. If not, the connection is terminated. ### Network >firewall 可以過嗎? ->多分おk >[color=red][name=7/12討論] ``` 12:42:06.468 DEBUG engine: wants QmaBCkhaeaaCzEKK1K9xzL39vMaXjA6QU1aERqSoXfVJmm - 2147483617 engine.go:241 12:42:06.468 DEBUG engine: peer <peer.ID SoLju6> wants QmaBCkhaeaaCzEKK1K9xzL39vMaXjA6QU1aERqSoXfVJmm ledger.go:80 12:42:19.996 INFO bitswap: Sending block [Block QmaBCkhaeaaCzEKK1K9xzL39vMaXjA6QU1aERqSoXfVJmm] to <peer.ID SoLju6> wantmanager.go:117 12:42:23.881 DEBUG engine: <peer.ID SoLju6> cancel QmaBCkhaeaaCzEKK1K9xzL39vMaXjA6QU1aERqSoXfVJmm engine.go:237 12:42:39.681 DEBUG dht: <peer.ID boMjby> adding <peer.ID SoLju6> as a provider for 'QmaBCkhaeaaCzEKK1K9xzL39vMaXjA6QU1aERqSoXfVJmm' 12:42:39.681 INFO dht: received provider <peer.ID SoLju6> for QmaBCkhaeaaCzEKK1K9xzL39vMaXjA6QU1aERqSoXfVJmm (addrs: [/ip4/127.0.0.1/tcp/4001 /ip4/104.236.151.122/tcp/4001 /ip4/10.12.0.5/tcp/4001 /ip4/172.17.0.1/tcp/4001 /ip6/::1/tcp/4001 /ip6/2604:a880:1:20::1d9:6001/tcp/4001 /ip6/fc3d:9a4e:3c96:2fd2:1afa:18fe:8dd2:b602/tcp/4001 /ip4/127.0.0.1/tcp/8081/ws /ip4/104.236.151.122/tcp/4001]) handlers.go:291 ``` IPFS can use any network, it stores addresses as **multiaddr** formatted byte strings for the underlying network to use. It can also connect to local network, and have local swarm peers. For example : > SCTP/IPv4 connection /ip4/10.20.30.40/sctp/1234/ > SCTP/IPv4 connection proxied over TCP/IPv4 /ip4/5.6.7.8/tcp/5678/ip4/1.2.3.4/sctp/1234/ ### Routing IPFS use a DSHT(Distributed Sloppy Hash Table) based on **S/Kademlia** and **Coral**. >Coral 的特性? V.S. bitTorrent DHT >routing 的意義? => Searching for node or data >[color=red][name=7/12討論] DSHT: >A sloppy insert is akin to an append in which a replica pointer appended to a “full” node spills over to the previous node in the lookup path. A sloppy retrieve only returns some randomized subset of the pointers stored under a given key. http://iptps03.cs.berkeley.edu/final-papers/coral.pdf IPFS DHT makes a distinction for values stored based on their size, small values (equal to or less than 1KB) are stored directly on the DHT, and for values larger, the DHT stores references, which are the NodeIds of peers who can serve the block. useful refs:https://github.com/ipfs/examples/blob/master/examples/data/readme.md (1KB的小檔案快取目前並沒有實做) >1KB 是檔案大小還是 block? -> 檔案大小 >一剛開始決定的 block 大小? >var BlockSizeLimit = 1048576 //1 MB >[name=7/19會議][color=green] ```go type IPFSRouting interface { FindPeer(node NodeId) // gets a particular peer's network address SetValue(key []bytes, value []bytes) // stores a small metadata value in DHT GetValue(key []bytes) // retrieves small metadata value from DHT ProvideValue(key Multihash) // announces this node can serve a large value FindValuePeers(key Multihash, min int) // gets a number of peers serving a large value } ``` ### Block Exchange >清楚的示意圖 >[color=red][name=7/12討論] IPFS use a Bittorrent inspired protocal: **BitSwap** to exchange blocks. It use a **credit-like system** to incentivice nodes to seed and punish the leechers. Let the ***debt ratio*** **r** between a node and its peer be: $$r = \frac{bytes\_sent}{bytes\_recv+1}$$ and the *probability* of sending to a debtor be: $$P(send|r) = 1-\frac{1}{1+exp(6-3r)}$$ The relation between $P$ and $r$: ![imgur](http://i.imgur.com/hEHppKW.png) So, the more bytes a peer send to you, the more probability you send bytes to him. In the case that a node has nothing that its peers want (or nothing at all), **it seeks the pieces its peers want, with lower priority** (cache) than what the node wants itself. This incentivizes nodes to cache and disseminate rare pieces, even if they are not interested in them directly. BitSwap nodes also keep **ledgers** accounting the transfers with other nodes. >懲罰機制? >[name=7/12討論][color=red] ```go type Ledger struct { owner NodeId partner NodeId bytes_sent int bytes_recv int timestamp Timestamp } ``` Bitswap protocol specification : ```go // Additional state kept type BitSwap struct { ledgers map[NodeId]Ledger // Ledgers known to this node, inc inactive active map[NodeId]Peer // currently open connections to other nodes need_list []Multihash // checksums of blocks this node needs have_list []Multihash // checksums of blocks this node has } type Peer struct { nodeid NodeId ledger Ledger // Ledger between the node and this peer last_seen Timestamp // timestamp of last received message want_list []Multihash // checksums of all blocks wanted by peer // includes blocks wanted by peer's peers } // Protocol interface: interface Peer { open (nodeid :NodeId, ledger :Ledger); send_want_list (want_list :WantList); send_block (block :Block) -> (complete :Bool); close (final :Bool); } ``` >上方 Peer 程式碼 interface & struct? -> 僅為示意,語法是錯的 >[color=green][name=7/19會議] Sketch of the lifetime of a peer connection: 1. Open: peers send ledgers until they agree. 2. Sending: peers exchange want_lists and blocks. 3. Close: peers deactivate a connection. 4. Ignored: (special) a peer is ignored (for the duration of a timeout) if a node's strategy avoids sending ### Objects IPFS builds a **Merkle DAG**[^first], a directed acyclic graph where links between objects are cryptographic hashes of the targets embedded in the sources. This is a generalization of the **Git data structure**. [^first]:確保交易的順序 It provides some useful propoties, including: 1. **Content Addressing**: all content is uniquely identied by its multihash checksum, including links. 2. **Tamper resistance**: all content is verified with its checksum. If data is tampered with or corrupted, IPFS detects it. 3. **Deduplication**: all objects that hold the exact same content are equal, and only stored once. This is par- ticularly useful with index objects, such as git trees and commits, or common portions of data. ### Path to Files After add file into IPFS, one can view the content by browsing gateway with #### Format > /ipfs/<hash-of-object>/<name-path-to-object> #### Example > /ipfs/XLYkgq61DYaQ8NhkcqyU7rLcnSa7dSHQ16x/foo.txt > /ipfs/<hash-of-foo>/bar/baz.txt > /ipfs/<hash-of-bar>/baz.txt > /ipfs/<hash-of-baz> ### Naming By using **IPNS**, one can access a mutable file with same link. Example: > /ipns/XLF2ipQ4jD3UdeX5xp1KBgeHRhemUtaA8Vm/ > /ipns/XLF2ipQ4jD3UdeX5xp1KBgeHRhemUtaA8Vm/docs > /ipns/XLF2ipQ4jD3UdeX5xp1KBgeHRhemUtaA8Vm/docs/ipfs It also provide **Peer link** feature let users can link other users' objects directly into their own objects. **[NOT implement]** > Alice links to bob Bob > ipfs link /<alice-pk-hash>/friends/bob /<bob-pk-hash> > Eve links to Alice > ipfs link /<eve-pk-hash/friends/alice /<alice-pk-hash> >Eve also has access to Bob /<eve-pk-hash/friends/alice/friends/bob >access Verisign certified domains /<verisign-pk-hash>/foo.com >上傳的文件會存在多久? >有 url,有無可能完全存取不到? >[color=green][name=7/19討論]