前言

本Substrate 應用開發解析系列,主要選擇優秀的面向具體應用的項目進行解析,總結經驗,整理模式,給其它項目方以啟示,並將Substrate 的應用推廣到更多場景。


本次我們選擇Subsocial 項目進行解析。


Subsocial 項目介紹


Subsocial 自己的一句話介紹是:


”An open platform for decentralized social networks and marketplaces.

It's censorship-resistant and has built-in monetization methods.

Built with Polkadot and IPFS tech stack.”


一個面向分佈式社交網絡和市場的開放平台。它抗審查,並內置鑄幣方式。它構建在Polkadot 和IPFS 技術棧上。


Subsocial 是目前Substrate 生態歷史最久,(相對)最成熟的社交網絡應用。你可以把它想像成分佈式的Reddit、Blog、Medium。使用Subsocial,你可以為每個社交類應用跑一個鏈。


據其官網所說,為何要選擇Subsocial,是因為當今的社交網絡有如下問題,而Subsocial 致力於解決這些問題:

全球審查
不公平的變現方式
網絡效應的壟斷
缺少可定制性
算法獨裁


Subsocial 項目將自己定位為一個社交網絡平台,同時也是一個社交網絡框架。用戶可以用subsocial 啟動自己的社區網絡,並(理想情況下),以平行鏈的形式接入未來上線的Polkadot 網絡。


Subsocial 的倉庫項目情況


Subsocial 官方倉庫在https://github.com/dappforce。其下有幾個主要的倉庫:


1. Subsocial-node:substrate 開發的鏈節點

2. Subsocial-offchain:subsocial 鏈下樞紐,處理鏈下業務

3. Subsocial-js:與subsocial node 打交道的js 庫,負責rpc 通信及上層的封裝

4. Subsocial-web-app:前端UI

5. Subsocial-docs:相關文檔

6. Subsocial-flutter:flutter sdk,用於手機端UI

7. Subsocial-starter:啟動腳本,用於啟動和運維


整個Subsocial 工程,除了鏈節點之外,還由好幾個組件共同組成。下面一節會解釋這些組件之間的關係。


Subsocial 的架構圖及解釋


Subsocail 官網給出的分層架構圖如下:


上圖中,只有Substrate 和IPFS 層是協議必備組件,其它部分是可選的,但可用於優化整體的交互體驗。


經過對Subsocial 結構深入分析,我們整理出如下總體架構圖:





Subsocial 總體架構圖


各個組件的功能如下:


IPFS組件用於存放Subsocial 平台的圖片文件和所有內容數據;

Subsocial node 存儲各種模型和其索引;

Subsocial offchain 是各種鏈下邏輯的樞紐;

PostgreSQL 用於存儲feed,notifications, activities 信息。訪問這些信息不走ipfs 和Subsocial node;

Elastic Search 用於搜索spaces, posts, comments, profiles 信息。搜索請求,直接訪問這裡;


寫的過程(以創建一篇Post 為例,假設你已經登錄):


1. 用戶WebApp 發起請求到Subsocial Offchain,運行ipfs/add,將Post 整個結構添加到ipfs 服務器中(如果Post 內容中包含image,則是先在瀏覽器中請求ipfs/addFile,再將返回的文件hash值放入Post 結構中);

2. 從ipfs 正常返回後,Subsocial Offchain 將ipfs 生成的Post hash 值(也就是cid)返回給WebApp;

3. WebApp 將cid 信息與Post 的其它結構信息一起,向Subsocial node 發起一個transaction。這時會調起你的Polkadot 瀏覽器插件進行簽名。每發起一次成功的交易,會扣除掉你的賬戶中的一部分金額(註冊後會有水龍頭給你一部分SUB token);

4. 交易執行後,會從Subsocial node 中拋出Event,Subsocial Offchain 會監聽Subsocial node,並獲取到這些Event,然後進行處理,並將Event 中的相關信息寫到PostgreSQL 和Elastic Search 中;

5. 這樣寫過程就完成了。


讀取一篇Post 的過程:


1. 對於剛創建的Post,其cid 會緩存在WebApp,於是用戶發起ipfs/get 請求到Subsocial Offchain;

2. Subsocial Offchain 直接去ipfs 服務器上取回數據(是一個Json),返回給用戶;

3. WebApp 將Json 數據渲染出來;


首頁加載過程:


1. 用戶訪問https://app.subsocial.network/,加載靜態資源到Browser;

2. WebApp 建立rpc.subsocial.network 連接,使用jsonrpc 協議,這個連接直接連接到Subsocial node 上,通過Substrate runtime api 獲取信息;

3. 通過rpc 從Subsocial node 獲取一些初始信息(鏈上的信息);

4. 通過調用20 次state_getStorage rpc 方法從Subsocial node 中取出20 條Post 索引信息,返回回來是編碼後的數據;

5. WebApp 解碼,得到最近20 篇Post 的cid;

6. 發請求到https://app.subsocial.network//offchain/v1/ipfs/get ,這個請求經Subsocial Offchain 節點轉發到ipfs 節點,從ipfs 節點取回這20 篇文章的json 結構;

7. 這些json 數據經Subsocial Offchain 中轉後,返回給WebApp;

8. WebApp 對這些數據進行前端渲染;

9. 還有一些其它數據請求,也是類似的模式;

10. 頁面呈現完畢。


由上圖結構可以看到,Subsocial Offchain 會啟動一個Web Server,並同時維護4 個連接(不全是長連接):


1. 與IPFS node 的連接

2. 與Substrate node 的連接,訂閱substrate event

3. 與Pg db 的連接

4. 與es 的連接


以上就是Subsocial 這個項目的總體架構。


一些選擇


由於Subsocial 項目立項時間比較早。在代碼裡面:


Runtime 尚未更新到v3 寫法

沒有使用substrate 提供的offchain worker 和offchain storage 特性


一些不足


從架構圖可以看到,Subsocial offchain 這一個獨立的nodejs 項目佔據整個系統的一個核心位置,而其是需要獨立運維的,並沒有納入Substrate node 一起實現自動去中心化。在這一點上,顯得不是那麼Web3.0,還有改進空間。


前端Js 體驗不夠好。加載數據慢,js 執行有時會卡死瀏覽器。


數據加載上的一些優化點,比如:首頁一次性直接加載了最近20 條Post 信息,是全文,沒有做摘要處理。


總結


Subsocial 作為一個Substrate 生態的老牌項目,在Web3.0 應用架構的摸索上走出了一條切實可行的路子。值得我們學習。


下一篇,我們將會分析Subsocial runtime 中的模型設計。