深入瞭解IPFS(2/6):什麼是星際關聯資料(IPLD)?
這篇文章是“深入理解IPFS”系列文章的續篇(第2部分),它將幫助理解IPFS的基本概念,如果你想了解什麼是IPFS及其工作原理,那麼你應該查閱第一篇。
在本系列文章的第一部分中,我們簡要討論了IPLD。我們看到IPLD處理IPFS中的“定義資料”。在這一部分中,我們將深入研究IPLD並進行討論:
IPLD 的意義 : 它背後的哲學是什麼,我們為什麼需要它以及它為什麼適合IPFS?
IPLD 是如何工作的 : 說明IPLD的工作原理,以及它是如何與IPFS的其他元件協調的?
實際使用 : 實際操作的過程總是有趣的。
希望你可以從本系列中學到很多關於IPFS的知識。讓我們開始吧!
第一、IPLD的重要性
IPLD不僅是IPFS專案的一部分,而且是一個單獨的專案。要理解它在去中心化世界中的重要性,我們必須理解關聯資料的概念:語義性網路。
什麼是關聯資料?為什麼我們需要它 ?
語義性網路(Semantic Web)或關聯資料(Linked Data)是蒂姆•伯納斯•李爵士(Sir Tim Berners Lee)於2001年發表在《科學美國人》上的一篇開創性文章中創造的一個術語。伯納斯•李在文章中闡述了全球資訊網的願景,即機器可以獨立於人類處理資料,從而實現一系列改變我們日常生活的新服務。資料可以由軟體代理進行分析和操作,然而,這篇論文對大多數包含結構化資料的網路頁面設想還並沒有實現,隨著越來越多的社群使用國際語義網路標準(稱為連結資料)實現資料共享,語義性網路已經成為一個對資料交換和整合越來越重要的平臺。
目前有許多使用語義性網路技術和連結資料的例子,它們以靈活和可擴充套件的方式在網路上共享有價值的資訊。語義性網路的相關技術被廣泛應用於生命科學中,通過在多個數據集之間尋找路徑來促進新藥物的發現,而這些資料集通過與每個資料集相關的基因來顯示藥物和副作用之間的關聯。《紐約時報》公佈了其150多年來發展起來的約10,000個主題或標題的詞彙來作為連結資料,並將其覆蓋面擴大到約30,000個主題標籤;它們鼓勵開發使用這些詞彙表的服務,並將它們與其他線上資源連線起來。英國廣播公司則通過使用連結資料,使內容更容易被搜尋引擎找到,也更容易通過社交媒體連結進行傳播;從音樂或體育等領域使用補充資源並新增額外的內容,進行連結的傳播,使其超出最初的輸入目標,以便在附加上下文中提供相關資訊。美國data.gov網站的主頁上說:“隨著連結文件的網路發展到包括連結資料網路,我們正在努力最大限度地發揮語義性網路技術的潛力,以實現連結資料的公開。”而且目前所有的社交媒體網站都在使用連結資料來建立網路,以此使他們的平臺儘可能地吸引人。
的確,我們目前有一些關聯資料正在被使用,但要利用關聯資料的真正力量,我們還有很長的路要走。
想象一下,如果你可以將你在git分支中的最新提交引用到比特幣交易中來為你的工作新增時間戳。通過連結git的提交,你可以從區塊鏈資源管理器中檢視提交。或者,如果你可將以太坊合約連結到IPFS上,那樣就可以修改它,並在每次函式執行時跟蹤它的更改。
所有這些都是可以使用IPLD實現的。
IPLD是基於內容可定址網路的資料模型(如第1部分所述)。
它允許我們將所有雜湊連結的資料結構視為統一子集,將所有資料與連結的資料模型統一為IPLD的例項。
換句話說,IPLD是一組用於建立去中心化資料結構的標準,這些資料結構具有普遍的可定址性和可連結性。 這些結構允許我們處理資料,就像 url 和連結處理 HTML 網路 頁面一樣。
通過雜湊進行內容定址已經成為分散式系統中連線資料的一種廣泛使用方法,從在區塊鏈上執行你最喜歡的加密貨幣到程式碼的提交,再到網路內容。然而,儘管所有這些工具都依賴於一些公共原則,但它們特定的底層資料結構是 不可互操作的 (目前我無法將git提交連結到區塊鏈上)。
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的高階專案規範。 即使你不完全理解,也沒關係。
要了解有關IPLD的更多資訊,請參閱Juan Benet的 精彩演講 。
好的,理論的東西已經夠多了。讓我們來看看這篇文章最有趣的部分
第四、對於 IPLD 的實際操作
在IPFS中,IPLD有助於構造和連結所有資料塊/物件。所以,正如我們在第1部分中看到的,IPLD負責組織的所有資料塊以構成了小貓的形象。
在本部分中,我們將建立一個類似於medium.com的釋出系統,並使用IPLD連結標籤、文章和作者。這將幫助你更直觀地理解IPLD,你也可以在Github上找到完整的教程。
讓我們開始吧!
在建立釋出系統之前,我們將研究IPFS DAG API,它允許我們以IPLD格式儲存IPFS中的資料物件。(你可以在IPFS中儲存更多令人興奮的東西,比如你最喜歡的貓的影象,但我們暫時只儲存些簡單的東西。)
如果你不熟悉Merkle和DAGs,那麼請到來。如果你理解了這些術語的意思,那麼繼續……
建立一個名為ipld-blogs的資料夾。執行npm init並按回車鍵檢視所有問題。
現在安裝依賴使用:
npm install ipfs-http-client cids --save
安裝模組後,你的專案結構將如下圖所示:
第五、建立 IPLD 格式節點
你可以通過將資料物件傳遞到ipfs.dag來建立一個新節點,該方法為新建立的節點回報內容識別符號(CID)。
ipfs.dag.put({name: ‘vasa’})
CID是IPFS中的一個數據塊的地址,該資料塊由其內容派生而來。每當有人將相同的{name: 'vasa'}資料放入IPFS時,他們將得到與你得到的相同的CID。如果他們輸入{name: 'vAsa'}, CID將會不同。
將此程式碼貼上到tut.js中並執行node .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("ERRn", 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 “zdpuaujl3 noemamvelpqwjpy6cyzhhhoskyqazbvrbafvwr8”。至此,我們已經成功建立了一個IPLD格式節點。
連線 IPLD 物件
有向無環圖(DAGs)其中的一個重要特徵是能夠將它們連結在一起。
在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
我將會開啟這個連結 : https : //explore.ipld.io/#/explore/zdpuAujL3noEMamveLPQWJPY6CYZHhHoskYQaZBvRbAfVwR8S
現在,由於我們已經研究了IPFS DAG API,我們準備使用IPLD建立我們的釋出系統。
建立釋出系統
我們將建立一個簡單的部落格應用程式。 這個部落格應用程式可以:
· 新增一個新的Author IPLD物件。作者將有兩個欄位:name和profile(你的profile的標記行)。
· 建立一個新的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 object
var newAuthor = await ipfs.dag.put({
name: name,
profile: "Entrepreneur | Co-founder/Developer @TowardsBlockChain, an MIT CIC incubated startup | Speaker | https://vaibhavsaini.com"
});
//Fetching multihash buffer from cid object.
const multihash = newAuthor.multihash;
//passing multihash buffer to CID object to convert multihash to a readable format
const cids = new CID(1, 'dag-cbor', multihash);
console.log("Added new Author "+name+": "+cids.toBaseEncodedString());
return cids.toBaseEncodedString();
}
//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()
});
//Fetching multihash buffer from cid object.
const multihash = post.multihash;
//passing multihash buffer to CID object to convert multihash to a readable format
const cids = new CID(1, 'dag-cbor', multihash);
console.log("Published a new Post by "+author+": "+cids.toBaseEncodedString());
return cids.toBaseEncodedString();
}
//Read a blog
async function readBlog(postCID){
ipfs.dag.get(postCID,(err, result)=>{
if (err) {
console.error('Error while reading post: ' + err)
} else {
console.log("Post Detailsn", result);
return result;
}
});
}
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。敬請期待...
感謝protoschool對於DAGs的出色解讀。
感謝你的閱讀。
原文作者:vasa
原文連結:https://hackernoon.com/understanding-ipfs-in-depth-1-5-a-beginner-to-advanced-guide-e937675a8c8a
翻譯:星際大陸海外團隊