用TXHASH_CHECKSIGFROMSTACKVERIFY替换CTV和ANYPREVOUT
翻译:DeepL, Google Translate; 校对:李林
回顾CTV和ANYPREVOUT之间的关系:
众所周知,尽管CTV和ANYPREVOUT提案的主要应用(CTV的拥堵控制和ANYPREVOUT的eltoo闪电通道)非常不同,但它们的应用有很大程度的重叠。特别是,ANYPREVOUT可以实现CTV的大部分应用,尽管成本更高。CTV的主要功能是允许scriptPubKey对其支出交易的哈希做出承诺,而输入的TXID不在哈希中。这种排除是必要的,因为scriptPubKey被散列到输入的TXID中,包括TXID会导致散列承诺的循环,这是不可能构建的。另一方面,ANYPREVOUT定义了一种签名哈希模式,它同样排除了输入的TXID,以达到其可重新绑定签名的目的。
这意味着ANYPREVOUT可以通过在scriptPubKey里面提交公钥以及ANYPREVOUT签名来模仿CTV的大部分特性。事实上,比特币今天没有契约的唯一原因是由于scriptPubKeys和TXIDs之间的这种循环,这种循环发生在所有sighash模式中。
通过ANYPREVOUT模拟CTV与实际的 CTV提案的主要区别是(1): 模拟CTV的成本。 在CTV中,支出 事务是用32字节的哈希值来提交的,而用ANYPREVOUT来模拟则需要64字节的哈希值。 ANYPREVOUT要求签名有64个字节,有些公钥要32个字节的,有些标志位需要多一些字节,就可以模拟CTV。 通过使用内部公钥(1字节表示)可以减少一些成本,而且,如果我们有CAT,也许可以通过可重用的片段来组装签名(即把签名的nonce设置为等于公钥)。
另一个主要区别是。(2) CTV的交易哈希值包括如交易中的输入数量和它们的序列号。ANYPREVOUT并不包括这些。 CTV的哈希值包含足够的信息,因此当与缺失的TXID结合时,你可以计算出支出交易的TXID。花费交易的TXID。 特别是如果输入的数量被承诺为承诺为1,一旦scriptpubkey的交易ID被知道并提交到到区块链上,其支出交易的TXID是可以推导出来的。 而且如果该交易的输出有CTV承诺,你可以反过来推断它们的支出TXID。 虽然这是一个很好的功能。ANYPREVOUT不能模仿的东西,它的主要应用是它的主要应用被列为使用拥堵控制来资助闪电通道,在它们的TXIDs在它们被放置在链上之前。 然而,如果ANYPREVOUT被用来模仿CTV,那么很可能是eltoo通道会被资助,而且没有必要事先知道eltoo通道的TXIDs来使用它们。为了使用它们,没有必要事先知道eltoo频道的TXID。
另一个提议:
鉴于CTV和ANYPREVOUT之间的功能重叠,我认为将它们的操作分解成各自的组成部分并以编程方式重新组合它们的行为是有意义的。为了这个目的,我提出OP_TXHASH和OP_CHECKSIGFROMSTACKVERIFY。
OP_TXHASH将从堆栈中弹出一个txhash标志,并根据该标志计算出一个(有标签的)txhash,并将得到的hash推到堆栈中。OP_CHECKSIGFROMSTACKVERIFY将从堆栈中弹出一个pubkey、消息和签名,如果签名没有在该消息上验证,则失败。
CTV和TXHASH的功能大致相当。 CTV DROP “可以通过”<ctv_style_flag> TXHASH EQUALVERIFY “来模拟。 反过来也是如此,'<ctv_style_flag> TXHASH’可以通过以下方式被CTV模拟 CTV',然而,正如你所看到的,从CTV模拟TXHASH要比其他方式昂贵得多,因为产生的32字节哈希结果必须作为见证栈的一部分。
CHECKSIGVERIFY可以通过'<apo_style_flag> TXHASH CHECKSIGFROMSTACKVERIFY’来模拟。 这里我们看到了 将哈希值推到堆栈中。 APO可以被模拟,而不需要在见证数据中包括一份所产生的TXHASH的副本。
除了CTV和ANYPREVOUT应用外,用CHECKSIGFROMSTACKVERIFY,我们可以验证由预言机应用的预言机签名的任意消息的签名。 这就是我们看到将操作分解成原始片段的好处。 通过让用户能够从组件中编程自己的用例,我们可以用更少的操作代码获得更多的应用 一个备选建议:。
注意事项::
首先,我承认复制CTV和ANYPREVOUT的行为确实比使用定制的目的性建议本身多花了几个字节。 这是我们选择从碎片中编程解决方案的能力时要付出的代价。 但是,我们可以从这些碎片中获得能够建立更多应用的好处。
与CTV不同的是,TXHASH不是NOP兼容的,只能在tapscript中实现。 特别是,在这个建议中,裸露的CTV是不可能的。然而,这个建议并不排除将CTV添加到传统脚本中,同时将TXHASH添加到tapscript中的可能性。
由于类似的原因,TXHASH不适合在以后扩展txflags的集合。 理论上,当遇到未知的标志集时,我们可以让TXHASH中止-成功。 然而,这将使分析tapscript更加困难。这样一来,tapscripts就可以根据脚本片段的组装和执行顺序,以成功或失败的方式中止,而顺序不正确将是灾难性的。 这种行为与目前的一批OP_SUCCESS操作码明显不同,无论它们是否会被执行,只要存在就会成功中止。
我相信升级TXHASH的困难可以通过从一开始就设计一套强大的TXHASH标志来缓解。 例如,有一些位来控制:(1)版本是否被覆盖;(2)锁定时间是否被覆盖;(3)txids是否被覆盖;(4)序列号是否被覆盖;(5)输入量是否被覆盖;(6)输入scriptpubkeys是否被覆盖;(7)输入的数量是否被覆盖;(8)输出量是否被覆盖;(9)输出scriptpubkeys是否被覆盖;(10)输出的数量是否被覆盖。(11) tapbranch被覆盖;(12) tapleaf被覆盖;(13) opseparator值被覆盖;(14) 是否覆盖所有、一个或没有输入;(15) 是否覆盖所有、一个或没有输出;(16) 是否覆盖一个输入位置;(17) 是否覆盖一个输出位置;(18) 是否覆盖sighash标志(注意。注意:是否覆盖了sighash标志,其本身必须被覆盖)。 可能会指定在单一情况下覆盖哪个输入或输出位置,以及该位置是相对于输入的位置还是绝对位置。
综上所述,即使将来需要其他TXHASH标志模式,增加TXHASH2始终是一个选择。
与未来潜在操作码的互动::
我们应该考虑这些操作码如何与未来的操作码(如CAT、滚动SHA256操作码)互动,或者如何与其他公约操作码对接,这些操作码可能会做一些事情,比如为计算目的直接将输入或输出量推入堆栈,这些操作码已经被添加到Elements项目中。
通过CAT和/或滚动SHA256操作码和/或现有的SHA256操作码,CHECKSIGFROMSTACKVERIFY可以验证以编程方式组装的信息的签名。 另外,结合对TXHASH的多次调用,可以用来创建对交易数据的复杂子集进行承诺的签名。
如果增加了新的操作码,将交易数据的部分方向推到堆栈中,例如OP_INSPECTOUTPUTVALUE,也许人们会担心它们会淘汰TXHASH,因为在滚动SHA256操作码的存在下,TXHASH可以被模拟。 然而,考虑到TXHASH可以紧凑地创建大量交易数据的哈希值,TXHASH似乎不太可能会被废弃。 另外,TXHASH和交易反省操作码的组合可以用来建立 “*潜伏契约”。
构建契约的通常方式,我们将称之为 “加法契约”,就是将你希望固定的交易数据的所有部分推到堆栈中,将其全部散列在一起,并验证产生的散列与固定值相匹配。 另一种建立契约的方法,我们称之为 “减法契约",是将交易数据的所有部分推到堆栈中,你希望保持自由。 然后使用滚动SHA256操作码,从一个固定的中间状态开始,提交到交易哈希数据的前缀。自由的部分被散列到该中间状态。 最后,对产生的哈希值进行验证,以匹配TXHASH返回的值。 能否很好地建立减法契约,取决于TXHASH哈希值的构造细节,我听说CTV已经考虑了这个问题。