背景
星際文件系統 IPFS(InterPlanetary File System)是一個面向全球的、點對點的分布式文件系統,目標是為了補充(甚至是取代)目前統治互聯網的超文本傳輸協議(HTTP),將所有具有相同文件系統的計算設備連接在一起。原理用基于內容的地址替代基于域名的地址,也就是用戶尋找的不是某個地址而是儲存在某個地方的內容,不需要驗證發送者的身份,而只需要驗證內容的哈希,通過這樣可以讓網頁的速度更快、更安全、更健壯、更持久。
社交互聯數據 Solid (Social Linked Data) 由萬維網發明者 Tim Berners-Lee 發起,該項目旨在從根本上改變 Web 應用程序的中心化趨勢, 它將真正地讓數據所有權屬于用戶,并改善隱私問題。它是一組約定和工具,主要用于構建基于關聯數據的分布式社交應用。
簡單來說,IPFS 是一個任何人都可以訪問的點對點存儲平臺(可以存儲大量非結構化數據),Solid 是一個必須授權才可以使用的結構化數據計算和存儲平臺。
我們想要解決的問題是,如何私有化存儲 IPFS 文件的哈希值。存儲在 IPFS 上的文件哈希如果被泄漏,任何人都可以訪問該文件,這是極不安全的,不是每個人都想把自己的文件上傳到公有網絡里。解決哈希值的泄漏有兩種方案:
- 自建 IPFS 私有節點。該方案成本比較大,需要根據 IPFS 開放的協議重頭來寫;
- 自己寫一套或使用成熟的互聯網訪問控制(WAC,Web Access Control)方案;
綜合考慮成本、時間等因素,我們使用第二種方案。而第二種方案有非常多的實現,同時 Solid 是所有實現中最具開放性、代表性和權威性的。WAC 本身就是由 Tim Berners-Lee 在 2009 年提出的方案,如今用于 Solid 項目中是天作之合。
Solid 一個巨大的優勢在于,它想將數據的所有權還歸用戶。如果想讓用戶愿意上傳隱私數據到 IPFS 網絡中,一個重要的因素在于如何保證用戶上傳的文件哈希不被其他人非法獲取到,而 Solid 不僅可以安全的存儲文件哈希值,還可以保證文件哈希值僅為用戶所有。
于是我們寫了個 solid-ipfs 框架用來解決這個問題。
解決方案
代碼在 Github 上已開源:Eximua/solid-ipfs。
以下是以一個 WebId (用戶在 Solid 網絡中的唯一標識)為 https://alicea.solid.authing.... 的用戶舉例。
這是用戶 Alicea 在 Solid 上的個人主頁,其中 Profile 和 Public Folder 是可以公開被讀取的數據(但是寫入需要 Alicea 的權限確認),Inbox 為隱私數據,只有 Alicea 本人可以讀取和寫入。我們上傳到 IPFS 網絡中的私有文件哈希值將被存儲到 Inbox 中。
簡單來說的話,Profile、Public Folder 和 Inbox 可以理解為公有文件夾和私有文件夾。你所有的公有文件可以放到到公有文件夾里,私有的隱私數據可以放到私有文件夾內。
更簡單來說,這就是 Solid Pod。
Solid 的數據存儲使用 RDF,RDF 是用來描述網絡資源的一個框架,他把所有資源以三元組的形式進行描述。比如(姚明,身高,226cm)定義了姚明的身高是 226 厘米。
示例中的 (alicea, type, Person) 則定義了 Alicea 的類型是人。同理,(alicea, hash, QmVCZeNR7eQNEu5Gekqqbnmk85v66cFHHjZZTGZxAqA2hD) 定義了 Alicea 的哈希值為 "QmVCZeNR7eQNEu5Gekqqbnmk85v66cFHHjZZTGZxAqA2hD"(該哈希來自于 IPFS 的某個文件)。
當然這種描述方式不是語義化的,僅供示例參考。
為了對這些 RDF 進行讀寫操作,RDF 官方封裝了 rdflib.js ,使語義計算可以在 Web 上執行(也就是可以在瀏覽器里執行語義計算啦)。
我們最終語義化的私有存儲樣例如下:
可以看到,我們使用了 "ipfs/hash" 這個命名空間(可以理解成文件夾)來存儲相應的 IPFS 文件哈希值,并且把每一個哈希值作為一個文件(哈希值.txt)存儲到 Solid Pod 中。這樣用戶在使用 Solid 賬號登錄之后我們就可以讀取用戶的文件哈希值列表,然后從 IPFS 網絡中拉取文件了。
具體的技術細節就不再細講了,感興趣的可以自行查看代碼:Eximua/solid-ipfs。
使用 solid-ipfs
最后介紹一下 solid-ipfs 的使用方法。
solid-ipfs 其實不止可以寫入私有數據,還可以寫入公有數據。
安裝
$ npm install solid-ipfs --save
使用
import SolidIPFS from 'solid-ipfs';const main = async () => {const solidIpfs = new SolidIPFS({url: 'YOUR_SOLID_URL', // e.g. https://alicea.solid.authing.cn/inbox/});const result = await solidIpfs.storeHash({hash: 'YOUR_IPFS_HASH',});console.log(result, result ? '保存成功' : '保存失敗');
}main();
通過訪問<YOURL_SOLID_URL>/ipfs/hash/
之后即可獲得用戶的 IPFS 哈希值列表
如果你還沒有 Solid 賬號,可以點擊這里注冊。
私有文件示例
- https://alicea.solid.authing....
import SolidIPFS from 'solid-ipfs';const main = async () => {const solidIpfs = new SolidIPFS({url: 'https://alicea.solid.authing.cn/inbox/', // inbox -> private});const result = await solidIpfs.storeHash({hash: 'YOUR_IPFS_HASH',});console.log(result, result ? '保存成功' : '保存失敗');
}main();
公有文件示例
- https://alicea.solid.authing....
- https://alicea.solid.authing....
import SolidIPFS from 'solid-ipfs';const main = async () => {const solidIpfs = new SolidIPFS({url: 'https://alicea.solid.authing.cn/public/', // public -> public});const result = await solidIpfs.storeHash({hash: 'YOUR_IPFS_HASH',});console.log(result, result ? '保存成功' : '保存失敗');
}main();
題外話,有的人可能對 RDF、語義計算這些概念不熟悉,這里再簡單介紹下。
RDF 為什么叫資源描述框架,這個資源具體指代什么?
RDF 中的資源指代一切資源,它是一個通用的,可以定義一切的規范。比如:文件夾、文件、文件類型、代碼、聊天內容、郵件等都屬于資源,RDF 主要定義了這些不同類型資源的存儲方式和數據規范。
我們為什么需要 RDF,它能解決什么問題?
RDF 看重語義化,可移植性和互操作性。語義化指你的數據存儲規范必須是人類能理解的;可移植性代表當我想把我的數據從 A 平臺移植到 B 平臺時,不需要做任何的數據格式兼容;互操作性指我在 A 平臺存儲的數據在 B 平臺上也可以進行讀取和計算。
簡單來說,就是所有的數據都共享同一套規范,減少為了兼容而產生的數據對齊時間,提升效率。RDF 是語義互聯網(Web 3.0)的重要組成部分,它的愿景是全萬維網的數據互通,變成一個大型計算平臺,目前這個概念更有名的叫法為“知識圖譜”。
Solid 資源列表:
- Solid 中文網
- Solid 中文社區
?3. Solid Pod 中國節點
?4. solid-ipfs
?