这两天在开发的时候遇到一个问题。对于一个支付通道cell,我们希望启动关闭程序的之后,通道双方都可以提交多次状态,进行状态更新。同时,这个提交期的时间需要是固定的(比如40个块)。在提交期之后,用户可以发起finalize操作。但是我们发现已有的since无法满足我们的要求。因为
- 绝对时间锁需要知道具体的块高,而我们不确定通道关闭会在未来的哪个块高发生。因此无法给出具体的截止日期。
- 另一个想法是通过相对时间锁来限制finalize操作,即在发生状态更新后需要度过多少个块才能进行finalize。但是这个相对时间锁只能依赖于live cell,在每一次状态提交之后都会重置,如果我们无法确定提交状态的次数,那么这个挑战期的时间长短也无法确定。
实际上我们的需求在以太坊上的实现逻辑很简单,只需要在合约内设定
deadline = block.number + DELTA
但是在CKB上,想要读取块高需要通过block_header,而block_header又需要等待4个epochs的成熟期,所以实现相同的逻辑需要等待额外的时间。
受益于CKB强大的脚本灵活性,我们可以实现和以太坊上相同的功能。具体而言,在开始通道关闭的时候在链上的cell会被分成两个。
- state cell
- clock cell
state cell用来让用户更新状态,他有两种解锁逻辑。
- 用户提交任何由双方签名的状态,即update操作。
- 用户在inputs里同时提供state cell和clock cell,即finalize操作。
而clock cell的解锁逻辑为
- 用户在inputs里同时提供state cell和clock cell,同时这个cell被一个相对时间锁since锁定(挑战期的长度)。
现在,可以启用finalize的时间就是clock cell可以被解锁的时间。在此之前,由于clock cell不可被解锁,双方都只能对state cell进行状态更新。受益于我们把时间锁从state cell中剥离了出来,这些更新并不会影响到finalize的时间。截止日期一到,用户就可以将两个cell都放入inputs中来进行finalize操作。