IPLD完整指南:其意义,原理和实际示例
这篇文章是新的“ 深入了解IPFS ”系列的继续(第2部分),它将帮助任何人理解IPFS的基本概念。 如果您想了解什么是IPFS及其工作原理,那么您也应该查看第一部分😊
在本系列的第一部分中,我们简要讨论了IPLD。 我们看到IPLD处理IPFS中的“定义数据”(当然,不仅限于IPFS)。 在这一部分中,我们将全面研究IPLD并讨论:
- IPLD的意义 :其背后的哲学是什么,为什么我们需要它,它在IPFS中适合什么地方?
- IPLD如何工作? :有关其规范的说明以及它如何与IPFS的其他组件协调?
- 与IPLD一起玩 :嗯,玩总是很有趣 😊
您可以在Twitter上关注我 @vasa_develop
如果您喜欢IPLD等高科技Web3概念并通过交互式教程简单地进行了解释,请前往此处 。
希望您从本系列中学到很多有关IPFS的知识。 开始吧!
IPLD的意义
IPLD不仅是IPFS项目的一部分,而且本身也是一个单独的项目 。 要了解其在去中心化世界中的重要性,我们必须了解链接数据的概念:语义网 。
什么是链接数据?为什么我们需要它?
语义网或链接数据是Tim Berners Lee爵士在2001年《科学美国人》上发表的开创性文章中创造的一个术语。BernersLee提出了一种机器可以独立于人类进行处理的万维网数据的愿景,从而使许多人可以新服务改变了我们的日常生活。
尽管本文对大多数包含结构化数据的网页的愿景尚未实现 ,但可以通过软件代理对其进行分析和采取行动,但语义网已成为一个日益重要的平台,通过不断增长的社区使用国际化的数据共享来实现数据交换和集成。 语义Web标准 ,称为链接数据 。
当前有许多使用语义Web技术和链接数据来以灵活且可扩展的方式在网络上共享有价值的结构化信息的示例。 语义网络技术在生命科学中得到了广泛的应用,它通过跨多个数据集查找路径来促进药物发现,这些路径显示了通过相互关联的基因在药物和副作用之间的关联。
《纽约时报》已发布了150年来开发的大约10,000个主题词的词汇,称为“链接数据”,并将覆盖范围扩展到大约30,000个主题标签; 他们鼓励开发使用这些词汇并将其与其他在线资源链接的服务。
英国广播公司使用链接数据使内容在搜索引擎中更易于查找,并在社交媒体上具有更多链接。 从音乐或体育等领域的补充资源中添加其他上下文,并传播链接和社论注释超出其原始输入目标,从而在其他上下文中提出相关信息。
美国data.gov网站的主页上说:“随着链接文档网络的发展,包括链接数据网络,我们正在努力最大程度地利用语义网技术的潜力,以实现链接开放政府数据的承诺。 。” 而且,所有社交媒体网站都使用链接数据来创建一个人脉网络,以使其平台尽可能吸引人。
因此,我们确实有一些链接数据,但是要利用链接数据的真正力量,我们还有很长的路要走。
现在想象一下,如果您可以将git分支中的最新提交引用到比特币交易中,以为您的工作添加时间戳。 因此,通过链接git commit,您可以从区块链资源管理器中查看该提交。 或者,如果您可以将以太坊合约链接到IPFS上的媒体,则可以对其进行修改并在每次执行功能时跟踪其变化。
使用IPLD,所有这些都是可能的。
IPLD是内容可寻址的网络(在所讨论的数据模型part1的 )。
它使我们能够将所有散列链接的数据结构视为统一信息空间的子集,从而将所有将具有散列数据的链接的数据模型统一为IPLD实例。
换句话说,IPLD是用于创建可普遍寻址和链接的分散式数据结构的一组标准和实现。 这些结构使我们可以对HTML网页的URL和链接进行数据处理。
通过哈希寻址的内容已成为连接分布式系统中数据的一种广泛使用的方法,从运行您喜欢的加密货币的区块链到支持代码的提交,再到整个Web内容。 然而,尽管所有这些工具都依赖于一些通用原语,但它们特定的基础数据结构不可互操作 (目前,我无法将git commit连接到区块链交易)。
IPLD是所有散列启发式协议的单一名称空间。 通过IPLD, 可以跨协议遍历链接,无论基础协议如何,都可以浏览数据 。
IPLD如何工作?
在深入探讨IPLD之前,让我们看一下IPLD的属性。
IPLD的属性
IPLD使您可以跨协议边界工作,这是无限的极限。 关键是默认情况下,IPLD提供了使基础数据可跨工具和跨协议互操作的库 。
规范数据模型
一个独立的描述模型 ,可以唯一地标识任何基于散列的数据结构,并确保同一逻辑对象始终映射到完全相同的位序列。
协议独立解析
IPLD将孤立的系统整合在一起(例如连接比特币,以太坊和git),从而使与现有协议的集成变得简单。
可升级
有了Multiformats(我们将在第4部分中进一步介绍)支持,IPLD可以轻松升级,并且会随您喜欢的协议一起增长。
跨格式运行
以各种可序列化的格式(例如JSON,CBOR,YAML,XML等)来表达IPLD对象,这使得IPLD可以与任何框架配合使用。
向下兼容
非侵入式解析器使IPLD易于集成到您现有的工作中。
所有协议的名称空间
IPLD允许您无缝地跨协议浏览数据,通过公共命名空间将基于哈希的数据结构绑定在一起。
现在,让我们更深入地研究IPLD。
深入探讨IPLD规范
IPLD不是单一规范,而是一组规范。
(IPLD堆栈)
该堆栈的目标是启用分散的数据结构,这又将启用更多分散的应用程序。
此堆栈中的许多规范是相互依赖的。
(依赖图)
这些图显示了IPLD的高级项目规范。 即使您不完全了解它也完全可以。
要了解有关IPLD的更多信息,这里是Juan Benet的精彩演讲 。
好。 理论上足够的东西。 让我们深入探讨这篇文章中最有趣的部分
玩IPLD
在IPFS中,IPLD帮助构建和链接所有数据块/对象。 因此,正如我们在第1部分中看到的那样,IPLD负责组织构成kitty🐱图像的所有数据块。
在这一部分中,我们将创建一个类似于media.com的发布系统,并使用IPLD链接标签,文章和作者。 这将帮助您更直观地了解IPLD。 您还可以在Github上找到完整的教程。
让我们开始吧!
在创建发布系统之前,我们将探索IPFS DAG API,该API使我们能够以IPLD格式将数据对象存储在IPFS中。 (您可以在IPFS中存储更多激动人心的内容,例如您最喜欢的cat GIF,但现在我们将坚持使用更简单的内容。)
如果您不熟悉Merkle尝试和DAG,请前往此处 。 如果您了解这些术语的含义,请继续…
创建一个名为ipld-blogs
的文件夹。 运行npm init
,然后按Enter
以回答所有问题。
现在使用以下命令安装依赖项:
npm install ipfs-http-client cids --save
安装模块后,您的项目结构将如下所示:
创建IPLD格式节点
您可以通过将数据对象传递到ipfs.dag.put
方法中来创建新节点,该方法将为新创建的节点返回内容标识符(CID)。
ipfs.dag.put({name: 'vasa'})
CID是IPFS中从其内容派生的数据块的地址。 每当有人将相同的{name: 'vasa'}
数据放入IPFS时,他们将获得与您获得的相同的CID。 如果他们输入{name: 'vAsa'}
,则CID将有所不同。
将此代码粘贴到tut.js
并运行node tut.js
//Initiate ipfs and CID instance
const ipfsClient = require ( 'ipfs-http-client' );
const CID = require ( 'cids' );
//Connecting ipfs instance to infura node. You can also use your local node.
const ipfs = new ipfsClient({ host : 'ipfs.infura.io' , port : '5001' , protocol : 'https' });
/*
Creating an IPLD format node:
ipfs.dag.put(dagNode, [options], [callback])
For more information see:
https://github.com/ipfs/interface-js-ipfs-core/blob/master/SPEC/DAG.md#ipfsdagputdagnode-options-callback
*/
ipfs.dag.put({ name : "vasa" }, { format : 'dag-cbor' , hashAlg : 'sha2-256' }, (err, cid)=>{
if (err){
console .log( "ERR\n" , err);
}
//featching multihash buffer from cid object.
const multihash = cid.multihash;
//passing multihash buffer to CID object to convert multihash to a readable format
const cids = new CID( 1 , 'dag-cbor' , multihash);
//Printing out the cid in a readable format
console .log(cids.toBaseEncodedString());
//zdpuAujL3noEMamveLPQWJPY6CYZHhHoskYQaZBvRbAfVwR8S
});
您将获得此CID zdpuAujL3noEMamveLPQWJPY6CYZHhHoskYQaZBvRbAfVwR8S
。 我们已经成功创建了IPLD格式节点。
连接IPLD对象
有向无环图(DAG)的一项重要功能是能够将它们链接在一起。
在ipfs
DAG存储中表达链接的方式是使用另一个节点的CID
。
例如,如果我们希望一个节点具有名为“ foo”的链接,该链接指向先前另存为barCid
另一个CID实例,则它可能类似于:
{
foo: barCid
}
当我们给一个字段起一个名字并将其值作为一个CID的链接时,我们称其为命名链接。
下面的代码显示了如何创建命名链接。
//Initiate ipfs and CID instance
const ipfsClient = require ( 'ipfs-http-client' );
const CID = require ( 'cids' );
//Connecting ipfs instance to infura node. You can also use your local node.
const ipfs = new ipfsClient({ host : 'ipfs.infura.io' , port : '5001' , protocol : 'https' });
/*
Creating an IPLD format node:
ipfs.dag.put(dagNode, [options], [callback])
For more information see:
https://github.com/ipfs/interface-js-ipfs-core/blob/master/SPEC/DAG.md#ipfsdagputdagnode-options-callback
*/
async function linkNodes ( ) {
let vasa = await ipfs.dag.put({ name : 'vasa' });
//Linking secondNode to vasa using named link.
let secondNode = await ipfs.dag.put({ linkToVasa : vasa});
}
linkNodes();
使用链接读取嵌套数据
您可以使用路径查询从深度嵌套的对象中读取数据。
ipfs.dag.get
允许使用IPFS路径进行查询。 这些查询返回一个对象,其中包含查询的值以及所有未解析的剩余路径。
这个API的优点是它还可以遍历链接。 这是一个如何使用链接读取嵌套数据的示例。
//Initiate ipfs and CID instance
const ipfsClient = require ( 'ipfs-http-client' );
const CID = require ( 'cids' );
//Connecting ipfs instance to infura node. You can also use your local node.
const ipfs = new ipfsClient({ host : 'ipfs.infura.io' , port : '5001' , protocol : 'https' });
function errOrLog ( err, result ) {
if (err) {
console .error( 'error: ' + err)
} else {
console .log(result)
}
}
async function createAndFeatchNodes ( ) {
let vasa = await ipfs.dag.put({ name : 'vasa' });
//Linking secondNode to vasa using named link.
let secondNode = await ipfs.dag.put({
publication : {
authors : {
authorName : vasa
}
}
});
//featching multihash buffer from cid object.
const multihash = secondNode.multihash;
//passing multihash buffer to CID object to convert multihash to a readable format
const cids = new CID( 1 , 'dag-cbor' , multihash);
//Featching the value using links
ipfs.dag.get(cids.toBaseEncodedString()+ '/publication/authors/authorName/name' , errOrLog);
/* prints { value: 'vasa', remainderPath: '' } */
}
createAndFeatchNodes();
您还可以使用此炫酷的IPLD资源管理器来探索IPLD节点。
就像,如果我想查看此CID: zdpuAujL3noEMamveLPQWJPY6CYZHhHoskYQaZBvRbAfVwR8S
,我将转到此链接:
ttps://explore.ipld.io/#/explore/zdpuAujL3noEMamveLPQWJPY6CYZHhHoskYQaZBvRbAfVwR8S
Now, as we have explored IPFS DAG API we are ready to work with IPLD and create our publication system.
创建发布系统
我们将创建一个简单的博客应用程序。 该博客应用程序可以:
- 添加一个新的作者IPLD对象。 作者将具有2个字段:名称和个人资料(个人资料的标记行)。
- 创建一个新的Post IPLD对象。 帖子将包含4个字段:作者,内容,标签和发布日期时间。
- 使用帖子CID阅读帖子。
以下是上述目标的代码实现。
/*
PUBLICATION SYSTEM
Adding new Author
An author will have
-> name
-> profile
Creating A Blog
A Blog will have a:
-> author
-> content
-> tags
-> timeOfPublish
List all Blogs for an author
Read a Blog
*/
//Initiate ipfs and CID instance
const ipfsClient = require ( 'ipfs-http-client' );
const CID = require ( 'cids' );
//Connecting ipfs instance to infura node. You can also use your local node.
const ipfs = new ipfsClient({ host : 'ipfs.infura.io' , port : '5001' , protocol : 'https' });
//Create an Author
async function addNewAuthor ( name ) {
//creating blog author object
var newAuthor = await ipfs.dag.put({
name : name,
profile : "Entrepreneur | Co-founder/Developer @TowardsBlockChain, an MIT CIC incubated startup | Speaker | https://vaibhavsaini.com"
});
console .log( "Added new Author " +name+ ": " + newAuthor);
return newAuthor;
}
//Creating a Blog
async function createBlog ( author, content, tags ) {
//creating blog object
var post = await ipfs.dag.put({
author : author,
content : content,
tags : tags,
timeOfPublish : Date ()
});
console .log( "Published a new Post by " + author + ": " + post);
return post;
}
//Read a blog
async function readBlog ( postCID ) {
ipfs.dag.get(postCID + "" , (err, post) => {
if (err) {
console .error( 'Error while reading post: ' + err)
} else {
console .log( "Post Details\n" , post);
ipfs.dag.get(postCID + "/author" , (err, author) => {
if (err) {
console .error( 'Error while reading post author: ' + err)
} else {
console .log( "Post Author Details\n" , author);
}
});
}
});
}
function startPublication ( ) {
addNewAuthor( "vasa" ).then(
( newAuthor ) => {
createBlog(newAuthor, "my first post" , [ "ipfs" , "ipld" , "vasa" , "towardsblockchain" ]).then(
( postCID ) => readBlog(postCID))
});
}
startPublication();
运行此代码后,它将首先通过addNewAuthor
创建作者,该作者将返回作者的CID。 然后,此CID将传递给createBlog
函数,该函数将返回postCID
。 readBlog
函数将使用此postCID
来获取帖子详细信息。
您可以使用IPLD创建更复杂的应用程序…
好。 仅此部分而已。 如果您有任何问题,可以在评论中进行提问。
希望您从这篇文章中学到了很多东西。 在下一篇文章中,我们将深入探讨分布式Web IPNS的命名系统。 因此,请继续关注...
感谢proto.school对DAG的出色解释。
谢谢阅读 ;)
学到了什么? 分享这篇文章,并帮助其他人找到它。
如果您喜欢内容,请按住拍手按钮! 它可以帮助我获得曝光。
关于作者
Vaibhav Saini是TowardsBlockchain ( 麻省理工学院剑桥创新中心孵化的初创公司)的联合创始人。
他是高级区块链开发人员,曾在以太坊,Quorum,EOS,Nano,哈希图,IOTA等多个区块链平台上工作。
他是演讲者,作家,并且是IIT Delhi的辍学者。
想了解更多? 查看我以前的文章。
在Twitter上关注我: @vasa_develop