作者:Jeremy Rubin

来源:https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2021-March/018615.html

我发现有些人(nullc、sipa、我,还有吗?)已经意识到了如何在当前的比特币上实现脚本委托(无需共识规则作任何修改),但也在跟 Andrew P 聊天时知道了这项技术还不是那么广为人知。所以我认为,出于存档的目的,介绍一下它的工作原理是有意义的。如有其它引用,欢迎在下面回复。

如果你更喜欢图像,请看这个:https://docs.google.com/presentation/d/1ikcthy3p-Ah59pJyss0TLEj-Q2FF6tv7BXhkORzErAE/edit#slide=id.p

技术上来讲,我们是将一个 UTXO 委托给另一个具体的 UXTO,而不是委托给某一个脚本。

假设你有 UXTO A。你想要把它委托给脚本 S。要么,你可以扫描区块链,找出绑定在 S 上的 UTXO,或使用任意的 UTXO B 来创建一笔交易 X,产生一个使用脚本 S 的输出 D(这个输出不必具有面额,但我们假设它有一定的面额从而不会产生粉尘问题)。因为交易 X 是不能变形的,在我们实际用上委托之前,都不必广播它和花费 B;而且,它可以创建出来(因为有 TXID),不需要 B 的所有者在线。因此你现在获得了一个使用 S 的 UTXO,无论它在链上存不存在,我们管它叫 D。

注:如果你准备多次使用这个代理脚本,你可以稍微优化一下这个创建步骤。

现在,使用 A,你签名一条带有 2 个输入(另一个输入是 D)的交易,签名哈希模式为 SIGHASH_NONE。这样,你会签名所有的输入(但不包括它们的 sequence),而不会签名任何输出。我们管这笔交易叫存根 G。

现在,你使用 S 和 SIGHASH_ALL,签名交易 G 的输入 D 以及你想创建的任何输出。这笔交易我们叫终局交易 F。

本质上,A 的持有者就是将自己的币的控制权委托给了脚本 S 的一个实例。委托之后,S 可以授权几乎任何交易(若想签名多个输入,则会复杂一些;但也有很好的替代品)。

高级议题:

撤回机制:有许多方法可以撤回委托,花费 A、花费 D、拒绝签名和创建 D(D 是由 B 创建出来的),都可以。因为这些都是跟具体的 UXTO 绑定的,这样终局交易就无法发生了(上面超链接里的图示可以帮助理解)。

跨输入的委托:一组 UXTO N可以创建一笔 SIGHASH_NONE 交易,加上代理脚本的一个输出,从而形成多个 UTXO 委托给一个 UTXO 的情形。

部分花费授权:将 SIGHASH_NONE 替换为 SIGHASH_SINGLE 就可以指定一个找零地址,从而形成委托花费的限额(插句话 —— OP_CTV 限制条款也可以被理解为扩展 SIGHASH_SINGLE,从而允许它指定一组输出)。

延后委托:因为 SIGHASH_NONE 签名了交易的 lock_time(绝对时间锁)字段,所以委托可以设置成在一段时间后才能生效。

多个代理:通过签名一个带有多个代理输出的交易,就可以执行多个独立的委托条件。通常来说这是没必要的 —— 为什么不直接把 S1 和 S2(脚本)串联起来?答案是你的 S1 需要相对高度锁,而 S2 需要相对时间锁(这是为 powswap.com 研究的机制之一)。

序列式的带条件委托:通过构造一个可能会委托资金的 TXID,你可以将委托的触发条件设置成另一个合约达成某个具体的状态。举个例子,假设我有一个合约,其可能的结束状态有 100 个,所有的状态最终都会有一个确定的输出点(译者注:outpoint,UTXO 的标记)。我可以把币委托给不同的代理安排,仅当合约到达某个状态时,这些币才能被代理申领。注意,这样的模式需要主合约与观察合约在一定程度上的合约,因为币的委托只能被申领一次。

CTV 专属的 P2SH 非币委托:OP_CTV 允许形成类似形式的委托,它将使用一个隔离见证的 P2SH 地址,作为 CTV 承诺地址的一部分,而无需将它绑定到任何具体的 UTXO。再加上 OP_CAT,就既能够按程序改变输出(而不是只能许可固定的交易),又能动态地选择代理脚本。

再委托:也就是 A 委托给 S,S 又委托给 S’。这种机制很又可能需要将资金在链上转移给某个脚本(A 或者 S 或者 S’),但链上的操作可以推迟(通过预先签名交易),直到 S’ 真的要对资金做什么操作。

显然,泛泛而言,你可以用委托来做许多其它事情,上文说得仅仅是币的委托要如何实现。也许我错过了一些有趣的东西,请在评论中告诉我。

(完)