近期damus社交软件大火,作为web3赛道率先上线app store的应用,很快引起了圈内圈外人士的关注。那么不少会有一个疑问,同样作为社交软件,web3赛道的damus相比于web2赛道的twitter和微博有什么优势,用户为什么要迁移到web3社交产品呢? 首先,看下damus官方给出的web2社交的一些关键问题:

  1. web2社交有广告,比如twitter上经常会看到一些广告,非常影响用户体验。
  2. web2社交会使用一些推荐技术让用户上瘾,比如twitter、tiktok都有自己的推荐算法,推荐算法会根据用户喜好不断推荐一些类似的内容,吸引用户留存。
  3. web2产品能封禁用户,比如特朗普的twitter账户就曾被twitter封禁。
  4. web2产品能对用户限流,导致用户的推文无法被其它用户看到。
  5. web2产品有很多垃圾信息。

上述问题导致web2产品无法实现真正的言论自由,根本原因在于web2产品是有专门中心化的公司和机构运营和维护,而且永远无法被替换。这些公司和机构为了盈利的目的,会破坏社交软件的言论自由。 为了实现真正的言论自由,web3就是一个很好的技术发展方向。web3的任何产品都不会由中心化的机构和公司来维护和运营,全靠社区和用户自主来维护,而且产品的代码也是开源的,任何人都可以下载阅读并参与开发。 那么Damus是如何做到的呢?那就不得不说一下它背后的去中心化社交协议Nostr了。打个比方,如果说Damus是一个大楼,那么nostr就是这个大楼的地基。

技术原理

Nostr是什么

Nostr是一个p2p的社交网络协议,基于密码学的公钥私钥和签名技术,并且不需要依赖任何的中心化服务器。

Nostr是如何工作的

Nostr网络由client和relay两个角色组成,用户运行client(比如手机上运行damus客户端),任何个人或者机构都可以运行relay。

nostr示意图

发送推文流程

  1. 第一步,用户使用客服端需要先生成公钥私钥,私钥相当于用户身份,不能对外公开。
  2. 第二步,用户在客户端提交推文内容,client会用私钥对推文内容进行签名,
  3. 第三步,client会把推文、公钥和签名发送到配置好的relay,relay会用公钥校验签名正确性。 推文内容格式为
{
  "id": "<消息ID>",
  "pubkey": "<用户公钥>",
  "created_at": "<创建时间>",
  "kind": "<消息类型>",
  "tags": [ // <用于订阅规则过滤>
    ["e", "<其它推文ID>", "<推荐relay地址>"],
    ["p", "<公钥>", "<推荐relay地址>"]
    ... // other kinds of tags may be included later
  ],
  "content": "<推文内容>",
  "sig": "<私钥签名>"
}

其中,id=sha256(JSON.stringify[0,pubkey,created_at,kind,tags,content])sig=seckey.sign(id)

接收推文流程

  1. 第一步,用户通过client发送推文订阅消息到relay。订阅消息格式为
["REQ", "<subscription_id>", {
  "ids": "<消息ID json array>",
  "authors": "<被订阅用户的pubkey json array>",
  "kinds": "<消息类型 json array>",
  "#e": "<'e' tag json array>",
  "#p": "<'p' tag json array>",
  "since": "<订阅开始时间>",
  "until": "<订阅结束时间>",
  "limit": "<初次订阅返回的最大历史推文数量>"
}, ...]

其中,subscription_id为客户端随机生成的uuid字符串 2. 第二步,relay发送推文消息到client。消息格式为

["EVENT", "<subscription_id>", {
  "id": "<消息ID>",
  "pubkey": "<用户公钥>",
  "created_at": "<创建时间>",
  "kind": "<消息类型>",
  "tags": [ // <用于订阅规则过滤>
    ["e", "<其它推文ID>", "<推荐relay地址>"],
    ["p", "<公钥>", "<推荐relay地址>"]
    ... // other kinds of tags may be included later
  ],
  "content": "<推文内容>",
  "sig": "<私钥签名>"
}]

取消推文流程

用户通过客户端发送关闭订阅消息

["CLOSE", "<subscription_id>"]

Damus如何实现推文评论

damus基于tags字段来实现推文评论功能,具体格式如下:

{
  ...
  "tags": [
    ["e", "<推文ID>", "<推荐relay地址>", "root"], // 评论链的根推文ID,必有
    ["e", "<推文ID>", "<推荐relay地址>", "mention"], // 相关推文ID,可选
    ["e", "<推文ID>", "<推荐relay地址>", "reply"], // 被评论推文ID,可选。如果没有就是root推文ID
    ...
  ],
  ...
}

Damus是如何管理用户信息

client会把用户信息发送到relay,格式如下

{
  "kind": 0,
  "name": "用户名",
  "about": "",
  "picture": "",
  ... // other fields
}

用户可以通过发送订阅消息来获取自己的用户信息,格式如下

["REQ", "<subscription_id>", {
  "authors": "<用户的公钥>",
  "kinds": [0]
}]

Damus的follower和following原理

following用户本地会维护一份contact列表,格式如下

{
  "kind": 3,
  "tags": [
    ["p", "91cf9..4e5ca", "wss://alicerelay.com/", "alice"], // 订阅用户1
    ["p", "14aeb..8dad4", "wss://bobrelay.com/nostr", "bob"], // 订阅用户2
    ["p", "612ae..e610f", "ws://carolrelay.com/ws", "carol"] // 订阅用户3
  ],
  "content": "",
  ...other fields
}

这些都是订阅的用户pubkey。但用户定阅新的用户或者取消已由的用户订阅的时候,会往relay发送新的contact列表,例如删除carol,订阅新的用户xxx

{
  "kind": 3,
  "tags": [
    ["p", "91cf9..4e5ca", "wss://alicerelay.com/", "alice"], // 订阅用户1
    ["p", "14aeb..8dad4", "wss://bobrelay.com/nostr", "bob"], // 订阅用户1
    ["p", "xxx", "ws://carolrelay.com/ws", "xxx"] // 订阅用户4
  ],
  "content": "",
  ...other fields
}

那么如何计算following就很简单,如果是在旧设备登录,只需要获取本地的订阅用户列表即可;如果是在新设备登录,就需要从relay中获取contact列表,那么就需要发送订阅消息,例如

["REQ", "<subscription_id>", {
  "authors": "<用户的公钥>",
  "kinds": [3]
}]

如何计算follower数量,也需要往relay发送订阅消息,例如

["REQ", "<subscription_id>", {
  "kinds": "3",
  "pubkeys": "<被订阅用户的pubkey json array>"
}]

根据relay返回的消息条数就可以计算

Nostr目前存在的一些缺陷和问题

  1. 无法发送图片等多媒体资源。因为nostr只负责发送文本消息,因此结合外部系统才能支持多媒体数据的上传。
  2. relay提供商缺少激励机制。目前relay服务提供商属于完成免费提供服务,长期看并不稳定可靠。
  3. 无法发送私信。由于推文内容目前都是对外公开的,还无法支持用户和用户之间点对点的私信。
  4. seckey作为用户的唯一身份验证,如果不小心泄露,那么用户账号就会永久丢失,无法重新恢复。

总结

总体上看,Damus是一款优缺点很明显的社交软件。它的去中心化特点可以最大化实现言论自由,同时也正是去中心导致用户体验上做了很多妥协。以Damus目前的产品,显然无法吸引绝大多数web2社交上的用户。这种新赛道的产品还是非常值得我们去持续关注的,等它解决好自身的问题后,可能会在未来的某个时间突然爆发。