一种新的时间锁逻辑

这两天在开发的时候遇到一个问题。对于一个支付通道cell,我们希望启动关闭程序的之后,通道双方都可以提交多次状态,进行状态更新。同时,这个提交期的时间需要是固定的(比如40个块)。在提交期之后,用户可以发起finalize操作。但是我们发现已有的since无法满足我们的要求。因为

  1. 绝对时间锁需要知道具体的块高,而我们不确定通道关闭会在未来的哪个块高发生。因此无法给出具体的截止日期。
  2. 另一个想法是通过相对时间锁来限制finalize操作,即在发生状态更新后需要度过多少个块才能进行finalize。但是这个相对时间锁只能依赖于live cell,在每一次状态提交之后都会重置,如果我们无法确定提交状态的次数,那么这个挑战期的时间长短也无法确定。

实际上我们的需求在以太坊上的实现逻辑很简单,只需要在合约内设定

deadline = block.number + DELTA

但是在CKB上,想要读取块高需要通过block_header,而block_header又需要等待4个epochs的成熟期,所以实现相同的逻辑需要等待额外的时间。

受益于CKB强大的脚本灵活性,我们可以实现和以太坊上相同的功能。具体而言,在开始通道关闭的时候在链上的cell会被分成两个。

  1. state cell
  2. clock cell

state cell用来让用户更新状态,他有两种解锁逻辑。

  1. 用户提交任何由双方签名的状态,即update操作。
  2. 用户在inputs里同时提供state cell和clock cell,即finalize操作。

而clock cell的解锁逻辑为

  1. 用户在inputs里同时提供state cell和clock cell,同时这个cell被一个相对时间锁since锁定(挑战期的长度)。

现在,可以启用finalize的时间就是clock cell可以被解锁的时间。在此之前,由于clock cell不可被解锁,双方都只能对state cell进行状态更新。受益于我们把时间锁从state cell中剥离了出来,这些更新并不会影响到finalize的时间。截止日期一到,用户就可以将两个cell都放入inputs中来进行finalize操作。

8 Likes

state cell的script需要感知clock cell?
clock cell的script需要感知state cell?
死锁?
如果不相互锁定,那么是否存在伪造clock cell的情况?

不是很理解你这边的死锁的问题,可以描述地更清晰一些吗。我目前想的想法是state cell和clock cell的对应规则都会放在type script里。然后对应finalize解锁的时候需要inputs里存在和当前脚本code hash相同的另一个cell,同时会检查这个cell是不是配对的那个cell。这里就涉及到你说的第二个问题,是否可以伪造clock cell。

这个问题可以通过在script里规定:在挑战期开始的时候(即cell一分为二的时候),state cell和clock cell会把他们父cell的outpoint放入脚本的args中作为id标识,而id是判断两个cell是否匹配的条件之一。由于每一个cell的outpoint都是唯一的,你就无法从另一个cell中生成拥有同样id的clock cell,自然就无法通过伪造的clock cell来解锁对应的state cell了。

我明白你的意思了,你是用同一个script,实现两个业务逻辑:state和clock,从而可以避免循环依赖的问题。
我之前的疑问是不同的业务逻辑使用不同的script,所以就会有2个script,这就涉及到相互依赖的场景。