Nostr 详解:仅凭一对密钥构建的去中心化社交协议
没有「账号」,也没有传统意义上的「服务器」。Nostr(Notes and Other Stuff Transmitted by Relays)是匿名开发者 fiatjaf 在 2020 年前后提出的一种极度简洁的去中心化社交网络协议:每一个身份都只是一对密钥,每一条数据都只是同一种带签名的 JSON 结构。本文解析这种极简设计如何同时兼顾抗审查性与实现的简易性。
Nostr 是什么:身份即密钥对本身
Nostr 没有中心化的服务器来接受用户注册、管理密码或邮箱。用来标识一个用户的,是一对与 Bitcoin 相同曲线的 secp256k1 密钥。公钥本身就是该用户的唯一 ID,用私钥对内容签名即可证明「这确实是我发出的」。这里的椭圆曲线密码学保障的不是货币的所有权,而是言论的真实性。
原始的密钥字节对人类并不友好,因此 NIP(Nostr Implementation Possibilities,即 Nostr 的编号提案)系列中的 NIP-19 定义了 bech32 编码的表示方式:公钥编码为 npub,私钥编码为 nsec。没有注册表单,也没有登录界面:生成一对密钥的瞬间,任何人都拥有了一个全新的 Nostr「账号」。
- 由于密码或邮箱从未托付给任何服务器,从原理上讲,任何运营方都不可能冻结或删除一个账号。
- 同一密钥对可以在多个客户端、多个 relay 之间通用,用户不会被锁定在某个特定应用或服务上。
- 与之相对的是,密钥的保管责任完全落在用户自己身上。不同于多签(multisig)这类能够将密钥共管与恢复形式化的密码学系统,Nostr 协议本身并没有标准化的密钥恢复或轮换机制。
事件(Event):Nostr 中唯一的数据结构
Nostr 上交换的所有数据,无论种类,都是一种叫做事件(event)的带签名 JSON 对象。个人资料更新、发帖、点赞、关注列表,全部用同一种结构来表达。
| 字段 | 含义 |
|---|---|
| id | 对事件内容序列化后计算的 SHA-256 哈希,既是事件的唯一标识符,也用于校验内容是否被篡改。 |
| pubkey | 发布者的公钥。 |
| created_at | Unix 时间戳。 |
| kind | 决定事件含义的整数。例如 kind 0 表示个人资料元数据,kind 1 表示一条文本笔记(帖子),kind 3 表示关注列表,kind 7 表示一次反应(点赞)。 |
| tags | 数组的数组,用于表达事件之间的关系与元数据,例如回复对象、提及(mention)或话题标签。 |
| content | 正文内容。根据 kind 的不同,可能是纯文本,也可能是加密后的 JSON。 |
| sig | 由与 pubkey 对应的私钥对事件生成的签名。 |
id 与 sig 这对组合,使得任何人都无需信任某个 relay 或客户端,即可验证「这条事件确实由该公钥的持有者创建,且此后未被篡改」。由于应用层的含义完全由 kind 这一个整数决定,新的用途,从文本发帖到 Lightning 打赏通知,再到长文,只需要通过一份新的 NIP 追加一个 kind 编号即可扩展,无需改动协议本身。
Relay 与 NIPs:在有意「愚笨」的传输层之上叠加的扩展
Nostr 的另一个核心概念是 relay(中继)。Relay 接受 WebSocket 连接,保存收到的事件,并转发给条件匹配的订阅者,仅此而已。它被有意设计得极其简单,即所谓的「愚笨(dumb)」。由于事件的真实性已经由签名保证,relay 本身无需承担更多校验工作,这使其实现可以非常轻量。
关键在于,relay 之间彼此不通信、不同步,也就是说它们不联邦(不 federate)。在联邦式架构及其代表 ActivityPub 中,服务器之间会在协议层面互相转发信息;而在 Nostr 中,冗余与可用性的责任完全落在客户端一侧。客户端会把同一条事件同时写入多个 relay,也会同时从多个 relay 并行订阅所关注对象的更新。某个 relay 宕机,或者开始审查内容,客户端只需切换到另一个 relay,而不会因此被整个网络排除在外。
- Relay 运营者有权拒绝存储或转发某些事件(在自己的 relay 上进行管理),但这并不会剥夺用户的身份或其关注者关系,密钥与社交图谱(关注了谁)是客户端一侧的状态,不属于任何一个 relay。
- Relay 可以是免费的,也可以是收费的,任何人都可以自行搭建。协议本身并不存在 relay 之间的权威或层级关系。
核心规范被有意保持在最小范围内,扩展则以编号形式的 NIPs(Nostr Implementation Possibilities) 提案在 GitHub 上公开讨论。仅通过为 kind 或 tag 赋予新含义即可添加功能,而无需改动协议整体,这正是 Nostr 生态得以持续成长的原因。
- NIP-01
- 基础协议。定义了事件的结构,以及与 relay 之间交换的 WebSocket 消息(用 REQ 发起订阅、用 EVENT 推送事件等),是所有实现都应遵循的基石。
- NIP-05
- 一种验证机制:用
name@domain.com这样便于记忆的标识符代替不便阅读的 npub,做法是将其映射到该域名下的.well-known/nostr.json文件。密钥本身仍然是公钥,DNS 名称只是面向人类的别名。 - NIP-13
- 为事件附加工作量证明(Proof of Work)的机制。要求作者不断尝试 nonce,直到 id 的开头出现规定数量的连续零比特为止,以此提高刷垃圾信息的成本。
- NIP-57
- 将基于 Lightning Network 的打赏行为(称为「zap」)标准化的机制。可以针对一条帖子即时发送少量比特币,比单纯点赞更直接地把价值传递给作者。
在这个简洁的底座之上,涌现出了大量各自独立实现的客户端,其中包括 iOS 上的 Damus 与 Android 上的 Amethyst。只要两个客户端讲的是同一套事件格式与 relay 协议,彼此就能自然互通。
优点与挑战
- 协议的简洁性:由于只有一种事件类型、relay 的职责又极其单薄,客户端与 relay 都能用相对少量的代码实现,协议本身的学习成本也很低。
- 账号封禁在原理上不可能:既然身份就是密钥对,任何运营方都不掌握「删除」账号的权力。即便被某个 relay 拒之门外,密钥与社交图谱也不会因此丢失。
- 迁移 relay 的自由:从不喜欢的 relay 换到另一个,几乎没有任何成本。这与 ActivityPub 中服务器迁移往往伴随账号断裂形成鲜明对比。
- 密钥丢失或泄露后没有恢复手段:一旦丢失私钥,身份、关注者与发帖历史将永久无法访问;一旦私钥泄露,也没有办法阻止他人冒充。协议同样没有提供标准化的密钥轮换机制。
- 垃圾信息防治完全依赖 relay:协议本身并未对发帖设置成本,因此诸如 NIP-13 工作量证明、对写入收费的 relay 等对策,都只能取决于各个 relay 运营者自己的判断。
- 事实上向热门 relay 集中:理论上任何人都可以搭建 relay,但实际连接与数据往往集中在少数几个大型 relay 上,维持一批高可用的替代 relay 缺乏足够的经济激励。
- 全局搜索与发现较为困难:由于 relay 之间不联邦,不存在一个可以横跨「整个 Nostr」的统一检索入口,查找特定帖子或用户往往需要在多个 relay 之间辗转。
Nostr、ActivityPub 与 AT Protocol 的比较
| 维度 | ActivityPub | AT Protocol | Nostr |
|---|---|---|---|
| 身份 | 服务器上的账号(例如 user@instance.tld,以 URL 标识) | DID(去中心化标识符,如 did:plc)加上句柄(handle) | 原始公钥(npub) |
| 服务器的角色 | 每个实例都是完整参与者,负责存储与转发数据 | PDS 持有用户的仓库(repository),AppView 负责聚合与索引 | Relay 只是负责存储与转发的「愚笨」管道 |
| 服务器间通信 | 服务器之间通过 ActivityPub 相互联邦 | 专门的 relay/AppView 对整个网络进行索引 | Relay 之间互不通信,冗余性依赖客户端向多个 relay 并行写入与订阅 |
| 抗审查性 | 实例可以按单位相互屏蔽或断开联邦(defederate) | 更换 PDS 后仍可保留 DID 与社交图谱 | 被某个 relay 拒之门外,也不会失去密钥与关注关系 |
| 身份可恢复性 | 依赖实例运营方,服务器迁移需要专门的迁移流程 | DID 提供密钥轮换机制 | 一旦丢失私钥即无法恢复 |
这三种协议都是为了对抗中心化社交媒体而诞生的,但各自对「把信任的根基放在哪里」做出了不同的选择:ActivityPub 以服务器(实例)为单位实现联邦,AT Protocol 把可恢复的标识符 DID 与承载数据的 PDS 分离开来,而 Nostr 则把绝对的信任交给密钥对本身。究竟该选择哪一种设计,取决于你更看重抗审查性、可恢复性,还是实现的简洁性。
相关页面
Nostr 的设计理念,在与本站介绍的其他去中心化思路的对比中会显得格外清晰。服务器之间彼此转发信息的联邦式架构及其代表 ActivityPub,与 Nostr「relay 之间不联邦」的设计选择恰成对照。同样属于去中心化社交协议的 AT Protocol,将身份的根基放在可恢复的去中心化标识符(DID)上,而非原始公钥本身,这正是对 Nostr 目前仍未解决的「丢失密钥即永久丢失身份」问题的一种回答。私钥应当如何保管与共管的问题,与多签一脉相承;而在 relay 之间高效传播事件的思路,也与流言协议所依赖的 anti-entropy 理念遥相呼应。