Very good topic.
Proof of Buying brings L2 consensus closer to mining than staking: participation has a real, irreversible cost on L1, not just locked capital.
That direct economic link to L1 security meaningfully changes the dynamics compared to PoS.
The key question is how PoB can evolve into a sustainable long-term value and utility mechanism for CKB.
我又学习以及理解了2天。这个PoB模型好像真的有且只有CKB可以用:
PoB + Fiber =用 PoW L1 代币CKB(能量结晶)作为成本,通过链下即时支付状态通道表达出块意图,在 L2 侧完成高频、低延迟的随机出块竞争,再把结果最终锚定回 L1。
实现:能量传递+价值捕获
这样理解对么?
poB是最适合在CKB 上做的,但并不是唯一的。
之所以是poB最适合CKB,首先是因为CKB天生就是为L2服务的L1, 其次是因为ckb有足够强的脚本编程能力(BTC就没有) 并且是基于POW这种 trustless极高的Layer1.
如果你想在其他L1上做poB L2也是可以的,但要考量清楚,他们的L1是否足够可信。因为poB是有信任假设的,它是基于L1的安全来做自己的安全基石。当你选择的L1不够安全的时候, poB的安全风险也是显而易见的
3 Likes
Fai
26
写的好
,也确实挺适合CKB的。大咖们多探讨,希望把CKB的初衷L1+L2中的L2方案丰富起来。
补,如何解决L2出块间隙比L1短的情况下的出块共识问题
前面我们提及了proof of buy要在出块共识的时候通过 VRF + 支付L1 token的方式来竞选出块权, 但我没有解释一个问题,如何支付L1 token?
我们都知道, L2的出块间隔 跟L1往往不同, 如果L2比L1出块更慢还好, 倘若L2出块比L1更快呢? 此时,如果矿工支付L1 token来竞选高度为100的L2区块,那么当发起了一笔L1 token的转账之后,L2 的第100个区块已经要出块了,而L1的出块还早,这就导致你这个支付token的交易在L1上还未出块呢, L2已经出块了。 此时L2看不到此时L1 token谁支付的多,它便不知道当前块高的出块权应该给谁。
该问题如果不解决,那么使用proof of buy的L2的出块时长就必然会受制于L1的出块时长。 最终导致L2为求更好的解决方案不得不重回 pos + BFT之类的共识(比如 stacks的poX)
预支付
针对此类问题,proof of buy可启用预支付的方式,即矿工们可以提前一次性 为未来 N个区块 总共支付一笔L1 token。 然后每次L2出块时从中声明出部分额度来表示自己愿意为此次出块所支付的L1 token数量。具体流程如下:
从创始区块开始,矿工先在L1上隐私支付一笔token (我们假设其token数量是一个密文承诺,记作 A) 给proof of buy指定的地址。这之后, 每次L2出块的时候, 矿工在本地生成VRF Output的同时,也需要声明自己要为该区块支付的一笔L1 token数量,记作 a_n(n表示块高。不需要在L2上真正支付,因为之前已经在L1上支付过了) 并生成一个zk proof,证明 a_0 + a_1 + … + a_n <= A, 此处表示自己已为该L2区块预支付过token了且金额足以支付从0到n的这些区块。
其他L2矿工拿到 (VRF_output,a_n, zk_proof) 之后, 根据L1上的A来验证 zk_proof,证明通过之后,将 VRF_output 和 a_n 代入计算中 来算出值 以得出该高度谁最终赢得出块权。
3 Likes
why NOT burn
会有人疑问为何不将L1的token直接烧掉,这样可以制造通缩从而抬升L1 token的币价。首先,要强调一个前提,proof of buy的设计是希望更多的应用链可以作为L2挂载在L1上,也就意味着我们预先考虑的一个问题是如何让proof of buy在L1上可以大规模可持续性的使用。
此时,如果将L1 token燃烧掉,我们将可能面临以下后果:
- 当燃烧速度 > L1 token的增发速度,其本质是在消灭L1的财富,L1将面临流动性枯竭甚至消亡的可能。这并不是一个可以让 L1 + 众多 L2可持续发展的方式
- 当燃烧速度 <= L1 token的增发速度,其本质为再分配。想象一下,你烧掉了一部分L1 token,然后L1通过增发将这些L1 token重新还回来。那么就得问一句:这种再分配的方式是怎样的,谁应该得到这些L1 token? proof of buy 直接将这部分token转账给一个固定的地址(比如L2项目方基金会的钱包地址)是否也是这个方式下的特殊场景?
- 随着烧掉的L1 token造成了通缩,使得L1 token的币价越来越涨, L1 token持币者意愿会越来越强,他们会越来越不愿意将手里的token烧给L2, L2的共识安全成本会因此越来越低
思考完上述问题之后,会引出一个问题, 那就是在proof of buy中, L1 token接收方(L2项目方基金会)由于一直在吸纳L1 token,长此以往下来,对于L2自己而言,他可以几乎无成本作恶(比如51%攻击),因为如果他自己参与挖矿出块,也是自己给自己支付L1 token,它除了在需要在L1上支付少许手续费之外没有其他成本,而其他矿工还会给他不断支付L1 token。怎么看这也是一个稳赚不赔的买卖,那么我们该如何防止这种情况呢? 且听下回分解~
3 Likes
VRF加权
为了防止富者(比如上述的L2项目方自己)垄断出块权和攻击网络,我们需要使用随机数对L1支付金额进行加权,以让出块权的选举不能单纯只靠支付金额大小。
我们引入VRF,并让VRF的输出结果与支付的L1 token金额结合在一起进行计算,我们用数学式来表达为: goal = f(L1_payment, vrf_output) 每个出块节点想竞争出块权的话必须在出块时广播自己的goal 并连同L2 block header一起 上传到L1 block,只有goal最大的才会成为该高度的区块。
fork choice
传统L1共识中,我们在finalize consensus的时候会用BFT或者最长/最重子链来决定哪条分支是主分支。但是在L2中,我们可以利用一些L1中没有的东西进行辅助finalize。
在这里为了方便理解,我们假设L1的出块间隔是10秒,L2的出块间隔是3秒。 当L1 的第1个区块出块完成时, L2已经完成了 高度 = 1、2、3 的区块的出块。 因为上一步我们会把goal 和L2 block header上传至L1,所以此时,L1的第1个区块上是存在L2的第1~3个区块的。 但这并不意味着这个L1 block上只有3个区块。 L2的高度=1的区块可能不止一个,其他矿工也可能上传这个高度的区块,形成不同的fork,此时我们则需要进行finalize其中一条为主分支。
proof of buy的原则是, 在这些fork中选择 max(goal)的那条作为主分支。因为goal中的VRF output很难被伪造且每个出块都是有实际的L1 token支付成本,如此,其他人只需要根据goal的数值便可知道自己该在跟随哪个fork。
并且,一旦L1 block 出块完成,该L1 block上被选择出来的 L2 main fork将自动被视为finalized 并且不可回滚。 这样以来后续所有针对该L2的长程攻击将无法产生威胁。
2 Likes
至此,我们会迎来一个新的问题。 如果, 此时我先使用VRF计算随机值,然后等待其他矿工广播他的goal,当我发现这些goal之后,我本地做计算,看看我需要为本区块支付多少L1 token才能比他的goal更高,从而抢得出块权。 如此, 几乎所有矿工都会偏好延迟广播自己的区块,要求先看到别人的goal再计算并广播自己的goal,后广播的矿工具备了天然优势。 这显然是不行的。
所以,我们需要将为本高度的区块支付L1 token的行为在时间上往前移——你必须事先指定你要为该区块支付多少L1 token,然后再计算VRF输出值。而事先支付L1 token的数量必须是commitment密文而不可以是明文,否则会有相似的情况。 如此就可以解决这个问题了。
注意这里说的支付L1 token,不是一开始在L1上预支一大笔L1 token, 而是在L1上声明你要为某个L2区块支付多少L1 token。
如此一来,L1 token的支付是预先完成的,你无法在出块的时候根据别人的goal来调整支付L1 token 的多少。而VRF的输出本身是固定的,在输入确定的情况下, 输出一定是确定性的,所以你无法通过调整VRF来改变goal。 这样竞选出块就会变得公平而随机。
那么,应该将这种为具体的块预支L1 token行为提前多久最安全呢? 我们需要在该L2 block之前4分钟左右预支(因为4分钟是24个CKB 区块出块的时间, 默认24个CKB区块便可获得足够的概率确定性)之所以这么做,是为了防止攻击者从L1发起自私挖矿。
自私挖矿
在pow中自私挖矿是一种常见的攻击方式,而proof of buy的内核更接近pow。 所以我们自私挖矿在proof of buy中是否能够构成威胁。
首先,恶意矿工很难在L2上直接自私挖矿,因为决定L2出块的只有两个因素, VRF output 和 L1 token支付数量,VRF output的值对于自己而言是确定的唯一的,想进行自私挖矿,只能在L1上实施。 比如在同一个区块高度上可能存在两个L1 block(设为 A 和 B), 攻击者可以在这两个不同的L1 block上同时预支付某个特定高度的L2 block的费用,此时如果没有经过足够的确认时间(24个CKB block) 那么对于大家而言,是无法确定A和B各自所在的fork 哪个会成为CKB上最终的main fork的。 那么对于L2而言就有小概率可能因为L1的最终性而影响L2 block的最终性。
所以我们将预支付L1 token的时间前移24个CKB block slot是最安全的做法。
2 Likes
来自项目方的女巫攻击
前面我们提到, proof of buy会让矿工们支付 L1 token到项目方的地址(以下简称mining addr)上,久而久之,为了防止项目方自己利用自己的 出块无成本的优势(因为矿工的token都是支付给他的)来自己亲自下场挖矿垄断出块权,我们设计了VRF这种伪随机的方式来让L2出块不会仅仅只受L1 token的支付数量的影响。
但有一个问题仍未解决,项目方可以利用自己的L1 token资金优势来进行女巫攻击:项目方自己可以分身为很多矿工来跟其他正常矿工抢夺出块权。即,假设现在有10个正常矿工要竞选L2的出块权,项目方决定亲自下场挖矿,虽然VRF能保证项目方的L1 token足够多也未必能挖到,但是它可以冒充出5000个矿工来一起参与挖矿,以此来无限稀释正常矿工能挖到矿的概率。
我们使用一种解法来防止这种攻击的可能,即把所有转入了mining addr的L1 token,都做一次转变,给这些L1 token(我们假设就是CKB这个币)的 type_script内增加一个逻辑: 该token永远不可以再回到该mining addr
如此项目方便不能够利用自身的优势挤压其他正常矿工了,但他们仍然可以用这些token去做别的事情(支付工资、资助生态) 并且由于该逻辑是写死进 type_script的,项目方自己无法使用混币器等手段通过抹除其交易历史的方式来绕过该限制。
唯一可能的方式是项目方将这些标记过的CKB和市面上其他正常的CKB进行交换。 但由于标记过的CKB有了用途的限制,所以普遍情况下在市场上它与正常CKB的汇率普遍会高于1:1,当汇率高于1:1的情况下,项目方便需要使用超量的被标记的CKB才能换回正常的CKB再进行女巫攻击,这是一件不可持续的事情,并且该L2越值钱,汇率就会越高,项目方的女巫攻击成本就越大。因此我们认为该种方式完全能够削弱项目方的女巫攻击。
1 Like