前言

本 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 中的模型设计。