一个去中心化的网络论坛设计

简介

本文讲介绍了一个基于 IPFS 去中心化论坛的设计,虽然用的 IPFS 技术,但是实际上这个设计也可以用于别的技术栈。同时这是个非常简单的设计,中间有很多可以优化的空间,本设计只为了读者提供思路。

技术背景介绍

为了后续内容的阅读体验,我将对本设计涉及到的技术—— IPFS,做一个简单的介绍,当然这个介绍不会深入 IPFS 网络的细节,只是对 IPFS 这个抽象层的介绍,另外为了读者的阅读考虑,我尽量少引用术语,如果读者对 IPFS 网络的细节感兴趣,可以自行阅读 IPFS 的文档

IPFS(InterPlanetary File System)又名星际文件系统,在一般的介绍里可能会说它是个「硬盘共享协议」,但我觉得它其实更像是个文件分享协议,如果你了解 BT 协议的话,IPFS 网络和 BT 网络是非常相近的。

在你加入 IPFS 网络之后,你和 IPFS 其他的节点一起构成一个内容存储的网络。在这个网络中,你上传到所有文件(或者文件夹)都有一个独一无二的 ID,称为 CID (Content Identifier),你不需要知道这个 CID 是如何生成的,你可以直接把这个 CID 直接理解为文件的 Hash 值(类似 BT 网络中的磁力链接),也正是因为如此当你修改文件内容时候 CID 也会随之改变。通过 CID IPFS 可以实现文件的去重,也就是它不会存储 CID 相同的文件。当你需要获取一个文件时候,如果这个网络中有人缓存了这个文件且在线,你可以直接通过这个 CID 获取到你想要文件。

但是这个不可变性也带来了问题,如果我们需要一个可变的内容该怎么办?举例来说,我们想要发布一个静态网站到 IPFS 网络上,我们不可能每次在更新网页之后都给用户提供一个新的 CID 地址,用户需要一个固定的地址来访问我们的网站。而解决这个问题的办法就是 IPNS(InterPlanetary Name System)。你不用在意这个 IPNS 是如何如何实现的,你只需要知道,我们可以通过一个固定 IPNS 地址来访问最新的内容就行,当然你之前的内容如果有人缓存的话也会停留在IPFS网络上,但是如果没人缓存或者缓存内容的人不在线,那么之前的内容就会丢失了。

下面就是一个例子,你可以看到我们把 CID 为QmSwMfsNFmUxn5D2BcHU2NGkuKoAEAaowdJ6Qdn9w1j8ev 绑定到了k2k4r8mu68txggqrlfp3zylq5rvabpgdhjz3uop2813at3g7xn3rbc3a这个 name 上,当然我们也可以更新这个 name 绑定的 CID 。

不过 IPNS 并不是唯一实现这个功能的协议,这里只是为了方便所以使用了这个协议,其他类似的协议还有有,比如说 DNSLink

1
2
$ ipfs name resolve k2k4r8mu68txggqrlfp3zylq5rvabpgdhjz3uop2813at3g7xn3rbc3a
/ipfs/QmSwMfsNFmUxn5D2BcHU2NGkuKoAEAaowdJ6Qdn9w1j8ev

以上就是这个设计所需要用到的技术的简单介绍。

具体设计

首先说明,这个设计基于一个最理想的情况,也就是所有用户都一直在线且会保存自己的文件,现实世界不一定如此。另外这只是一个初步的设计,肯定会有很多不完善的地方。此外为了简单起见,我们将用户的「回复」也作为「帖子」处理。

network

在这个网络中,有两类节点,请注意这里的每个节点都有 IPNS 地址:

  • 论坛节点
  • 用户节点

其中「论坛节点」是这个论坛系统运作的核心,而这个节点中最为重要的文件就是 users.csv ,其具体内容如下:

1
2
3
ipns1,users1_id
ipns2,users2_id
ipns3,users3_id

在这个文件中,记录了一系列的 IPNS 地址,这里的每一个 IPNS 地址指向了一个用户的发帖文件夹,而 user_id 则是用户的标识符,这里可以充当标识符的内容有很多比如:用户名、用户的公钥等。而用户注册这个论坛的方式,也就是向这个文件中加入一条记录,具体的注册方式有很多不同的解决方案,比如论坛的维护者可以做一个简单的网页来让用户注册。

而「主题文件」是作为发帖分类用的,具体的使用方式见下文。

在「用户节点」,用户需要创建一个文件夹,并在在这个文件夹内存放自己帖子,你在这个文件夹中添加新的文件就相当于发帖。用户需要按照以下协议进行发帖。

用户发帖格式:

1
2
3
4
5
6
7
8
Preview_CID:[回复/帖子/主题的CID,] 
Date:Unix时间戳
File_Type:plain
Title:
Lorem ipsum
Content:
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
Pellentesque vitae scelerisque purus. Curabitur sed lectus ut sapien sodales hendrerit.

这个格式主要分为两个区域: Meta 区域和 Content 区域

  • Meta 区域主要记录的发帖的「元信息」比如是个「新帖子」还是「回复」,要回复谁或者要发到哪个分类下。

在这个分类中有一个 Preview_CID,它接受一个 CID 组成的数组,这里的 CID 可以是某个帖子、回复或者论坛提供的主题的 CID。

  • Content 区域主要记录发帖的内容,比如帖子的标题和内容等。

在这个分类中 Title 表示帖子的的标题,而 Content 表示帖子的具体内容。

用户在发布一个新的「帖子」之后,需要更新自己的 IPNS 地址的绑定来添加新的内容。

而用户获取他人帖子的具体步骤如下,首先去论坛节点的 IPNS 地址获取到最新的 users.csv,然后根据这个列表上的其他用户的 IPNS 地址获取到其他用户的最新发帖,最后根据用户发帖中的 Preview_CID 信息将讨论串拼接起来。

总结

首先我还是得重复一下,这个是个非常简单的设计,中间肯定会有非常多可以优化的地方。

在这个设计中,你发的所有帖子都是先存放在本地,当别人需要的时候才会被同步出去,这意味着你不用担心你的贴文内容会被「论坛」所控制,也不会因为某天论坛消失了,你得发的内容也消失了。此外因为 IPFS 网络的特性,你只要能连上 IPFS 网络,你就可以获取到 users.csv ,这样也解决了因为你所在的公司、地区和国家进行了网络封锁导致你无法访问的论坛的问题。

上面看上去都是这个这个分布式论坛看得到的好处,我觉得看不到的好处也很重要,因为它很有趣,这是个基本上没多少先例的领域,创造之前没有人做过的东西总是很有趣的。