作者:Steven Roose
来源:https://roose.io/blog/hark-erk-evolving-the-ark-protocol-using-ctv-and-csfs/
(本文同时发布在 Delving Bitcoin 论坛中。)
上周在 OP_NEXT 论坛上,我提出了 Ark 协议的一种新变种,叫做 “Erk”,它消除了参与回合的用户的所有交互需要。在本文中,Erik De Smedt 和我希望明确 Erk 以及利用 CTV(OP_CHECKTEMPLATEVERIFY
)和 CSFS(OP_CHECKSIGFROMSTACK
)可以在 Ark 上作出的其它优化。
简单来说,我们得出了 Ark 的 两种 相互竞争的协议,它们具有如下特性:
- “Erk”:
- 参与回合的时候不需要用户交互
- 离线刷新(服务商可以为用户刷新)
- 永续离线刷新(服务商可以为一个用户不断刷新,没有期限)
- 在单输入、单输出的 VTXO 上效果最好
- 需要 CTV + CSFS
- “hArk”:
- 参与回合的时候不需要用户交互
- 非常高效,哪怕输入有多个
- 无法实现离线刷新(至少到目前为止)
- 只需要 CTV
Ark 简介
我们先要总结一下现有的基于 CTV 的 Ark 协议以及基于 MuSig 的 clArk 协议,然后是关于新的 Erk 和 hArk 变种的详细解释。
首先,我们来总结一下会在下文的解释中用到的核心概念。
我们将 Ark 服务商的公钥记为 $S$,而用户的公钥则记为 $A, B, …$
Ark 协议的基础砖块是交易树,它让多个用户能够共享一个链上的 UTXO 。下面的骨架图展示了一棵交易树,其中 Alice($A$)拥有 4 BTC、Bob($B$)拥有 3 BTC、Carol($C$)拥有 2 BTC,而 Dave($D$)拥有 1 BTC 。Ark 是一套离链的协议,所以,在乐观情形下,整个交易树只有注资交易(FUNDING)会得到区块链确认。
(每个方框都是一笔比特币交易)
+------------+
| FUNDING |
+------------+
| 10₿
+-----+------+
| NODE 1 |
+-----+------+
+---------┴--------------+
7₿ | | 3₿
+----+----+ +----+----+
| NODE 2 | | NODE 3 |
+----+----+ +----+----+
| |
+-----+-----+ +-----+-----+
4₿ | 3₿ | 2₿ | | 1₿
+---+----+ +---+----+ +---+----+ +---+----+
| EXIT A | | EXIT B | | EXIT C | | EXIT D |
+--------+ +--------+ +--------+ +--------+
在这套装置中,Alice 可以通过广播她所在的交易树分支,来执行单方面退出、领取她的资金。她的分支由这四笔交易组成:FUNDING、NODE 1、NODE 2 和 EXIT A 。在 Alice 知道这些交易(以及让它们变成有效交易所需的见证数据)并且可以用公钥 $A$ 来花费它们的时候,我们就说 Alice 拥有一个 VTXO 。
每一个 Ark VTXO 都有一个过期时间点,在这个过期时间点之前,这个 VTXO 必须要么被花掉、要么刷新(否则用户就会失去其中的价值)。而 “刷新一个 VTXO”,本质上意味着将一个 VTXO 换成一个新的(刷新时间延后了的)VTXO。刷新操作在 Ark 的 “回合” 中实现,也就是是 Ark 服务商和自己的用户的一个在线交互流程。
在过期之后,服务商就可以清扫整个交易树中的价值。在理想情况下,服务商可以直接清扫(花费)注资交易,但如果某个(某些)用户执行过单方面退出,服务商就只能清扫尚未有用户退出的所有剩余节点中的价值。
Arkoor
如果 Alice 持有一个 VTXO、想给 Bob 支付,她可以创建一笔新的链下交易(在类型上称为 “arkoor 交易”)、花费她自己的 VTXO(也即她的退出交易的输出)、为 Bob 创建一个新的 VTXO 。Bob 可以存储构成 Alice 的 VTXO 的所有交易,再加上 Alice 创建的这笔 arkoot 交易,构成他的新的 arkoor VTXO 。
(译者注:“Arkoor” 是 “Ark out-of-round” 的缩写,顾名思义,是在回合之外执行的。)
输出的花费条件
我们将用在 Ark 协议中的输出花费条件分为三种:
- 节点交易花费条件:用在所有节点交易(也包括注资交易)中的花费条件
- 叶子条件:用在最后一笔节点交易的输出中的花费条件,支付给一笔退出交易
- 退出条件:用在退出交易中的花费条件;退出交易是整个交易树的叶子,可被用户用来执行单方面退出
从逻辑上来说,你可以将这些三种花费条件视为前后相接的。下图指明了上图所示的不同交易所用到的输出花费条件。退出交易后面可以跟随 arkoor 交易或者弃权交易。
FUNDING
+-------------+-----+
| node policy | 10₿ |
+-------------+-----+
NODE 1
+-------------+-----+
| node policy | 7₿ |
+-------------+-----+
| node policy | 3₿ |
+-------------+-----+
NODE 2
+-------------+-----+
| leaf policy | 4₿ |
+-------------+-----+
| leaf policy | 3₿ |
+-------------+-----+
EXIT A
+-------------+-----+
| exit policy | 4₿ |
+-------------+-----+
所有的变种都具有以下共性:
每一个回合都会在一个 过期区块高度 $T_{exp}$ ,在这个区块之后,这个回合(所对应的交易树)中的资金就可以被 Ark 服务商密钥清扫。
在我们的构造中,所有的交易都是 0 手续费的,都有一个手续费锚点输出。在现实中,手续费可以是非零值,如果服务商倾向于给用户补贴一部分退出成本的话。带有交易费不是整个构造能够工作的必要条件,但带有手续费锚点输出则是。(译者注:这个锚点输出允许用户通过 “CPFP” 方法来追加手续费)。
节点花费条件 和 叶子花费条件 的功能都是延续交易树的分支,并带有一个替代性的花费路径,让服务商可以在过期之后清扫资金。
对用户来说,活性要求是指,他们要在自己的 VTXO 过期之前(也即 $T_{exp}$ 之前)的一段时间里回到互联网上,要么刷新自己的 VTXO ,要么执行单方面退出(如果服务商和自己的 arkoor VTXO 的任何一位前任所有权人行为不轨的话)。
一旦退出交易得到区块确认,过期机制就失效了,资金会进入 退出条件。退出条件有两个主要功能以及对应的 条款:
- 支付条款,给用户和服务商提供了一种合作式创建即时花费的方法(用于创建 arkoor 交易和弃权交易)
- 退出条款,用户提供了一种访问这些资金的方法,如果 TA 从未用这个 VTXO 创建过即时花费
退出条件 的最初设计在 退出条款 中使用了一个相对时间锁,但我们的更新设计结合了一个绝对时间锁 $T_{exp}$ 和一个相对时间锁 $\Delta t$ 。
- 这个相对时间锁保证了,支付条款 优先于 退出条款。
- 这个绝对时间锁保证了,这个 VTXO 的任何后续的所有权人(任何可能通过使用 支付条款 的 arkoor 交易收到这个 VTXO 的人),除了在 $T_{exp}$ 之前一段时间上线之外,没有别的活性要求
细说部分变种
Ark
最初版本的 Ark 协议基于 CTV 。我们对这个想法的最新迭代也一样。
节点花费条件 和 退出条件 都使用了 OP_CTV
来承诺下一笔交易。
- 节点条件 和 叶子条件:$CTV\ or\ (S + T_{exp})$
- 退出条件:$(A + S)\ or\ (A + T_{exp} + \Delta t)$
在回合中(刷新 VTXO 的时候),用户需要签名一笔 弃权交易,将自己的 VTXO交给服务商,并且,该弃权交易的生效条件是下一回合的正确开启。一个 连接器 是下一个回合的注资交易的一个专用后代交易,它会被用作 弃权交易 的一个输出,从而保证,服务商只有在下一回合(的注资交易)成功得到确认时,才能强制执行这个弃权交易。一旦所有用户都为自己的 VTXO 签名了弃权交易,服务商就可以签名注资交易、并广播到比特币网络中。
弃权交易有两个输入:
- 退出交易的输出,使用 退出花费条件 的 支付条款
- 连接器输入,来自新回合的注资交易的一连串后代交易的一个输出
弃权交易只有一个输出,就是将所有资金发送给服务商。
forfeit tx:
| inputs | outputs |
+===========+=========+
| exit tx | S |
+-----------+---------+
| connector | |
+-----------+---------+
clArk,“无需限制条款的 Ark”
clArk 与 Ark 非常相似,只是在交易树上使用了递归的多签名装置。每一个 节点条件 都包含了一个多签名装置,使用该节点下的所有叶子的公钥。
- 节点条件:$(A + B + C + … + S)\ or\ (S + T_{exp})$
- 叶子条件:$(A + S) or\ (S + T_{exp})$
- 退出条件:$(A + S)\ or\ (A + T_{exp} + \Delta t)$
回合机制是一样的,也使用了 连接器。唯一的区别在于,在所有客户端签名(自己所在的)交易树的分支时,需要一个额外的阶段。
Erk,“Erik 的 Ark”
我在 OP_NEXT 大会上演示 Erk 之后,我们又作了一些额外的升级。
Erk 的花费条件跟 Ark 中的一模一样,但我们让签名变成 可以重新绑定的(“可以重新绑定的签名” 是使用 APO 语义的签名,意思是他们不承诺具体的 UTXO 输入,所以可以用来花费任何包含相同公钥的输出)。我们可以使用 CTV + CSFS 来实现可以重新绑定的签名。
- 节点条件 和 叶子条件:$CTV\ or\ (S + T_{exp})$
- 退出条件:$(A + S)\ or\ (A + T_{exp} + \Delta t)$
退出条件 中的 $A + S$,就是我们要使用重绑定签名的地方。
Erk 的核心和基本原则体现在下列交易中,我们称为 退款交易。
refund tx:
| inputs | outputs |
+====================+================+
| old exit tx for A | exit policy A' |
+--------------------+----------------+
| new exit tx for A' | S |
+--------------------+----------------+
Erk 回合没有用户交互(我们把 “用户交互” 定义为 “所有用户同时采取行动”)。用户通过发送一个新的公钥($A’$)以及一个签过名的退款交易给服务商,来参与一个回合。注意,退款交易的一个输入是用当前的公钥 $A$ 来签名的,而另一个输入则是用新的公钥 $A’$ 来签名的。
这时候,服务商可以安全地创建一棵新的 VTXO 树、为用户发行相同的 VTXO(减去一些手续费)。这个新的 VTXO 有一个 退出条件,使用的新公钥 $A’$。
用户可以随时安全地签名这笔退款交易,因为他们依然能从交易的其中一个输出中收到自己的钱。所以如果这笔交易被服务商恶意使用,用户并不会丢失任何资金。
服务商也可以在收到这样的签过名的退款交易之后创建回合,因为,如果用户尝试(恶意地)退出原本的旧 VTXO,服务商可以揭晓这个新 VTXO,然后同时花费两者、拿走用户无权拥有的东西。
Arkoor
在 Erk 变种中实现 arkoor 交易需要格外小心。设想,如果用户 Alice 把自己的新 VTXO 发送给了 Bob(使用一笔 arkoor 交易),然后又恶意的尝试退出旧的 VTXO 。服务商将被迫广播新的 VTXO 并使用退款交易,这就把 Bob 的 arkoor VTXO 作废掉了。
然而,因为作为交易树的叶子的退出交易,跟退款交易拥有相同的输出花费条件(对公钥 $A’$ 来说),那么 Bob 可以要求 Alice 提供可以重新绑定的 arkoor 签名:这个签名在这两种输出上都可以使用。(注意,同一时间,只有其中一个才能存在,因为退款交易是退出交易的子交易。)
这一设计让 arkoor 交易在 Erk 上也可以实现,前提是每一个新的 VTXO 都来自一个 VTXO 输入。当我们尝试将这种设计推广到多个 VTXO 输入被合并为一个 VTXO 输出的情形中时,arkoor 构造就会无法工作。
离线刷新
现在,设想如果用户已经预先为自己的 VTXO 签名了一笔退款交易(就在这个 VTXO 刚刚创建好的时候)、把这个签名交给了服务商,然后就离线了。这意味着,这个服务商可以随时安全地重新发行这个 VTXO,只要持有这笔退款交易,就不怕用户同时领取这两个 VTXO 。这意味着,即使用户放弃了手动刷新,服务商也可以自动帮助 TA 。也可以让瞭望塔来监控这个 Ark,并在服务商没有帮助刷新用户的 VTXO 时通知这个用户。
(译者注:“瞭望塔” 指的是能够监控比特币区块链并代替客户对其中发生的事件作出响应的互联网服务。)
此外,设想第一次刷新将公钥 $A$ 变更为 $A’$,Alice 也可以预先为未来的 VTXO $A’$ 签名一笔退款交易,从而将公钥变更为 $A’’$。实际上,Alice 可以预先签名任意次数的刷新操作,每一次都将资金转入一个新的公钥(还可以每一次都减去一些数额,作为给服务商的服务费)。这样一来,一个服务商可以不断刷新一个 VTXO,用户不需要回到互联网上,除非一个瞭望塔提醒 TA 服务商并没有遵守约定。
也许一个恶意的服务商可以尝试迅速地应用所有这些退款交易,从而领走所有的服务费(请注意,这不一定是经济的,因为他需要为每一笔交易支付挖矿手续费)。可以通过在每一笔退款交易中放置绝对时间锁来避免这一点:服务商只能在根据预计的回合时间计算出来的未来时间点之后使用相应的退款交易。)
hArk,“哈希锁 Ark”
Erk 看起来非常强大(尽管我们放弃了 “aArk” 这个可能的代号),但依然有两个主要缺点:
- 服务商为了 “报复” 一个恶意退出操作,必须揭晓新 VTXO 所在的交易树分支。这在 “入场 VTXO” —— 用户自己在移动资金到一个 Ark 中时创建的 VTXO) —— 上问题尤其突出。入场 VTXO 只由一笔注资交易和一笔退出交易构成(该注资交易的输出使用 叶子花费条件)。这意味着用户尝试恶意退出的代价是很低的,而服务商要报复的代价则可能是很高的。
- Erk 只能支持单 VTXO 输入的刷新。
hArk 并不是 Erk 的变种,而是跟 Erk 完全不同的 Ark 变种。它的回合机制也不要求任何用户交互,它是链上踪迹最小化的,而且完美适配多 VTXO 输入的情形。
在 hArk 中,叶子花费条件 与 节点花费条件 不同,在于前者要求知道一个秘密值。
- 节点条件:$CTV\ or\ (S + T_{exp})$
- 叶子条件:概念上是 $(CTV + secret) or\ (S + T_{exp})$($secret$ 即所要求的秘密值),但另类的 $(A + S + secret tweak) or\ (S + T_{exp})$ 可以使用 Taproot 密钥路径花费,所以更加高效
- 退出条件:$(A + S)\ or\ (A + T_{exp} + \Delta t)$
在 hArk 的回合中,用户提交自己希望刷新的 VTXO 输出。服务商为树上的每一个新 VTXO 创建一个秘密值。因为一开始只有服务商才知道这个秘密值,所以 TA 可以安全地为回合(交易树)注资。一开始,没有任何一个新 VTXO 是能被用户访问的,因为所有的秘密值都还是保密的。
在回合注资交易得到区块确认之后,用户再签名一笔 弃权交易。这笔弃权交易将跟 Ark 和 clArk 中弃权交易不同,它让服务商可以通过揭晓秘密值来领取 VTXO 中的价值。
这笔弃权交易的输出花费条件是 $(S + secret)\ or\ (A + \Delta t)$ 。粗略地说,秘密值的检查可以通过使用简单的哈希锁来实现,但也可以在 Taproot 的密钥花费路径(Schnorr 签名)中使用 “适配器签名” 来实现,可以节约一些字节。
forfeit tx:
| inputs | outputs |
+=========+============+
| exit tx | S + secret |
| | or A + Δt |
+---------+------------+
在用户签名这笔弃权交易之后,服务商再告诉用户这个秘密值。这样一来,用户就能访问新的 VTXO 了。
如果用户签名这笔弃权交易之后,这个服务商拒绝交出相关的秘密值,那么用户将被迫尝试单方面退出,最终,这要么将钱交回给用户,要么服务商再链上揭晓这个秘密值。
结论
如果 CTV 可用,我们就能在 Ark 回合机制中完全消除所有用户交互。VTXO 刷新将变成一个完全异步的过程,用户可以自由登记,服务商可以独立地发行新的 VTXO,用户日后回到互联网上,就可以完成整个流程。
如果 CTV 之上还有 CSFS 可用,那么离线刷新甚至可以递归使用。这让服务商可以无需用户参与、自动刷新 VTXO,并且用户可以将监控正确动作的任务委托给第三方(瞭望塔)。
Erk 和 hArk 可以同时使用。用户可以总是预先签名 Erk 退款交易,以防自己不能及时上线,但依然使用 hArk 方法手动参与回合,比如需要合并多个 VTXO 为一个的时候,或是他们希望尽快刷新的时候。
我们想象,上述方案可以极大地强化 Ark 的用户体验、Ark 在移动端场景中的可用性,以及 Ark 服务商可以提供的功能性。
(完)