RGB++ 深入讨论(1): 安全性分析

Special thanks to Ren Zhang , Ian, and c4605 for feedback and discussion.

The RGB receiver optimization approach is inspired by Jason Cai.

PoW 比你想象的更安全

PoW 的安全性风险在于区块 revert/reorg,从而导致双花。只要有一个诚实矿工,用户的状态/资产就不会计算错误,只有可能出现因区块重整导致的双花交易损失。因此 PoW 的核心安全假设就是 N 个区块后交易就几乎不会被 revert 了,例如 Bitcoin 普遍认为 6 区块甚至更少即可。

显然,6确认的 BTC 肯定比1确认更安全,那么 PoW 确认数和安全性是线性关系吗?并不是,推翻区块的难度随着区块深度指数增长,这个指数增长具体的参数已经有几十篇论文在讨论了。随着时间的推移,大家发现“NC比从前以为的更安全”。

根据 Ren Zhang 博士的计算,假设敌手算力占比30%,要实现比特币中孤块率为0、6个块确认的安全性,当 CKB 的孤块率设定成 2.5% 的时候,需要23.29个块确认即可达到相同的安全性 。通过这样的等价关系,我们可以在后续的讨论中方便地讨论 RGB++ 协议中各种典型操作的安全性。

PoW 安全性的示意图(非理论计算

RGB 的安全性

RGB 通过一次性密封和客户端验证的方式实现了在 Bitcoin UTXO 上绑定 RGB 的状态和合约,为 Bitcoin 提供了图灵完备的扩展。交易安全性有两类,一类是状态计算的正确性;一类是交易确定性,即双花风险。客户端验证确保了状态计算的正确性,每个人负责自己的状态,不依赖任何第三方。而基于 BTC UTXO 的一次性密封确保了双花 RGB 的难度和双花 BTC 的难度相同。因此,我们可以说 RGB 100% 继承了 Bitcoin 的安全性。用户需要多安全,就按照比例等待多少个 BTC 确认即可。

RGB++ 的安全性

L1 交易安全性

RGB++ 的 L1 交易指的是 RGB++ 交易的 UTXO 的"持有人" 是 Bitcoin 的 UTXO。即只有消费 Bitcoin UTXO 才能操作或更新 RGB++ UTXO。这种情况下,虽然每一笔 RGB++ 交易都同步发起一笔 CKB 交易,但其安全性和 CKB 没有关系,CKB 仅作为 DA 和状态公示来使用。这种情况下,RGB++ L1 的交易安全性和 RGB 交易相同,也是完全继承了 BTC 的安全性

L2 交易安全性

L2 交易即 100% 发生在 CKB 上的交易,显然它的安全性 100% 由 CKB 负责。但由于开篇提出的 PoW 安全的非线性特性,24个区块的 ckb 确认即可等价于 6 确认的 BTC 确认,因此我们也可以说 L2 交易安全性与 L1 交易安全性等价(需要更多区块确认,但事实上更短确认时间)。

能做到这一点的前提是 RGB++ 的同构映射链必须是 PoW 的,如果它是 PoS 的链,无论等待多少个区块,它安全性上限都是 PoS 的 stake 量,无法与 Bitcoin 安全性等价。

Jump 操作

RGB++ 协议中用户的资产既可以在 Bitcoin 上流转,也可以随时到 CKB 上流转,或者反向操作。在切换的过程不需要跨链桥,更不需要信任任何多签方。我们将资产或状态在 Bitcoin 上和 CKB 上流转的切换称为 Jump。Jump 操作前后,影响 RBG++ 协议安全性的核心点在于:

  • 一次性密封条,从使用 Bitcoin UTXO 变为使用 CKB UTXO,或相反

  • 客户端验证所需要的数据保持不变,都是 CKB 上的同构绑定交易

Jump 操作时,用户需要在两条链上分别等待足够的区块数,以获得安全性。

兼顾用户体验

根据上面的讨论,等待足够多的区块数确实可以获得足够的安全性,但用户体验实在太差了。考虑平庸的方案,每个 RGB++ L1 交易要等待 6 个 BTC 确认再进行下一次操作,每个 L2 交易要等待 24 个 CKB 确认再进行下一次操作,而 Jump 操作则需要等待 6 BTC + 24 CKB 确认。能否对这个方案进行优化呢?

RGB 收款方 UTXO 的优化

考虑原 RGB 协议,为了实现交易隐私性,Bitcoin 上发起的 RGB 交易的收款方(以一个 Bitcoin utxo 表达)和这笔 Bitcoin 交易的 output 并不一致。这使得观察者无法通过追踪 bitcoin 交易的方式来追踪 RGB 交易。

但在 RGB++ 协议中,所有的 RGB++ 层交易都同构绑定并公示在 CKB 上,尽管极大地简化了用户的交易验证难度,也较为遗憾地损失了 RGB 协议的隐匿性(RGB++ 协议可以利用 CKB 的隐私层引入更为强大的隐私属性)。所以 RGB++ 协议在收款人方面做了调整,它不要求收款方预先提供一个自己的 UTXO,而只需要提供一个收款地址,RGB++ 交易本身在构造 BTC 交易时会生成一个 UTXO 指向该收款人地址。这样就可以完成非交互式转账,大幅简化了用户的操作流程。注意下面的示意图做了一些简化,为了实现同构绑定,某些包含在 BTC TX 和 CKB TX 中的字段不会被包含在 commitment 中,以防止出现互相包含的矛盾。

交易串接

上面的 RGB 非交互式转账的优化不仅仅有利于提升用户体验,对于交易确认的优化也有本质的作用。

首先对于一个诚实的用户,尽管区块 reorg 经常发生,但只要该用户不主动进行双花交易,BTC 链上打包的用户交易是不变的,因此不会影响到 CKB 链上的 RGB++ 资产和状态。

考虑一笔 L1 RGB++ 交易,假设为了用户体验我们允许单块 BTC 交易确认即可发起同构交易,即在 CKB 构造同步的 RGB++ 资产交易。此时,对于恶意用户,TA 可能构造一笔新的 BTC 交易,取代之前的 BTC TX B,使得 CKB TX B‘ 找不到对应的 BTC 交易,但这时 CKB TX B’ 已经上链。这里的后果是,在 BTC 上被双花的 btc_utxo#2 在 CKB 上的同构映射 cell 已经在 CKB TX B’ 中消耗了,即使用户双花了 BTC 上的 utxo,他也无法双花 RGB++ 的资产,同时先前交易生成的 RGB++ cell 输出( lock 为 btc_utxo#3)也因为链式交易的失效而被用就锁定。所以恶意用户在 BTC 上做双花交易不会有任何收益,还会导致自己的资产失效。

考虑一笔 L2 RGB++ 交易,它 100% 运行在 CKB 上,因此我们只需要符合原来的交易逻辑即可,即也可以在 dapp 中获得连续操作的体验。

最后考虑一笔 Jump 操作,用户将 RGB++ 资产从一个 Bitcoin UTXO 中转到一个 CKB 地址上,后续的操作会持续发生在 CKB 上,此时我们需要考虑因 Bitcoin TX revert 造成的 CKB 上资产复制的问题。

考虑上面的交易,BTC_TX_A 和 CKB_TX_B 同构绑定,之后 BTC_TX_A 被重构成 BTC_TX_A’,此时同构绑定的交易 CKB_TX_B’ 无法通过 ckb 共识上链,因为它依赖的 input (lock= btc_utxo#1)已经在 CKB_TX_B 中被使用了。这就导致 BTC 上的交易和 CKB 的交易同构绑定失败。但注意,如果同构绑定失败,但相关的所有资产均被锁定,那么我们不认为出现了安全性问题。因为这种失败源自交易发起人主观攻击协议,那么TA的所有资产被永久锁定不是问题。

但图示的操作中,我们发现 CKB 上的两个输出,RGB++ cell 的 lock 是 btc_utxo#2,它依赖被 revert 的旧的 BTC 交易,因此被永久锁定,没问题。单另一个 ckb cell 则不受影响。这就造成了安全风险。

因此,我们引入一个新的 lock,暂定名为 btc_time_lock 通过提供额外的锁定逻辑来解决这个问题。

BTC Time Lock

btc_time_lock 的核心参数有三个,分别是 lock_hashafter,和 bitcoin_tx。它具体的含意是:“仅当在参数中指定的 bitcoin_tx 被超过 after 个 btc 区块确认后,本 cell 才可以被解锁,且解锁后需要换成 lock_hash 指定的 lockscript(ckb 地址)”。 我们以上面的例子看一下 btc_time_lock 是如何工作的。

和之前的讨论相同,如果 BTC_TX_A 被 revert 了,对应的 RGB++ Cell 被永久锁定,而其他的 CKB cell 则按照要求被放置自啊 btc_time_lock 中,且他们被解锁的条件是 BTC_TX_A 经过了 6 个区块确认。那么显然由于 BTC_TX_A 不存在而因此被永久锁定。反过来讲,如果 6 个 btc 确认后,BTC_TX_A 仍然存在,那么该 CKB Cell 就可以正常使用。

总结

总结来说,RGB++ 不论在 L1 还是在 L2 上都可以获得与 Bitcoin 相同级别的安全性,在 L1 和 L2 Jump 时,RGB++ 协议额外要求资产锁定 6 个或更多的 BTC 区块,以获得在跨层使用时一致的安全性。RGB++ 协议在不妥协安全性的前提下为 BTC 网络进行了图灵完备的补充和性能的扩展。

12 Likes

我对这里“安全性”的前提/定义比较疑惑,有些不同的看法。如果考虑数据可用性——RGB 交易的数据只在相关用户之间链外交换,是一种 partial replication,与 Bitcoin 正常交易 (full replication) 相比,应该说削弱了安全性或者增加了前提(用户能管好数据)。因此我不认为 RGB 是 100% 继承了 Bitcoin 安全性。

也有因为这个原因,RGB++ 把原本只在链外交换的数据放到了 CKB 链上,使得数据在 CKB 网络里面 full replicate (也可以说用 CKB 做 DA),使得 RGB++ 交易在这个维度上更安全或者只需要更弱的前提(而不是相同),但也因此牺牲了隐私性。

3 Likes

这里被花掉 Cell(lock=btc_utxo#1) 是怎么创造的?攻击者有可能在 L1 revert 之后创建另一个 Cell’(lock=btc_utxo#1) 吗?

3 Likes

这是个很好的思考,之前没有考虑到。之前的设计是允许任何人创建任何 Cell(lock=btc_utxo)的,这样会导致 RGB++ Cell 与 BTC UTXO 的解绑,例如一笔 RGB++ 交易生成了 Cell(data=1234, lock=btc_utxo#1),用户下一笔交易可以使用另一个 Cell(data=5678, lock=btc_utxo#1) 作为输入。

这样看来,RGB++ 的资产类型必须是有额外的逻辑,不能直接复用 CKB 现有的 xudt/spore 资产,这个额外逻辑就是 Cell(type=rgbpp, lock=btc_utxo#1) 创建时必须验证同构绑定的 btc 交易的 output 中可以找到对应的 btc_utxo#1。这样用户就无法随意创建一个新的 Cell’(lock=btc_utxo#1)

本质上是Lock作为output的时候无法执行验证的原因?
能否使用这样的模式,一个是资产 cell,资产 cell 的 owner 是一个Type Script,该Type Script 的 lock 是 always_success,这样就可以执行检查了。

在RGB++里可以使用的代码,我觉得所有使用 data_hash 模式的应该不用在RGB++里部署 (因为直接绑定代码),但是使用 type_id 模式的代码会有问题,即交易序列无法导出成脱离CKB仍可验证的序列。

header_deps, cell_deps以及since,如果考虑到可导出性,感觉都需要做一定的约束,以保证其可以导出一个不依赖CKB即可验证正确性的交易序列(为了其作为 L2 的正统性需要,避免被攻击成侧链方案)。

如果是这样的话,RGB++ Cell 需要特殊的发行/创建逻辑,xUDT 应该是可以做到的(可以通过 owner lock 和 extension script 定义)。Spore 当前版本是否能做到不确定,可能需要一些升级。

好文!
高手论道如龙出没!或行九天,或潜深渊,只在转念一瞬之间!
争取多看几遍能对RGB++的安全性有更深入的理解!

看完了,感谢,我之前提问题的时候以为 RGB++ 在某些情况下下是可以完全和 RGB 协议兼容的,所以提出了一些问题,这次看你的文章才意识到其实 RGB++ 和 RGB 协议构造的 BTC TX 应该是完全不兼容的,所以我纠结的有一个问题是不存在的


我看到之前那个帖子和这个帖子里都隐约提到了 CKB 链上的 bitcoin 轻客户端(比如这个帖子里提到了要有一个 btc_time_lock ,验证交易已经经过了多少个,bitcoin block),请问关于这个轻客户端有什么文档吗?我想了解一下(抱歉我对 CKB 生态不是非常熟悉……)


另外,在这段文字中,提到 CKB TX B’ 无法被执行,因为它依赖的 btc_utxo#1 已经被占用了

考虑上面的交易,BTC_TX_A 和 CKB_TX_B 同构绑定,之后 BTC_TX_A 被重构成 BTC_TX_A’,此时同构绑定的交易 CKB_TX_B’ 无法通过 ckb 共识上链,因为它依赖的 input (lock= btc_utxo#1)已经在 CKB_TX_B 中被使用了。这就导致 BTC 上的交易和 CKB 的交易同构绑定失败。但注意,如果同构绑定失败,但相关的所有资产均被锁定,那么我们不认为出现了安全性问题。因为这种失败源自交易发起人主观攻击协议,那么TA的所有资产被永久锁定不是问题。

请问这是如何实现的呢?CKB 链上能有一个全局的索引机制来列出所有已经被 RGB++ Cell 的锁引用过的 BTC UTXO 吗?

感觉这里讨论了三个内容:

  1. 数据可用性
  2. 状态计算的正确性
  3. 交易确定性

关于数据可用性
在 RGB 中,数据可用性完全由用户自己保证,一旦用户自己丢失了数据,就很难恢复相关的 RGB 资产。

而在 RGB++ 中,数据会额外再存一份在 CKB 上,就是所说的用 CKB 做 DA。这一过程并不妨碍用户自己再存一份。

此时会存在一个新的问题,如何保证 RGB++ 的数据被 100% 地保存到了 CKB 上?

我理解应该是只要在 Bitcoin 上有一笔 RGB++ 的交易,任何人应该都可以拿着 Bitcoin 的 TX 数据在 CKB 上同步这笔交易。(这一点我并不确定,求 @Cipher 解惑)

在此同步过程中存在两个问题:

  1. 同步是否需要 Bitcoin TX 以外的数据。如果需要其他链外数据的话,可能会存在用户没有公布的问题。
  2. 同步交易至 CKB 链上的经济激励问题。毕竟 CKB 链上同步交易是需要消耗 Gas,并且有可能需要创建新的 cell 占用 CKB 的。(这个在早期应该不是问题)

整体而言,RGB++ 的数据可用性高于 RGB,当然也会牺牲 RGB 额外的隐私性。(我个人并不是很认可 RGB 完全客户端验证带来的隐私性,因为这个对整体系统可用性的破坏有点太大了)

关于状态计算的正确性
RGB 是客户端验证,用户对状态计算的正确性负责。(PS:这里我不确定是否存在,用户下载了有问题的客户端,导致状态计算失败的情况 :joy:。)

RGB++ 应该是会在 CKB 链上再次进行相关的状态计算,所以状态计算的正确性由 CKBVM 和 CKB 上的 RGB++ 智能合约保证。当然这并不影响用户自己进行客户端验证。

整体而言,如果是客户端验证 + CKB 上的 RGB++ 交易确认的话,状态计算的正确性最高,有点像你自己算了一遍,然后又邀请了一个高手算了一遍,double check 最安全。

当然不管对于 RGB 还是 RGB++,状态计算的正确性都是比较容易保证的,毕竟算错了很容易看出来。

关于交易确定性
最后,RGB 和 RGB++ L1 交易的确定性都 100% 来自于 Bitcoin,两者在这一点上无异。


所以这里应该是:

  • RGB 100% 继承了 Bitcoin 的交易确定性
  • L1 的 RGB++ 100% 继承了 Bitcoin 的交易确定性。同时如果你愿意在发起一笔 RGB++ 的 L1 交易时,double check 一下 RGB++ 在 CKB 上的同步交易的话,还将获得基于 CKB 的数据可用性和状态计算的正确性
1 Like

BTC 轻客户端的设计讨论在这里,比较技术,欢迎参与讨论:[2024-02-21] BTC SPV on CKB · GitHub

这是因为 BTC 上的 btc_utxo#1 只能被花费一次,我们是盯住 BTC 的。

2 Likes

感谢回复!我去看看


噢我想明白了,我漏了 jump 交易也是需要花费 RGB++ Cell 的

1 Like

假设敌手算力占比30%,要实现比特币中孤块率为0、6个块确认的安全性,当 CKB 的孤块率设定成 2.5% 的时候,需要23.29个块确认即可达到相同的安全性 。通过这样的等价关系,我们可以在后续的讨论中方便地讨论 RGB++ 协议中各种典型操作的安全性。

这个假设不能理解。简单的假设敌手算力比例可以比较 NC 的理论协议,但是无法比较现实世界中不同系统规模和网络规模的差距。尽管我没研究过相关的论文,但是比特币网络的安全性一定与算力相关。如果期望 CKB 获得与现实世界中比特币网络相似的安全性,那么应当假设相同量级的敌手算力而不是“比例”。

但由于开篇提出的 PoW 安全的非线性特性,24个区块的 ckb 确认即可等价于 6 确认的 BTC 确认,因此我们也可以说 L2 交易安全性与 L1 交易安全性等价(需要更多区块确认,但事实上更短确认时间)。

基于上面假设的不认同,我觉得可能需要重新考量 L2 交易的安全性。

需要指出一点,在思考PoW安全性时需要考虑「哈希统治率」,即全球所有计算这个哈希的算力,该链的PoW算力在其中占比多少,而一般使用独有的哈希算法+ASIC的,哈希统治率都是很高的,那么除去敌手算力之外,全世界其他地方也找不到更多的算力用来攻击了。而当存在巨大的外部算力源时,即使PoW算力很高,也不安全。

这个确实是这样,当资产jump到L2的时候,其抗双花能力就更多是由L2来保证了,在原始的RGB协议中也有类似的设计,即 xchain, 见rgb-core/src/contract/xchain.rs at 18e49327e2557bb9a2777036c36f3764404e70a2 · RGB-WG/rgb-core · GitHub ,目前xchain支持Liquid,而Liquid似乎是一个联盟链。

不信任除BTC以外链抗双花能力的用户可以永远不使用类似jump或者xchain的机制,完全没问题,这是可选的。

3 Likes

被提醒来爬上来讨论一下这个点。
比较两个不同的共识协议的确认概率,没有完美的方法。根本上,CKB和Bitcoin的密码学谜题不同,直接拿算力(每秒钟尝试次数)来估算肯定不合适。
所以一直以来都有两个可以切入的方法:

  1. 直接拿CKB和Bitcoin各自所有矿工每秒钟的耗电量,作为两个币算力对比的估算值,假设敌手用同样的电费能够以多大的概率推翻多少个区块。这应该是您觉得更合理的方法。
  2. 算敌手控制同样比例的矿工,即Cipher文中采用的方法。

我个人觉得对于和Bitcoin采用不同哈希谜题,且有独立ASIC矿机的链,用2.更合理,因为客观上讲,在(a)拿出一大堆钱当电费,和(b)变出一大堆CKB矿机,这两个任务中,显然(b)的难度要大于(a),而且大很多。

1 Like

第二个假设里跟矿机数量没有关系,贿赂现有的矿机也可以提高敌手的算力。“敌手控制同样比例的矿工”不能等于“变出一大堆CKB矿机”。我比较认同 orange-xc 的说法。用户信任或者不信任 CKB 还有信任的程度是可选的,rgb++ 提供给用户这种可选的能力。

您说得很对,我怎么就把贿赂这个事儿忘了呢。

嗯PoW比较容易留出这种灵活性让用户选择。

关于收款人的调整,我有个疑问,btc_utxo#2 所属的 Bitcoin TX 收款方是否能对该 UTXO 进行 RBF?即该指向收款人地址的 utxo 具体的构建是一个什么流程,这笔 tx 的 input 的来源是什么?

据我了解 RGB 每次交易都必要有一笔 btc 的 tx 产生,上述的简化是否可以理解RGB++ 每次交易都需要两笔 btc 的 tx?

如果是这种形式的话那么只是对收款方操作上的简化,实际上的流程是复杂化了,同时产生了额外的费用,这笔额外的费用是需要哪一方来承担呢?

如果说 btc_utxo#2 就是Bitcoin TX A 的 output,那么问题就是变成:本来 sender 进行一次 RGB 资产 transfer 只需要支付 TX A 的 tx fee,完全可以将 outputs 指向自己的地址,但简化后就变成 sender 在进行 RGB 资产 transfer 时,就必须额外向 recipient 转一笔 btc,这样对 sender 来说不是很友好。

还有一个问题是,sender 可以在一笔 tx 中封装多笔 RGB 的资产 transfer,而 RGB 链下数据会记录每一笔关于自己的 transfer 记录,资产稍微一多的话,链下数据的增长速度会很快,如果说 RGB++ 将资产合约放到链上,则需要同步所有账号的对应的 transfer 记录,CKB 有能力承载这么多的数据吗?关于这点 RGB++ 是如何解决的呢?

2 Likes

对,就是这个方案,这个 output 只有最小的粉尘聪,几百 sats,< 0.5 美元(1B=70K) ,相对于手续费,不是一个显著的数值。换取的是非交互便利性。

L1 上的 RGB++ 交易再快再多也会收到 BTC 交易的限制,对 CKB 来说不构成压力。但是通过 Leap 操作后,大量的交易会直接发生在 CKB 上,这时候确实会有吞吐量的要求。后面我们会做基于 UTXO 子链的扩容方案,正在设计中。

4 Likes

听说过一个发生在BTC上的一个故事:当年早起BTC的全网算力还不太大的时候,有个大矿工,手里的算力已经超过了51%了,但是他的选择是关掉部分算力,避免自己的算力超过50%,他说,如果矿机全开,那么手里的BTC可以就没有价值了。
不作恶,可能并不是没有能力,而也可能作恶的成本自己损失最大,
这个经济机制也是BTC的白皮书设计的一部分。
据说这位BTC矿工是位国人。

2 Likes