撰文:Colby Serpa

编译:DAOrayaki

Nostr 2.0 可能能够作为 Layer 2 建立在比特币之上,提供安全的离链数据存储,就像闪电网络作为 Layer 2 提供即时的离链支付一样。

本文将阐述 Nostr 中继如何在保持轻量级特性的同时同步其数据,使用户可以选择性地删除数据,这是 Layer 1 区块链所不具备的。同时,与在比特币区块链中存储大量数据相比,因为比特币区块的容量和速度有限,使用 Nostr 中继存储数据可能更加便宜。

下面的简单计算机科学设计改进了 Nostr 网络在标准化的 CAP 定理准则下的分布特性。CAP 代表一致性(Consistency)、可用性(Availability)和分区容忍性(Partition tolerance)

Nostr 中继不知道一个配置文件何时是不完整的,中继缺乏一致性(CAP 定理中的 C)

Nostr2.0:作为比特币layer2链下数据存储层Nostr2.0:作为比特币layer2链下数据存储层

中继缺乏一致性(CAP 定理中的 C)

一致性意味着在各个计算机上同步的数据库是相同的。Nostr 中继不能以类似区块链逐个区块同步其数据的方式进行信任最小化的同步。与比特币全节点不同,Nostr 中继存储的数据库通常是不完整的。除了盲目请求由特定用户签名的所有帖子外,Nostr 中继无法发现缺失的数据。

Nostr 的一致性 / 同步问题:

如果两个用户将各自的帖子上传到不同的 Nostr 中继,那么这两个用户可能无法看到彼此的帖子,因为 Nostr 不像一个区块链。在区块链中,每当有新的记录时,所有全节点都会将区块链同步。所有全节点会将这些数据作为一个区块同时添加到他们的区块链中。比特币区块链上的每个全节点都拥有完全相同的区块链。

Nostr2.0:作为比特币layer2链下数据存储层Nostr2.0:作为比特币layer2链下数据存储层

如果我们希望 Nostr 用户始终能够看到彼此的帖子,那么所有的 Nostr 中继都需要一种方式来识别用户配置文件中缺失的数据,以便它们可以从其他 Nostr 中继或用户那里请求缺失的部分。

使用每周的链上 Merkle 根和整个树哈希来同步 Nostr 中继

  • 大约每周一次,用户可以将他们的所有帖子组织成一个 Merkle 树。
  • Merkle 树中的每个叶子包含一个帖子的哈希,就像比特币中每个叶子包含一个交易的哈希一样。
  • 一旦用户将整个配置文件组织成一个 Merkle 树,他们将在链上的 OP_RETURN 中发布 Merkle 根,在一个普通的比特币交易下方。这就是为什么 Nostr 2.0 不需要对区块链进行硬分叉来工作。OP_RETURN 是比特币交易下方的一个区段,允许在发送者签名之前附加小的注释信息。
  • 另外,用户将对整个树进行哈希,并将其与 Merkle 根一起(在 OP_RETURN 中)上传到链上。Merkle 根只是顶部分支的哈希,而不是整个树的哈希。整个树的哈希对于用户和中继能够检测到配置文件数据是否缺失至关重要。
Nostr2.0:作为比特币layer2链下数据存储层Nostr2.0:作为比特币layer2链下数据存储层
  • 要获得整个树的哈希,请将 Merkle 根放置在文本文件的根部。然后,在根下方的行上放置 Merkle 分支。然后,在分支下方的行上放置 Merkle 叶子。一旦树按照描述的方式排列好,一次性对其进行哈希处理。下面是一个整个树哈希的示例,它是上面所示的 Merkle 树的整个树哈希的样子。整个树哈希(一次性哈希所有 Merkle 树数据)
Nostr2.0:作为比特币layer2链下数据存储层

Merkle 根和整个树哈希提供了两个关键功能:

  • Merkle 根允许用户和中继一次下载一个配置文件的一部分,就像能够下载一个交易而不必下载整个区块一样。
  • 整个树哈希让用户和中继知道他们存储的配置文件是否不完整。与 Merkle 根不同,只有在 Merkle 树中拥有所有数据位时,整个树哈希才会匹配。

这种廉价的方法可以用来每周或用户自定义的频率更新整个配置文件。Nostr 仍然可以像现在一样工作,但是如果用户希望所有用户都能看到他们的帖子,他们可以偶尔支付一些 sats 来在 Nostr 中继之间同步他们的数据。

用户和中继可以一次下载一个分支的帖子。在每个分支之后,他们会将该分支与最接近 Merkle 根的另一个分支进行哈希,以检查是否与链上的 Merkle 根匹配(类似于 SPV)。如果这些分支一起哈希与 Merkle 根匹配,那么他们就会知道该分支是用户配置文件的一部分,即使他们还没有完整的用户配置文件。用户可以从许多不同的 Nostr 中继下载同一个配置文件的不同分支,同时验证每个分支的有效性,并确保下载的配置文件是完整的。

逐个下载分支可以防止延迟攻击,这种攻击可能会瘫痪许多分布式网络,这就是为什么比特币白皮书中使用 Merkle 根和分支来保护 SPV 轻钱包的原因。

为什么 Merkle 根不能像整个树哈希一样的功能?

如果 Nostr 中继仅依赖于 Merkle 根,那么它们将无法知道 Merkle 树何时完整,因为最接近 Merkle 根的每对分支都会哈希到同一个 Merkle 根中。

为了确保用户的配置文件完整,中继或用户会将他们更新后的整个 Merkle 树进行哈希,并验证它是否与链上的整个树哈希匹配。如果整个树哈希匹配,那么用户数据就是完整的。如果整个树哈希不匹配,那么中继或用户可以告诉其他中继他们的最新叶子编号,并请求缺失的分支,直到整个树哈希匹配为止。为了跟踪每周左右添加的所有新 Merkle 根,Nostr 中继必须成为比特币全节点。Nostr 2.0 中继通过间接获得报酬来存储比特币区块链,同时增强了比特币和 Nostr 的安全性。

Nostr 存储的限制:用户的经验法则

由于中继有权选择要存储的内容,与比特币全节点不同,Nostr 中继可能会丢失一些用户数据。因此,用户应该只在 Nostr 中继上存储数据,如果用户可以在本地进行备份。Web5 的自托管服务可以让用户将备份同步到所有本地设备上,这将降低对使用 Nostr 感到担忧的用户的风险。归根结底,只有区块链是数据真正不可变的地方。虽然如此,Nostr 是一个相当安全的混合方案,对于许多应用程序仍然能够良好运行。下面列出了权衡的方面:

三层信任最小化

  • 第 1 层:不可变且昂贵的数据存储,极难被审查。(链上区块同步所有比特币全节点)
  • 第 2 层:可变且廉价的数据存储,中等难度的审查。(离链 Merkle 树和链上哈希,按需同步 Nostr 中继)
  • 本地数据存储同步到所有本地设备,容易被审查。(本地集中化)

基于 Nakamoto 共识的区块链和 Nostr 之间的根本权衡

存储特定地址数据的 Nostr 中继越多,越难以审查该数据。这意味着由许多 Nostr 中继托管的热门数据可能比很少被下载的不受欢迎数据更难以被审查。

另一方面,Nakamoto 共识区块链可以防止基于数据的年龄进行审查。数据在区块链中存在的时间越长,使用 51% 攻击删除数据就越困难。

使用可检索性证明(Proof-of-Retrievability)的 ZKCSP 与闪电网络支付 Nostr 中继

由于我们可以验证某些分支属于特定用户,所以每当 Nostr 中继将一小段数据传递给用户时,就可以向它们支付报酬。为了实现这一点,用户需要下载区块链的头部(就像在 SPV 中那样),以便能够执行轻钱包的典型功能。用户将利用轻钱包的 SPV 功能从链上获取特定的交易,该交易将在其 OP_RETURN 中包含用户配置文件的 Merkle 根和整个树哈希。现在,用户可以支付中继逐个分支地下载该用户的配置文件,并通过将它们进行哈希运算以与链上的 Merkle 根匹配来验证每个分支。

为了向 Nostr 中继发送 sats(比特币的最小单位),以交换提供数据,我们使用 Gregory Maxwell(著名比特币核心开发者)的 ZKCP 设计(零知识条件支付)[1]的演化版本,即 ZKCSP:可检索性证明[2]与闪电网络相结合。

根据 ZKCSP 白皮书的描述:

「…不需要可信任的第三方…我们还为可检索性证明的情况实现了 ZKCSP 协议,客户向服务器支付费用以获得证明客户数据在服务器上正确存储。」 [2]

Nostr2.0:作为比特币layer2链下数据存储层Nostr2.0:作为比特币layer2链下数据存储层
  • 用户与几位融资者启动了一个闪电智能合约。
  • 用户向周围的融资者发送请求。融资者对该请求进行签名。
  • 用户将融资者签署的请求直接发送给与这些融资者连接的 Nostr 中继。
  • 用户现在启动 ZKCSP 构造,以确保只有在正确请求的数据被传递后,Nostr 中继才会从融资者那里获得支付。

一旦发生第 3 步,用户在第 4 步中启动 ZKCSP 构造之前,将在融资者签署的原始请求之上进行修改。用户将在原始请求之上添加额外的内容,指定从用户和融资者的余额中扣除的金额(它们必须是相同的金额,加上融资者的费用),然后用户将对其添加到原始消息上的内容进行签名。

如果用户指定要发送的 sats 超过其拥有的数量,或者超过融资者在该 Nostr 中继上冻结的数量,那么 Nostr 中继将拒绝该请求,因为中继将无法得到支付。

通过这种方式,用户可以与许多 Nostr 中继连接,同时只与少数融资者冻结他们的资金。闪电网络也可以采用类似的方式,其中信任最小化的融资者是用户和商家之间的无需许可的中间人。在 Nostr 2.0 中也可以使用普通的 P2P 闪电跳,但是如果路由和通道平衡经常失败,这种方法可能会很有用。

白名单解锁付费 Nostr 中继

如果 Nostr 中继希望存储所有这些用户查看的数据,它们可以将某些密钥加入白名单。如果 Nostr 中继无法将希望存储数据的用户加入白名单,那么它们将存储发送给它们的任何数据。如果用户始终可以免费向中继发送数据,那么用户将永远不需要支付 Nostr 中继。只有当中继有拒绝存储无法支付的数据的选项时,Nostr 才能提供付费选项。免费中继仍然存在,但目前不存在付费中继的选项。

付费的 Nostr 中继可以使用白名单选择性地存储其付费用户每天查看的所有数据,而不是试图免费存储所有 Nostr 数据。一些 Nostr 中继将继续采用免费模式,但在最大规模上,这是不可持续的,因为大多数免费中继只是热情的爱好者。白名单(即使我们能够为每个 Nostr 配置文件安全地分配一个公钥)赋予 Nostr 中继决定哪些数据存储的能力,将不可能实现。

每个配置文件一个公钥解锁白名单功能:比特币地址成为您的 Nostr 公钥

该系统最终使我们能够为每个配置文件分配一个公钥。

用户为每个帖子创建新的公钥没有任何好处...因为它们都与他们的配置文件关联!这与比特币地址不同。与比特币不同,让用户在同一个应用程序中拥有多个公钥并不会提高隐私。

Nostr 配置文件的公钥必须与包含每周哈希值(用户所有帖子的 Merkle 根和整个树哈希)的比特币交易的公钥匹配。与 Nostr 用户使用 Schnorr 签名不同,他们将需要使用比特币钱包(移动钱包 / 轻钱包或完整节点)进行签名。

这个美妙之处在于,每个 Nostr 账户都将用其比特币地址表示,这意味着用户可以直接向 Nostr 账户发送付款,而无需请求两个不同的公钥。这降低了新用户在系统中的认知成本。用户仍然需要向彼此发送公钥或 DNS 以在 Nostr 上找到对方,而不是使用用户名。

如果其他 Nostr 应用程序使用不同的公钥,它们仍然可以附加到相同的去中心化身份(DID)上 - 这样,识别您的账户的方式在应用程序间仍然保持一致。不过,这个 Nostr 共识规则将限制每个 Nostr 应用程序上的每个配置文件只能使用一个公钥。

DHT 作为对等发现排行榜。

中继可以使用分布式哈希表(DHT)来找到其他中继。中继可以通过列出存储数据的公钥来在分布式哈希表中共享其白名单。这样,对于某个公钥的数据缺少分支的中继可以扫描 DHT 并直接连接到声称存储那些缺少分支的其他中继的 IP 地址。然后,中继可以直接从这些 Nostr 中继下载缺少的分支。

中继还将能够通过检查这些中继在链上解决了多少以前的 ZKCSP 交易 - 近期和全部时间 - 来找到最活跃的中继。在这个系统中,所有 Nostr 中继都成为完整节点,所以审计其他中继的先前交易将是轻松的。这将使得伪造信任成本昂贵,因为链上交易总是需要交易费用。如果 Nostr 中继打开许多通道与自己建立信任,以获取其他中继的信任,他将不得不支付大量交易费用来维持每周的虚假声誉。在攻击者无法提供缺失的分支之后,超时将导致中继断开连接 - 因此这只是一种暂时的、代价高昂的攻击(就像 51% 攻击是一种暂时的、代价高昂的攻击)。

DHT 不像挖矿那样匿名,因为每个 Nostr 中继的公钥将在 DHT 中的 IP 地址旁边列出,但它将避免中继在网络上盲目发送请求的需求 - 在足够大的规模下,这将导致网络超载。希望获得更高隐私性的 Nostr 中继可以使用 VPN 或其他 IP 保护服务。

用户将无法访问此相同的信任系统,因为他们不是完整节点。不过,用户可以依赖。

金融家间接连接到数百个 Nostr 中继

由于用户在其轻钱包中自动存储了所有区块头,用户可以查看最活跃的矿工是哪些。矿工成为金融家将使用户能够筛选出最受欢迎的矿工,这样他们就不必盲目地将资金与没有与网络的生存能力相关的随机金融家绑定。

金融家(矿工)只需要将他们的 sats 与 Nostr 中继锁定,而不需要在用户和中继之间传递数据本身。金融家(矿工)只需签署用户的请求,以便用户可以直接与金融家连接的所有 Nostr 中继进行交互 - 如上所述的 ZKCSP+Lightning 的 4 个步骤。

结论

如果没有比特币的 Nakamoto 共识区块链,闪电网络将无法存在,因为用户将没有地方存储其离链交易的捆绑证明。

就像用户将所有这些闪电网络交易捆绑在一起并将小证明放入区块链中一样,我们将捆绑所有 Nostr 数据并将小证明放入区块链中。与闪电网络在第二层提供即时支付的方式相同,Nostr 可能能够在第二层提供数据存储,而无需承担不安全的侧链的风险。

它采用了与闪电网络相同的方法,其中比特币的 Nakamoto 共识区块链位于第一层,Nostr+ZKCSP 闪电位于第二层。