IPFS数据模型-IPLD

ipld.io

Github:ipld

原文:IPLD specs

有许多系统使用和受启发的数据结构(例如git,bittorrent,ipfs,tahoe-lafs,sfsro)。IPLD(星际链接数据)定义:

merkle-links:merkle-graph的核心单元

merkle-dag:任何边为merkle-links的图。代表“有向无环图”

merkle-paths:使用命名的merkl-links来遍历merkl-dags的unix风格的路径。

IPLD格式:可以表示IPLD对象的一组格式,例如JSON,CBOR,CSON,YAML,Protobuf,XML,RDF等。

IPLD规范格式:一种序列化格式的确定性描述,确保相同的逻辑对象始终被序列化到相同的位序列。这对于链接和所有加密应用程序都是至关重要的。

介绍

什么是merkle-link?

merkl-link是两个对象之间的链接,它们是由目标对象的加密散列处理的,并嵌入到源对象中。merkl-links的内容寻址允许:

加密完整性检查:解析链接的值可以通过哈希来测试。反过来,这可以实现广泛,安全和可靠的数据交换(例如git或bittorrent),因为其他人不能给你任何不会散列到链接值的数据。

不可变的数据结构:带有merkle链接的数据结构不能改变,这对于分布式系统来说是一个不错的属性。这对于版本控制,表示分布式可变状态(例如CRDT)和长期存档很有用。

一个merkle-link在IPLD对象模型中由包含一个到“链接值”的映射表示。例如:

一个以json表示的“链接对象”的链接

对象为的链接

对象在的实际链接以及中的伪“链接对象”。

当取消链接时,映射本身将被它指向的对象替换,除非链接路径无效。

该链接可以是,在这种情况下,假设它是/ipfs层次结构中的链接,或者直接指向对象的绝对路径。目前,只允许使用/ipfs层次结构。

如果应用程序想要将具有单个/key的对象用于其他目的,则应用程序本身应负责转义/IPLD对象中的/key,这样应用程序的key就不会与IPLD的特殊/key发生冲突。

什么是merkle-graph或merkle-dag?

带有merkl-links的对象形成一个Graph(merkle-graph),如果加密散列函数的属性保持不变,则这些对象必然都是定向的,并且可以认为它是非循环的,即merkle-dag。因此,所有使用merkle-linking(merkle-graph)的图必定也是有向无环图(DAG,因此为merkle-dag)。

什么是merkle路径?

merkl-path是一种unix风格的路径(例如,/a/b/c/d),它最初通过merkl-link进行引用,并允许访问被引用节点和其他节点的元素。

我们鼓励通用文件系统在IPLD上设计一个对象模型,该模型将专门用于文件操作,并有特定的路径算法来查询该模型。

merkle-paths如何工作?

merkl-path是一种unix风格的路径,最初通过merkl-link进行引用,然后在中间对象中命名merkl-links。名称后面的意思是查找对象,查找名称并解析相关的merkl-link。

例如,假设我们有这个merkle-path:

路径表述:

是一个协议命名空间(允许计算机识别要做什么)

是一个加密哈希。

是一个路径遍历,就像在unix中一样。

路径遍历,用符号表示/,发生在两种链接上:

对象内遍历遍历同一对象内的数据。

跨对象遍历从一个对象遍历到另一个对象,通过merkle-link解析。

例子

使用以下数据集:

路径的一个例子:

将遍历第一个对象并获取字符串。

将遍历两个对象并获取字符串

遍历两个对象并获取字符串

遍历第一个和第二个对象并获取字符串

遍历第一个和最后一个对象并获取字符串

什么是IPLD数据模型?

IPLD数据模型为所有merkle-dag定义了一个简单的基于JSON的结构,并标识了一组格式来将结构编码进去。

限制和期望

一些限制:

IPLD路径必须是明确的。给定的路径字符串必须总是确定性地遍历到同一个对象。(例如避免重复链接名称)

IPLD路径必须是通用的,避免对非英语国家不友好(例如使用UTF-8,而不是ASCII)。

IPLD路径必须在UNIX和Web上干净地分层(使用/,对ASCII系统具有确定性的变换)。

考虑到JSON的广泛成功,大量的系统提供了JSON接口。IPLD必须能够对JSON进行简单的导入和导出。

JSON数据模型也非常简单易用。IPLD必须一样易于使用。

定义新数据结构必须非常简单。要在IPLD上尝试新的定义,不应该很麻烦,也不需要太多的知识。

由于IPLD基于JSON数据模型,因此它完全可以通过JSON-LD与RDF和关联数据标准兼容。

IPLD序列化格式(在磁盘上和在线上)必须快速且节省空间。(不应该使用JSON作为存储格式,而应使用CBOR或类似的格式)

IPLD密码哈希必须是可升级的(使用multihash)

一些不错的点:

IPLD不应该犯下错误,例如JSON中缺少整数。

IPLD应该是可升级的,例如,如果出现更好的磁盘格式,系统应该能够迁移到它之上并且最小化这样做的成本

IPLD对象应该能够解析路径的属性,而不仅仅是merkle links。

IPLD Canonical Format应该易于编写解析器。

IPLD Canonical Format应该能在不解析完整对象的情况下进行查找。(CBOR和Protobuf允许)。

格式定义

(注意:这里我们将使用JSON和YML来显示格式是什么样的。我们显式地使用这两种方法来显示不同格式的对象的等价性。)

IPLD数据模型“是JSON”,它(a)也是基于树的文档,具有一些基本类型,(b)1:1映射到JSON, (c)用户可以通过JSON本身使用它。它“不是JSON”(a)在某些错误上有所改进,(b)具有高效的序列化表示,(c)实际上并没有指定单一的on-wire格式,因为众所周知,这个世界正在改进。

基本的节点

以下是JSON中的示例IPLD对象:

假设它散列的multihash值。注意,它根本没有链接,只是一个字符串名称值。但是我们仍然能够“解析”它下面的key name:

当然,我们可以用其他格式来查看它

链接节点之间

节点之间的Merkle-Linking是IPLD存在的原因。IPLD中的链接只是一种特殊格式的嵌入式节点:

假设这个散列值为multihash值。该节点通过子路径链接到,上面这一节的节点。所以我们现在可以做到:

链接属性约定

IPLD允许用户构建复杂的数据结构,以及与链接相关的其他属性。这对编码其他信息以及链接(例如关系类型或链接中所需的辅助数据)很有用。这与下面讨论的“链接对象约定”不同,它们本身非常有用。但有时候,你只是想在链接上添加一些数据而不必创建另一个对象。IPLD不会妨碍你。您可以简单地通过将实际的IPLD链接嵌套在另一个对象中,并使用其他属性来完成。

重要提示:链接属性不允许直接在链接对象中使用,因为存在明显的歧义。阅读规格历史,了解有关难点的讨论。

例如,假设您有一个文件系统,并希望在对象之间的链接中分配类似于权限或所有者的元数据。假设你有一个哈希值为的目录对象像这样:

或YML

虽然我们在特定于此数据结构的链接中拥有新属性,但我们仍然可以很好地解析链接:

但是我们无法像其他属性那样很好地提取链接,因为链接是要通过解析的。

重复属性keys

注意,有两个同名的属性是不允许的,但实际上不可能阻止(有人会这样做并将它提供给解析器),所以为了安全起见,我们定义了路径遍历的值作为序列化表示中的第一个条目。例如,假设我们有对象:

假设这是规范格式(不是json,而是cbor)的准确顺序,并且它的散列为。我们总是得到:

路径限制

Unix和Web中的路径描述有一些重要的问题。有关讨论,请参阅此讨论。为了与unix和web的模型和期望兼容,IPLD明确禁止具有特定路径组件的路径。请注意,数据本身可能仍然包含这些属性(有人会这样做,并且有合法用途)。所以只有路径解析器不能通过这些路径来解析。这些限制与典型的unix和UTF-8路径系统相同:

todo:

[ ] 列表路径解析限制

[ ] show示例

JSON中的整型

IPLD可以直接与JSON兼容,以利用JSON的成功,但它不需要因为JSON的错误而受到限制。这是我们可以遵循格式惯用选择的地方,但必须注意确保始终存在定义明确的1:1映射。

关于整数,在JSON中存在多种表示整数为字符串的格式,例如EJSON。这些可以被使用和转换到其他格式,这是自然发生的- 也就是说,将JSON转换为CBOR时,应该将EJSON整数自然地转换为合适的CBOR整数,而不是将其表示为字符串值的映射。

序列化数据格式

IPLD通过multicodec支持各种序列化数据格式。这些可以使用,但是对于格式是惯用的,例如CBOR,我们可以使用CBOR类型tags来表示merkl-link,并避免写出完整的字符串键@link。鼓励用户充分使用这些格式,并以最有意义的任何格式存储和传输IPLD数据。唯一的要求是必须有一个明确定义的IPLD规范格式的一对一映射。这样就可以将数据从一种格式转换为另一种格式,而不必改变其含义或密码哈希值。

带标签的序列化CBOR

在CBOR中,可以使用定义在RFC 7049 section 2.4.中的标记来表示IPLD链接。

标签被定义。这个标签可以是一个文本字符串(主类型3)或者是对应于链接目标的字节字符串(主类型2)。

将IPLD“链接对象”编码到CBOR时,请使用以下算法:

提取链接值。

如果链接值是一个有效的multiaddress,并且将该链接文本转换为多地址二进制字符串,并返回到文本将保证产生完全相同的文本,则该链接将转换为存储在CBOR中的二进制多地址字节字符串(主类型2)。

否则,链接值被存储为文本(主类型3)

由此产生的编码是链接值的CBOR表示

当解码CBOR并将其转换为IPLD时,的每一个事件都由以下算法转换:

以下值必须是提取的链接值。

如果链接是二进制字符串,则将其解释为多地址并转换为文本格式。否则,直接使用文本字符串。

用一个键值对创建一个映射。关键是标准的IPLD链接key/,该值是包含链接值的文本字符串。

当一个IPLD对象以这里所述的方式包含这些标记时,用于表示对象编解码器的multicodec头必须是/cbor/ IPLD -tagsv1,而不仅仅是/cbor。读者应该能够使用优化的阅读过程来检测使用这些标签的链接。

规范格式

为了保持merkle-linking的能力,我们必须确保IPLD文档有一个单一的规范序列化表示。这可确保应用程序获得相同的加密哈希。应该指出的是,这是一个系统范围的参数。未来的系统可能会改变它来演进表示。不过,我们估计这需要十年不超过一次。

IPLD规范格式是带tags的规范化CBOR。

除了此处定义的规则外,规范CBOR格式必须遵循RFC 7049 section 3.9中定义的规则。

这种格式的用户不应该期望keys的任何特定排序,因为keys可能以不同的非标准格式排序。

传统的规范格式是protocol buffers。

这种规范格式用于决定首次创建对象并计算其哈希时使用的格式。一旦为IPLD对象决定了格式,它必须在所有通信中使用,以便发送者和接收者可以根据散列来检查数据。

例如,当发送一个在protocol buffers中编码的传统对象时,发送方不得发送CBOR版本,因为接收方将无法检查文件的有效性。

同样,当接收者存储对象时,它必须确保该对象的规范格式与对象一起存储,以便能够与其他节点共享该对象。

用它们的格式存储这些对象的一种简单方法是用它们的multicodec头存储它们。

数据结构示例

重要的是,IPLD是一种简单,灵活和可扩展的格式,不会妨碍用户定义新的或导入旧数据文件的方式。为此,下面我将展示一些示例数据结构。

Unix文件系统

一个小文件

一个分块文件

分割成多个独立的子文件。

目录

git

git blob

git tree

git commit

比特币

比特币block

比特币交易

这一次,在YML中。TODO:让它是一个真正的txn

  • 发表于:
  • 原文链接https://kuaibao.qq.com/s/20180524G1T78700?refer=cp_1026
  • 腾讯「云+社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 yunjia_community@tencent.com 删除。

扫码关注云+社区

领取腾讯云代金券