星际文件系统是一种点对点的分布式文件系统, 旨在链接全部有相同的文件系统的计算机设备。在某些方面, IPFS相似于web, 但web 是中心化的,而IPFS是一个单一的Bittorrent 群集, 用git 仓库分布式存储。换句话说, IPFS 提供了高吞吐量的内容寻址块存储模型, 具备内容寻址的超连接。这造成了一个广义的Merkle DAG 数据结构,能够用这个数据结构构建版本文件系统,区块链,甚至是永久性网站。。IPFS 结合了分布式哈希表, 带有激励机制的块交换和自我认证命名空间。IPFS 没有单故障点, 节点不须要相互信任。node
在全球分布式文件系统这领域, 已经有许多人的尝试。一些系统已经取得了重大的成功, 而不少却彻底失败了。在学术尝试中, AFS【6】就是成功的例子,现在已经获得普遍的应用, 然而,其余的【7, ?】却没有获得相同的结果。在学术界以外,应用最普遍的是面向音视频媒体的点对点文件共享系统。 最值得注意的是, Napster, KaZaA 和BitTorrent[2]部署的文件分发系统支持1亿用户的同时在线。即便在今天, BitTorrent 也维持着天天千万节点的活跃数。 基于这些学术文件系统理论而实现的应用程序有不少的用户量, 然而,这些系统理论是在应用层,而没有放在基础层。以至没有出现通用的文件系统基础框架, 给全球提供低延迟的分发。
也许是由于HTTP这样“足够好“的系统已经存在。到目前为止,HTTP已经做为“分布式文件系统“的协议,而且已经大量部署,再与浏览器相结合,具备巨大的技术和社会影响力。在如今, 它已经成为互联网传输文件的事实标准。然而,他没有采用最近15年的发明的数十种先进的文件分发技术。 从一方面讲, 因为向后兼容的限制 和 当前新模式的投入, 不断发展http web 的基础设施几乎是不可能的。但从一个角度看, 从http 出现以来, 已经有许多新协议出现并被普遍使用。升级http协议虽然能引入新功能和增强当前http协议,但会下降用户的体验。
有些行业已经摆脱使用HTTP 这么久, 由于移动小文件相对便宜,即便对拥有大流量的小组织也是如此。可是,随着新的挑战,咱们正在进入数据分发的新纪元。git
虽然一些对等文件系统直接在DHT中存储数据块,这种“数据存储在不须要的节点会乱费存储和带宽”[5]。Coral DSHT扩展了Kademlia三个特别重要的方式:web
6.分布式版本改变对其余用户而言只是转移对象和更新远程引用。算法
SFS [ 12,11 ]提出了两个引人注目的实现(a)分布式信任链,和(b)平等共享的全局命名空间。SFS引入了一种自我建构技术—注册文件:寻址远程文件系统使用如下格式:数据库
1
2
3
|
/sfs/<Location>:<HostID>
Location:表明的是服务网络地方
HostID = hash(public_key || Location)
|
所以SFS文件系统的名字认证了它的服务,用户能够经过服务提供的公钥来验证,协商一个共享的私钥,保证全部的通讯。全部的SFS实例都共享了一个全局的命名空间,这个命名空间的名称分配是加密的,不被任何中心化的body控制。数组
IPFS是一个分布式文件系统,它综合了之前的对等系统的成功想法,包括DHT,BitTorrent,Git和SFS。 IPFS的贡献是简化,发展和将成熟的技术链接成一个单一的内聚系统,大于其部分的总和。 IPFS提供了编写和部署应用程序的新平台,以及一个新的分发系统版本化大数据。 IPFS甚至能够演进网络自己。
IPFS是点对点的;没有节点是特权的。 IPFS节点将IPFS对象存储在本地存储中。节点彼此链接并传输对象。这些对象表示文件和其余数据结构。 IPFS协议分为一组负责不一样功能的子协议:
1. 身份 - 管理节点身份生成和验证。描述在3.1节。
2.网络 - 管理与其余对等体的链接,使用各类底层网络协议。可配置的。详见3.2节。
3.路由 - 维护信息以定位特定的对等体和对象。响应本地和远程查询。默认为DHT,但可更换。在3.3节描述。
4.交换 - 一种支持有效块分配的新型块交换协议(BitSwap)。模拟市场,弱化数据复制。贸易策略可替换。描述在3.4节。
5.对象 - 具备连接的内容寻址不可更改对象的Merkle DAG。用于表示任意数据结构,例如文件层次和通讯系统。详见第3.5节。
6.文件 - 由Git启发的版本化文件系统层次结构。详见3.6节。
7.命名 - 自我认证的可变名称系统。详见3.7节。
这些子系统不是独立的;它们是集成在一块儿,互相利用各自的属性。可是,分开描述它们是有用的,从下到上构建协议栈。符号:Go语言中指定了如下数据结构和功能浏览器
节点由NodeId标识,这是使用S / Kademlia的静态加密难题[1]建立的公钥的密码散列。节点存储其公私钥(用密码加密)。用户能够在每次启动时自由地设置一个“新”节点身份,尽管这会损失积累的网络利益。激励节点保持不变。缓存
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
type NodeId Multihash
type Multihash []byte // 自描述加密哈希摘要
type PublicKey []byte
type PrivateKey []byte // 自描述的私钥
type Node struct {
NodeId NodeID
PubKey PublicKey
PriKey PrivateKey
}
基于S / Kademlia的IPFS身份生成:
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)
|
首次链接时,对等体交换公钥,并检查:hash(other.PublicKey)等于other.NodeId。若是没有,则链接被终止
关于加密函数的注意事项:
IPFS不是将系统锁定到一组特定的功能选择,而是支持自我描述的值。哈希摘要值以多重哈希格式存储,其包括指定使用的哈希函数的头和以字节为单位的摘要长度。例如:安全
1
|
<function code><digest length><digest bytes>
|
这容许系统服务器
1
2
3
4
|
# an SCTP/IPv4 connection
/ip4/10.20.30.40/sctp/1234/
# an SCTP/IPv4 connection proxied over TCP/IPv4
/ip4/5.6.7.8/tcp/5678/ip4/1.2.3.4/sctp/1234/
|
IPFS节点须要一个路由系统, 这个路由系统可用于查找:
1
2
3
4
5
6
7
|
type IPFSRouting interface {
FindPeer(node NodeId)
// 获取特定NodeId的网络地址。
SetValue(key []bytes, value []bytes)
// 往DHT存储一个小的元数据。
GetValue(key []bytes)
// 从DHT获取元数据。
ProvideValue(key Multihash)
// 声明这个节点可一个提供一个大的数据。
FindValuePeers(key Multihash, min
int) // 获取服务于该大数据的节点。
}
|
注意:不一样的用例将要求基本不一样的路由系统(例如广域网中使用DHT,局域网中使用静态HT)。所以,IPFS路由系统能够根据用户的需求替换的。只要使用上面的接口就能够了,系统都能继续正常运行。
IPFS 中的BitSwap协议受到BitTorrent 的启发,经过对等节点间交换数据块来分发数据的。像BT同样, 每一个对等节点在下载的同时不断向其余对等节点上传已下载的数据。和BT协议不一样的是, BitSwap 不局限于一个torrent文件中的数据块。BitSwap 协议中存在一个永久的市场。 这个市场包括各个节点想要获取的全部块数据。而无论这些块是哪些如.torrent文件中的一部分。这些快数据可能来自文件系统中彻底不相关的文件。 这个市场是由全部的节点组成的。
虽然易货系统的概念意味着能够建立虚拟货币,但这将须要一个全局分类帐原本跟踪货币的全部权和转移。这能够实施为BitSwap策略,并将在将来的论文中探讨。
在基本状况下,BitSwap节点必须以块的形式彼此提供直接的值。只有当跨节点的块的分布是互补的时候,各取所需的时候,这才会工做的很好。 一般状况并不是如此,在某些状况下,节点必须为本身的块而工做。 在节点没有其对等节点所需的(或根本没有的)状况下,它会更低的优先级去寻找对等节点想要的块。这会激励节点去缓存和传播稀有片断, 即便节点对这些片断不感兴趣。
这个协议必须带有激励机制, 去激励节点去seed 其余节点所须要的块,而它们自己是不须要这些块的。 所以, BitSwap的节点很积极去给对端节点发送块,期待得到报酬。但必须防止水蛭攻击(空负载节点从不共享块),一个简单的相似信用的系统解决了这些问题:
1
|
r = bytes_sent / bytes_recv + 1
|
根据r,发送到负债节点的几率为:
1
|
P(send | r ) = 1 − ( 1/ ( 1 + exp(6 − 3r) ) )
|
正如你看到的图片1,当节点负债比例超过节点已创建信贷的两倍,发送到负债节点的几率就会急速降低。
图片1 当r增长时发送的几率
负债比是信任的衡量标准:对于以前成功的互换过不少数据的节点会宽容债务,而对不信任不了解的节点会严格不少。这个(a)给与那些创造不少节点的攻击者(sybill 攻击)一个障碍。(b)保护了以前成功交易节点之间的关系,即便这个节点暂时没法提供数据。(c)最终阻塞那些关系已经恶化的节点之间的通讯,直到他们被再次证实。
BitSwap节点保存了一个记录与全部其余节点之间交易的帐本。这个可让节点追踪历史记录以及避免被篡改。当激活了一个连接,BitSwap节点就会互换它们帐本信息。若是这些帐本信息并不彻底相同,分类帐本将会从新初始化, 那些应计信贷和债务会丢失。 恶意节点会有意去失去“这些“帐本, 从而指望清除本身的债务。节点是不太可能在失去了应计信托的状况下还能累积足够的债务去受权认证。伙伴节点能够自由的将其视为不当行为, 拒绝交易。
1
2
3
4
5
6
7
|
type Ledger struct {
owner NodeId
partner NodeId
bytes_sent
int
bytes_recv
int
timestamp Timestamp
}
|
节点能够自由的保留分布式帐本历史,这不须要正确的操做,由于只有当前的分类帐本条目是有用的。节点也能够根据须要自由收集分布式账本,从不太有用的分布式账开始:老(其余对等节点可能不存在)和小。
BitSwap 节点有如下简单的协议。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
// 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);
}
|
对等链接的生命周期草图:
IPFS对象的格式是:
1
2
3
4
5
6
7
8
9
10
|
type IPFSLink struct {
Name
string // 此link的别名
Hash Multihash
// 目标的加密hash
Size
int // 目标总大小
}
type IPFSObject struct {
links []IPFSLink
//links数组
data []
byte //不透明内容数据
}
|
IPFS Merkle DAG是存储数据很是灵活的一种方式。只要求对象引用是(a)内容可寻址的,(b)用上面的格式编码。IPFS容许应用彻底的掌控数据域;应用可使用任何自定义格式的数据,即便数据IPFS都没法理解。单独的内部对象link表容许IPFS作:
1
2
3
4
5
6
|
> ipfs ls /XLZ1625Jjn7SubMDgEyeaynFuR84ginqvzb
XLYkgq61DYaQ8NhkcqyU7rLcnSa7dSHQ16x 189458 less
XLHBNmRQ5sJJrdMPuu48pzeyTtRo39tNDR5 19441 script
XLF4hwVHsVuZ78FZK6fozf8Jj9WEURMbCX4 5286 template
<object multihash> <object size> <link name>
|
1
2
3
4
5
6
|
> ipfs refs --recursive \
/XLZ1625Jjn7SubMDgEyeaynFuR84ginqvzb
XLLxhdgJcXzLbtsLRL1twCHA2NrURp4H38s
XLYkgq61DYaQ8NhkcqyU7rLcnSa7dSHQ16x
XLHBNmRQ5sJJrdMPuu48pzeyTtRo39tNDR5
XLWVQDqxo9Km9zLyquoC9gAP8CL1gWnHZ7z
|
原始数据结构公共link结构是IPFS构建任意数据结构的必要组成部分。能够很容易看出Git的对象模型是如何套用DAG的。一些其余潜在的数据结构:
IPFS对象能够遍历一个字符串路经。路经格式与传统UNIX文件系统以及Web一致。Merkle DAG的links使遍历变得很容易。全称路经在IPFS中的格式是:
1
2
3
4
|
*# 格式
/ipfs/<hash-of-object>/<name-path-to-object>
*# 例子
/ipfs/XLYkgq61DYaQ8NhkcqyU7rLcnSa7dSHQ16x/foo.txt
|
/ipfs前缀容许只要在挂载点不冲突(挂载点名称固然是可配置的)的状况下挂载到一个已存在的系统上。第二个路经组成部分(第一个是IPFS)是一个对象的hash。一般都是这种状况,由于没有全局的根。一个根对象可能会有一个不可能完成的任务,就是在分布式环境(可能还断开连接)中处理百万对象的一致性。所以,咱们用地址可寻址来模拟根。经过的hash全部的对象都是可访问的。这意思是说,给一个路经对象/bar/baz,最后一个对象能够能够被全部的访问的:
1
2
3
|
/ipfs/<hash-of-foo>/bar/baz
/ipfs/<hash-of-bar>/baz
/ipfs/<hash-of-baz>
|
IPFS客户端须要一个本地存储器,一个外部系统能够为IPFS管理的对象存储以及检索本地原始数据。存储器的类型根据节点使用案例不一样而不一样。在大多数状况下,这个存储器只是硬盘空间的一部分(不是被本地的文件系统使用键值存储如leveldb来管理,就是直接被IPFS客户端管理),在其余的状况下,例如非持久性缓存,存储器就是RAM的一部分。
最终,全部的块在IPFS中都是可以获取的到的,块都存储在了一些节点的本地存储器中。当用户请求一个对象时,这个对象会被查找到并下载下来存储到本地,至少也是暂时的存储在本地。这为一些可配置时间量提供了快速的查找。
但愿确保特定对象生存的节点能够锁定此对象。这保证此特定对象被保存在了节点的本地存储器上。也能够递归的进行锁定全部相关的派生对象。这使全部被指定的对象都保存在本地存储器上。这对长久保存文件特别有用,包括引用。这也一样让IPFS成为一个links是永久的Web,且对象能够确保其余被指定对象的生存。
IPFS是全球分布的。它设计为容许成千上万的用户文件能够共同的存在的。DHT使用内容哈希寻址技术,使发布对象是公平的,安全的,彻底分布式的。任何人均可以发布对象,只须要将对象的key加入到DHT中,而且以对象是对等节点的方式加入进去,而后把路径给其余的用户。要注意的是,对象本质上是不可改变的,就像在Git中同样。新版本的哈希值不一样,所以是新对象。跟踪版本则是额外版本对象的工做。
IPFS是具有能够处理对象级别加密操做的。一个已加密的或者已签名的对象包装在一个特殊的框架里,此框架容许加密和验证原始字节。
1
2
3
4
5
6
7
8
|
type EncryptedObject struct {
Object []bytes
// 已加密的原始对象数据
Tag []bytes
// 可选择的加密标识
type SignedObject struct {
Object []bytes
// 已签名的原始对象数据
Signature []bytes
// HMAC签名
PublicKey []multihash
// 多重哈希身份键值
}
|
加密操做改变了对象的哈希值,定义一个不一样的新的对象。IPFS自动的验证签名以及使用用户指定的钥匙链解密数据。加密数据的links也一样的被保护着,没有解密秘钥就没法遍历对象。也存在着一种现象,可能父对象使用了一个秘钥进行了加密,而子对象使用了另外一个秘钥进行加密或者根本没有加密。这能够保证links共享对象安全。
IPFS在Merkle DAG上还为模型化版本文件系统定义了一组对象。这个对象模型与Git比较类似:
Block:一个可变大小的数据块
List:块或者其余链表的集合
Tree:块,链表,或者其余树的集合
Commit:树在版本历史记录中的一个快照
我本来但愿使用与Git对象格式一致的模型,但那就必需要分开来引进在分布式文件系统中有用的某些特征,如
1
2
3
|
{
"data": "some data here", // blobs无links
}
|
List对象表明着由几个IPFS的blobs链接成的大文件或者重复数据删除文件。Lists包含着有序的blob序列或list对象。从某种程度上而言,IPFS的list函数就像一个间接块的文件系统。因为lists能够包含其余的lists,那么包含linked的链表和平衡树的拓扑结构是有可能的。有向图中相同的节点出如今多个不一样地方容许在文件中重复数据删除。固然,循环是不能够能的,由于是被哈希寻址强制实行的。
1
2
3
4
5
6
7
8
9
10
11
|
{
"data": ["blob", "list", "blob"], //lists有一个对象类型的数组做为数据
"links": [
{ "hash": "XLYkgq61DYaQ8NhkcqyU7rLcnSa7dSHQ16x",
"size": 189458 },
{ "hash": "XLHBNmRQ5sJJrdMPuu48pzeyTtRo39tNDR5",
"size": 19441 },
{ "hash": "XLWVQDqxo9Km9zLyquoC9gAP8CL1gWnHZ7z",
"size": 5286 } //在links中lists是没有名字的
]
}
|
IPFS中的tree对象与Git中类似,它表明着一个目录,一个名字到哈希值的映射。哈希值则表示着blobs,lists,其余的trees,或者commits。注意,传统路径的命名早已经被Merkle DAG实现了。
1
2
3
4
5
6
7
8
9
10
11
|
{
"data": ["blob", "list", "blob"],//trees有一个对象类型的数组做为数据
"links": [
{ "hash": "XLYkgq61DYaQ8NhkcqyU7rLcnSa7dSHQ16x",
"name": "less", "size": 189458 },
{ "hash": "XLHBNmRQ5sJJrdMPuu48pzeyTtRo39tNDR5",
"name": "script", "size": 19441 },
{ "hash": "XLWVQDqxo9Km9zLyquoC9gAP8CL1gWnHZ7z",
"name": "template", "size": 5286 }//trees是有名字的
]
}
|
IPFS中的commit对象表明任何对象在版本历史记录中的一个快照。与Git中相似,可是它可以表示任何类型的对象。它一样link着发起对象。
Commit对象表明着一个对象在历史版本中的一个特定快照。在两个不一样的commit中比较对象(和子对象)能够揭露出两个不一样版本文件系统的区别。只要commit和它全部子对象的引用是可以被访问的,全部前版本是可获取的,全部文件系统改变的所有历史是可访问的,这就与Merkle DAG对象模型脱离开来了。
Git版本控制工具的全部功能对于IPFS的用户是可用的。对象模型不彻底一致,但也是可兼容的。这可能
版本控制和分发大文件其中一个最主要的挑战是:找到一个正确的方法来将它们分隔成独立的块。与其认为IPFS能够为每一个不一样类型的文件提供正确的分隔方法,不如说IPFS提供了如下的几个可选选择:
就像在LIBFS[?]中同样使用Rabin Fingerprints [?]来选择一个比较合适的块边界。
使用rsync[?] rolling-checksum算法,来检测块在版本之间的改变。
容许用户指定专为特定文件而调整的’快分隔’函数。
基于路径的访问须要遍历对象图。获取每一个对象要求在DHT中查找它们的key,链接到对等节点,而后获取它的块。这形成至关大的开销,特别是查找的路径由不少子路径组成时。下面的方法能够减缓开销:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
{
"data":
["tree", "blob", "tree", "list", "blob" "blob"],
"links": [
{ "hash": "<ttt222-hash>", "size": 1234
"name": "ttt222-name" },
{ "hash": "<bbb111-hash>", "size": 123,
"name": "ttt222-name/bbb111-name" },
{ "hash": "<ttt333-hash>", "size": 3456,
"name": "ttt333-name" },
{ "hash": "<lll111-hash>", "size": 587,
"name": "ttt333-name/lll111-name"},
{ "hash": "<bbb222-hash>", "size": 22,
"name": "ttt333-name/lll111-name/bbb222-name" },
{ "hash": "<bbb222-hash>", "size": 22
"name": "bbb222-name" }
] }
|
目前为止,IPFS桟造成了一个对等块交换组成一个内容可寻址的DAG对象。这提供了发布和获取不可改变的对象。这甚至能够跟踪这些对象的版本历史记录。可是,这里有一个关键成分遗漏了:易变的命名。没有这个,发送IPFS的links,全部新内容的通讯确定都会有所误差。如今所需就是能有某些方法能够获取相同路径的的易变状态。
这值得详述缘由—若是最终易变数据是必须的—咱们费了很大的力气构建了一个不可改变的Merkle DAG。就当作IPFS脱离了Merkle DAG的特征:对象能够
不可变的内容可寻址对象和命名的Merkle DAG, 可变指针指向Merkle DAG,实例化了一个出如今不少成功分布式系统中的二分法。这些系统包括Git的版本控制系统,使用不可变的对象和可变的引用;还有UNIX分布式的继承者Plan9[?]文件系统,使用可变的Fossil和不可变的Venti[?]。LBFS[?]一样使用可变的索引以及不可变的块。
使用SFS[12,11]中的命名方案,给咱们提供了一个种能够构建自我认证名称的方法,
在一个加密指定的全局命名空间中,这是可变的。IPFS的方案以下:
注意下面的细节:
由于这不是一个内容可寻址的对象,因此发布它就要依靠IPFS中的惟一的可变状态分配制度,路由系统。过程是(a)首先把此对象作一个常规的不可变IPFS的对象来发布(b)将此对象的哈希值做为元数据的值发布到路由系统上:
1
|
routing.setValue(NodeId, <ns-object-hash>)
|
发布的对象中任何links在命令空间中充当子名称:
1
2
3
|
/ipns/XLF2ipQ4jD3UdeX5xp1KBgeHRhemUtaA8Vm/
/ipns/XLF2ipQ4jD3UdeX5xp1KBgeHRhemUtaA8Vm/docs
/ipns/XLF2ipQ4jD3UdeX5xp1KBgeHRhemUtaA8Vm/docs/ipfs
|
通常建议发布一个commit对象或者其余对象的时候,要使用历史版本记录,由于这样就用户就能够找到以前使用过的名字。不过因为这并不老是须要的,因此留个用户本身选择。
注意当用户发布一个对象的时候,他不能使用相同的方式来发布对象。
IPNS的确是一个分配和在分配名称的好方法,可是对用户却不是十分友好的,由于它使用很长的哈希值做为名称,众所周知这样的名称很难被记住。IPNS足够应付URLs,但对于不少线下的传输工做就没有这么好用了。所以,IPFS使用下面的技术来增长IPNS的用户友好度。
对等节点Links
被SFS所鼓舞,用户能够直接将其余用户的对象link到本身的对象上(命令空间,家目录等等)。这有一个好处就是建立了一个可信任的Web(也支持老的真实性认证模型):
1
2
3
4
5
6
7
8
|
# Alice links 到Bob上
ipfs link /<alice-pk-hash>/friends/bob /<bob-pk-hash>
# Eve links 到Alice上
ipfs link /<eve-pk-hash/friends/alice /<alice-pk-hash>
# Eve 也能够访问Bob
/<eve-pk-hash/friends/alice/friends/bob
# 访问Verisign 认证域
/<verisign-pk-hash>/foo.com
|
DNS TXT IPNS 记录
若是/ipns/是一个有效的域名称,IPFS会在DNS TXT记录中查找关键的ipns。IPFS会将查找到的值翻译为一个对象的哈希值或者另外一个ipns的路径:
1
2
3
4
|
# DNS TXT 记录
ipfs.benet.ai. TXT "ipfs=XLF2ipQ4jD3U ..."
# 表现为符号连接
ln -s /ipns/XLF2ipQ4jD3U /ipns/fs.benet.ai
|
Proquint 可读的标识符
老是会有将二进制编码翻译成可读文件的方法。IPNS则支持Proquint[?].。以下:
1
2
3
4
|
# proquint语句
/ipns/dahih-dolij-sozuk-vosah-luvar-fuluh
# 分解为相应的下面形式
/ipns/KhAwNprxYVxKqpDZ
|
缩短名称服务
会涌现出不少服务器提供缩短名称的服务,向用户提供他们的命名空间。就像咱们如今看到的DNS和Web的URLs:
1
2
3
4
|
# 用户能够从下面获取一个link
/ipns/shorten.er/foobar
# 而后放到本身的命名空间
/ipns/XLF2ipQ4jD3UdeX5xp1KBgeHRhemUtaA8Vm
|
IPFS设计为可使用多种不一样的方法来使用的,下面就是一些我将会继续追求的使用方式: