何时反转?盘点山寨币们即将面临的 10
63 2024-09-03
作者:Chakra;编译:0xjs@金色财经
本文为Chakra发表的比特币扩展性系列文章的Part III。
第一部分参阅金色财经此前文章“比特币原生扩容方案回顾:SegWit和Taproot”,
第二部分参阅金色财经此前文章“比特币可扩展性:Layer2方案和相关项目解析”。
第三部分为本文,如下:
相比以太坊等图灵完备的区块链,比特币脚本被认为限制性极强,仅能进行基本运算,甚至不支持乘法和除法。更重要的是,区块链自身的数据几乎无法被脚本访问,导致灵活性和可编程性严重不足。因此,人们一直在努力让比特币脚本实现内省(introspection)。
内省是指比特币脚本检查和约束交易数据的能力。这允许脚本根据特定的交易细节控制资金的使用,从而实现更复杂的功能。目前,大多数比特币操作码要么将用户提供的数据推送到堆栈上,要么操纵堆栈上的现有数据。然而,内省操作码可以将当前交易的数据(例如时间戳、金额、txid 等)推送到堆栈上,从而可以更精细地控制 UTXO 支出。
截至目前,比特币脚本中只有三个主要操作码支持内省:CHECKLOCKTIMEVERIFY、CHECKSEQUENCEVERIFY 和 CHECKSIG,以及其变体 CHECKSIGVERIFY、CHECKSIGADD、CHECKMULTISIG 和 CHECKMULTISIGVERIFY。
契约(Covenant,也可译作“限制条款”),简单地说,是指对货币转移方式的限制,允许用户指定 UTXO 的分配方式。许多契约都是通过内省操作码实现的,关于内省的讨论现在已经被归类到比特币 Optech契约主题下。
比特币目前有两个契约,CSV(CheckSequenceVerify)和 CLTV(CheckLockTimeVerify),这两个契约都是基于时间的契约,是许多扩容解决方案(如闪电网络)的基础。这说明了比特币的扩容解决方案严重依赖于内省和契约。
我们如何为代币的转移添加条件?在加密货币领域,我们最常用的方法是通过承诺,通常通过哈希来实现。为了证明转移要求得到满足,还需要签名机制进行验证。因此,契约中存在许多对哈希和签名的调整。
下面,我们将描述被广泛讨论的Covenant操作码提案。
CTV(CheckTemplateVerify)是BIP-119中的一个比特币升级提案,引起了社区的广泛关注。CTV允许输出脚本指定交易中资金支出的模板,包括nVersion、nLockTime、scriptSig哈希、输入计数、序列哈希、输出计数、输出哈希、输入索引等字段。这些模板限制是通过哈希承诺实现的,当资金被花费时,脚本会检查支出交易中指定字段的哈希值是否与输入脚本中的哈希值匹配。这有效地限制了该UTXO未来交易的时间、方法和数量。
值得注意的是,输入的 TXID 被排除在此哈希之外。这种排除是必要的,因为在传统和隔离见证交易中,当使用默认的 SIGHASH_ALL 签名类型时,TXID 取决于 scriptPubKey 中的值。包括 TXID 会导致哈希承诺中的循环依赖,从而无法构建。
CTV 的内省方式是直接拉取指定的交易信息进行哈希运算,然后与堆栈上的承诺进行比较。这种内省方式对链空间要求较低,但缺乏一定的灵活性。
比特币二层解决方案(如闪电网络)的基础是预签名交易。预签名通常是指提前生成和签署交易,但在满足某些条件之前不广播它们。本质上,CTV 实现了一种更严格的预签名形式,将预签名的承诺发布在链上,并限制在预定义的模板内。
CTV 最初是为了缓解比特币的拥堵而提出的,这也可以称为拥堵控制。在拥堵严重时,CTV 可以在单笔交易中承诺多笔未来交易,避免在高峰时段广播多笔交易,并在拥堵缓解后完成实际交易。这在交易所挤兑期间可能特别有用。此外,该模板还可用于实施 Vault 以防止黑客攻击。由于资金流向是预先确定的,黑客无法使用 CTV 脚本将 UTXO 指向自己的地址。
CTV 可以显著增强二层网络。例如,在闪电网络中,CTV 可以通过将单个 UTXO 扩展为 CTV 树来创建超时树和通道工厂,只需一笔交易和一次确认即可打开多个状态通道。此外,CTV 还通过 ATLC 支持 Ark 协议中的原子交易。
BIP-118 为 tapscript 引入了一种新型签名哈希标志,旨在促进更灵活的支出逻辑,称为 SIGHASH_ANYPREVOUT。APO 和 CTV 有很多相似之处。在解决 scriptPubKeys 和 TXID 之间的循环问题时,APO 的方法是排除相关输入信息并仅对输出进行签名,从而允许交易动态绑定到不同的 UTXO。
从逻辑上讲,签名验证操作OP_CHECKSIG(及其变体)执行三个功能:
1、组装支出交易的各个部分。
2、对它们进行哈希处理。
3、验证哈希是否已由给定的密钥签名。
签名的具体细节具有很大的灵活性,由SIGHASH标志决定对交易的哪些字段进行签名。根据BIP 342中签名操作码的定义,SIGHASH标志分为SIGHASH_ALL,SIGHASH_NONE,SIGHASH_SINGLE和SIGHASH_ANYONECANPAY。SIGHASH_ANYONECANPAY控制输入,而其他控制输出。
SIGHASH_ALL 是默认的 SIGHASH 标志,对所有输出进行签名;SIGHASH_NONE 不签名任何输出;SIGHASH_SINGLE 签名特定输出。SIGHASH_ANYONECANPAY 可以与前三个 SIGHASH 标志一起设置。如果设置了 SIGHASH_ANYONECANPAY,则只对指定的输入进行签名;否则,必须对所有输入进行签名。
显然,这些 SIGHASH 标志并不能消除输入的影响,即使是 SIGHASH_ANYONECANPAY,它也需要承诺一个输入。
因此,BIP 118 提出了 SIGHASH_ANYPREVOUT。APO 签名不需要承诺已花费的输入 UTXO(称为 PREVOUT),而只需签署输出,从而为比特币控制提供更大的灵活性。通过预先构建交易并创建相应的一次性签名和公钥,发送到该公钥地址的资产必须通过预先构建的交易来使用,从而实现契约。APO 的灵活性还可用于交易修复;如果交易因费用过低而卡在链上,则可以轻松创建另一笔交易来增加费用,而无需新的签名。此外,对于多重签名钱包来说,不依赖于已花费的输入会使操作更加方便。
由于消除了 scriptPubKeys 和输入 TXID 之间的循环,APO 可以通过在 Witness 中添加输出数据来执行内省,尽管这仍然需要额外的 Witness 空间消耗。
对于闪电网络和金库(Vaults)等链下协议,APO 减少了保存中间状态的需要,大大降低了存储要求和复杂性。APO 最直接的用例是 Eltoo,它简化了通道工厂,构建了轻量级且廉价的瞭望塔,并允许单边退出而不留下错误状态,从而在许多方面增强了闪电网络的性能。APO 还可用于模拟 CTV 功能,尽管它要求个人存储签名和预签名交易,这比 CTV 更昂贵且效率更低。
APO 的主要批评集中在它需要一个新的密钥版本,而这不能通过简单的向后兼容来实现。此外,新的签名哈希类型可能会带来双重支付的潜在风险。经过广泛的社区讨论,APO 在原有的签名机制之上增加了常规签名以缓解安全担忧,从而获得了 BIP-118 代码。
BIP-345 提议增加两个新的操作码,OP_VAULT 和 OP_VAULT_RECOVER,它们与 CTV 结合使用时,可实现专门的契约,允许用户强制延迟使用特定货币。在此延迟期间,可以通过恢复路径“撤销”之前进行的交易。
用户可以通过创建特定的 Taproot 地址来创建 Vault,该地址必须在其 MAST 中包含至少两个脚本:一个带有 OP_VAULT 操作码以促进预期的提款过程,另一个带有 OP_VAULT_RECOVER 操作码以确保在提款完成之前可以随时恢复代币。
OP_VAULT 如何实现可中断的定时锁定提款?OP_VAULT 通过用指定脚本替换已使用的 OP_VAULT 脚本来实现这一点,从而有效地更新 MAST 的单个叶子,同时保持其余 Taproot 叶子节点不变。此设计类似于 TLUV,只是 OP_VAULT 不支持对内部密钥的更新。
通过在脚本更新过程中引入模板,可以限制付款。时间锁参数由OP_VAULT指定,CTV操作码的模板限制了可以通过此脚本路径使用的输出集。
BIP-345 专为Vaults设计,利用 OP_VAULT 和 OP_VAULT_RECOVER 为用户提供安全的托管方法,使用高度安全的密钥(例如纸钱包或分布式多重签名)作为恢复路径,同时为定期付款配置一定的延迟。用户的设备会持续监控保险库的支出,如果发生意外转账,用户可以启动恢复。
通过 BIP-345 实现 Vault 需要考虑成本问题,尤其是对于恢复交易。可能的解决方案包括 CPFP(子节点为父节点付费)、临时锚点和新的 SIGHASH_GROUP 签名哈希标志。
TLUV 方案围绕 Taproot 构建,旨在有效解决共享 UTXO 退出问题。指导原则是,当 Taproot 输出被使用时,可以通过加密转换和 Taproot 地址的内部结构对内部密钥和 MAST(tapscript trie)进行部分更新,如 TLUV 脚本所述。这使得 Covenant 功能的实现成为可能。
TLUV 方案的概念是通过引入新的操作码 TAPLEAF_UPDATE_VERIFY 根据当前支出输入创建一个新的 Taproot 地址。这可以通过执行以下一项或多项操作来实现:
更新内部公钥
修剪 Merkle 路径
删除当前正在执行的脚本
在 Merkle 路径末尾添加新步骤
具体来说,TLUV 接受三种输入:
指定如何更新内部公钥。
为 Merkle 路径指定新步骤的一种方法。
指定是否删除当前脚本和/或要修剪 Merkle 路径的多少步。
TLUV操作码计算更新的scriptPubKey,并验证当前输入对应的输出是否花在这个scriptPubKey上。
TLUV 的灵感来源于 CoinPool 的概念。如今,联合资金池仅需预先签名的交易即可创建,但如果要实现无需许可的退出,则需要创建数量成倍增长的签名。而 TLUV 则允许无需许可的退出,无需任何预先签名。例如,一组合作伙伴可以使用 Taproot 构建共享的 UTXO,将他们的资金汇集在一起 。他们可以使用 Taproot 密钥在内部转移资金,也可以联合签名以在外部发起付款。个人可以随时退出共享资金池,删除他们的付款路径,而其他人仍可以通过原始路径完成付款,并且个人的退出不会暴露有关内部其他人的其他信息。与非池化交易相比,这种模式更高效、更私密。
TLUV 操作码通过更新原始 Taproot Trie 实现了部分支出限制,但它没有实现对输出金额的自省。因此,还需要一个新的操作码 IN_OUT_AMOUNT。此操作码将两个项目推送到堆栈上:此输入的 UTXO 金额和相应输出的金额,然后使用 TLUV 的人需要使用数学运算符来验证资金是否适当地保留在更新的 scriptPubKey 中。
输出金额的内省增加了复杂性,因为以 satoshis 为单位的金额需要最多 51 位来表示,但脚本仅允许进行 32 位数学运算。这需要重新定义操作码行为以升级脚本中的运算符或使用 SIGHASH_GROUP 替换 IN_OUT_AMOUNT。
TLUV 有潜力成为去中心化第 2 层资金池的解决方案,但其调整 Taproot Trie 的可靠性仍需确认。
MATT(Merkleize All The Things)旨在实现三个目标:Merkleizing the state、Merkleizing the script、Merkleizing the performing,从而实现通用智能合约。
对状态进行 Merkle 化(Merkleizing the state):这涉及构建 Merkle Trie,其中每个叶节点代表一个状态的哈希值,而 Merkle Root 则体现合约的整体状态。
对脚本进行 Merkle 化(Merkleizing the script):这指的是使用 Tapscript 形成 MAST,其中每个叶节点代表一种可能的状态转换路径。
Merkle 化执行(Merkleizing the performing):通过加密承诺和欺诈挑战机制对执行进行 Merkle 化。对于任何计算函数,参与者可以在链下计算,然后发布承诺 f(x)=y。如果其他参与者发现错误结果 f(x)=z,他们可以发起挑战。仲裁通过二分搜索进行,类似于 Optimistic Rollup 的原理。
默克尔化执行
为了实现 MATT,比特币脚本语言需要具备以下功能:
强制输出具有特定脚本(及其数量)
将一段数据附加到输出
从当前输入(或另一个输入)读取数据
第二点至关重要:动态数据意味着可以通过消费者提供的输入数据来计算状态,因为这允许模拟状态机,能够确定下一个状态和附加数据。MATT 方案通过 OP_CHECKCONTRACTVERIFY (OP_CCV) 操作码实现这一点,该操作码是之前提出的 OP_CHECKOUTPUTCONTRACTVERIFY 和 OP_CHECKINPUTCONTRACTVERIFY 操作码的合并,使用附加标志参数来指定操作的目标。
控制输出金额:最直接的方法是直接内省;但是,输出金额是 64 位数字,需要 64 位算术,这在比特币脚本中带来了很大的复杂性。OP_CCV 采用延迟检查方法,如 OP_VAULT,其中 CCV 中相同输出的所有输入的输入金额相加,作为该输出金额的下限。延迟是因为此检查发生在交易过程中,而不是在脚本评估输入期间。
鉴于欺诈证明的普遍性,MATT 合约的某些变体应该能够实现所有类型的智能合约或 2 层构造,尽管需要准确评估额外要求(例如资金锁定和挑战期延迟);需要进一步研究以评估哪些应用程序可以接受交易。例如,使用加密承诺和欺诈挑战机制来模拟 OP_ZK_VERIFY 函数,在比特币上实现无需信任的 Rollups。
实践上,事情已经发生了。Johan Torås Halseth 利用 MATT 软分叉提案中的 OP_CHECKCONTRACTVERIFY 操作码实现了elftrace,这使得任何支持 RISC-V 编译的程序都可以在比特币区块链上进行验证,从而使合约协议中的一方能够通过合约验证来访问资金,从而桥接比特币原生验证。
从APO操作码的介绍中我们了解到OP_CHECKSIG(及其相关操作)负责组装交易、哈希计算和验证签名。但是这些操作验证的消息是通过操作码序列化交易而来的,不允许指定任何其他消息。简单来说,OP_CHECKSIG(及其相关操作)的作用是通过签名机制来验证作为交易输入被花费的UTXO是否被签名持有者授权使用,从而保护比特币的安全。
CSFS,顾名思义,就是从堆栈中检查签名(Checks theSignatureFromStack)。CSFS操作码从堆栈中接收三个参数:签名、消息和公钥,并验证签名的有效性。这意味着人们可以通过见证人将任何消息传递到堆栈,并通过 CSFS 进行验证,从而实现比特币的一些创新。
CSFS 的灵活性使其能够实现诸如支付签名、授权委托、预言机合约、双重支付保护保证以及更重要的交易自省等机制。使用 CSFS 进行交易内省的原理非常简单:如果 OP_CHECKSIG 使用的交易内容通过见证者推送到堆栈,并且使用相同的公钥和签名对 OP_CSFS 和 OP_CHECKSIG 进行验证,并且如果两次验证都成功通过,则传递给 OP_CSFS 的任意消息内容与 OP_CHECKSIG 隐式使用的序列化支出交易(和其他数据)相同。然后我们在堆栈上获得经过验证的交易数据,这些数据可用于对使用其他操作码的支出交易施加限制。
CSFS 经常与 OP_CAT 一起出现,因为 OP_CAT 可以连接交易的不同字段以完成序列化,从而可以更精确地选择自省所需的交易字段。如果没有 OP_CAT,脚本就无法从可以单独检查的数据中重新计算哈希值,因此它真正能做的是检查哈希值是否对应于特定值,这意味着只能通过单个特定交易来使用代币。
CSFS 可以实现 CLTV、CSV、CTV、APO 等操作码,使其成为多功能内省操作码。因此,它也有助于比特币 2 层的可扩展性解决方案。缺点是它需要在堆栈上添加已签名交易的完整副本,这可能会显著增加使用 CSFS 自省的交易的大小。相比之下,像 CLTV 和 CSV 这样的单一用途内省操作码的开销很小,但添加每个新的特殊内省操作码都需要进行共识更改。
OP_TXHASH 是一个简单的内省操作码,允许operator选择特定字段的哈希并将其推送到堆栈上。具体来说,OP_TXHASH 从堆栈中弹出一个 txhash 标志,并根据该标志计算(带标签的)txhash,然后将生成的哈希推送回堆栈。
由于TXHASH与CTV的相似性,社区内对两者产生了大量讨论。
TXHASH 可以看作是 CTV 的通用升级,它提供了更高级的交易模板,允许用户明确指定支出交易的各个部分,解决了许多与交易费用相关的问题。与其他 Covenant 操作码不同,TXHASH 不需要见证中必要数据的副本,从而进一步降低了存储要求;与 CTV 不同,TXHASH 不兼容 NOP,只能在 tapscript 中实现;TXHASH 和 CSFS 的组合可以作为 CTV 和 APO 的替代方案。
从构建契约的角度来看,TXHASH 更有利于创建“加法契约”,其中你希望修复的所有交易数据部分都被推送到堆栈上,一起进行哈希处理,并验证生成的哈希是否与固定值匹配;CTV 更适合创建“减法契约”,其中你希望保持自由的所有交易数据部分都被推送到堆栈上。然后,使用滚动 SHA256 操作码,哈希处理从固定的中间状态开始,该状态提交到交易哈希数据的前缀。自由部分被哈希到这个中间状态。
TXHASH规范中定义的TxFieldSelector字段预计会扩展到其他操作码,比如OP_TX。
与TXHASH相关的BIP目前在GitHub上处于Draft状态,尚未分配编号。
OP_CAT 是一个神秘的操作码,最初被中本聪出于安全考虑而放弃,但最近却引发了比特币核心开发者的激烈讨论,甚至在网络上掀起了 Meme 文化。最终,OP_CAT 在 BIP-347 下获得批准,被称为近期最有可能通过的 BIP 提案。
事实上,OP_CAT 的行为非常简单:它将两个来自堆栈的元素连接起来。它如何实现 Covenant 功能?
事实上,连接两个元素的能力对应着一个强大的加密数据结构:Merkle Trie。要构建 Merkle Trie,只需要连接和哈希运算,而比特币脚本中提供了哈希函数。因此,使用 OP_CAT,我们理论上可以在比特币脚本中验证 Merkle 证明,这是区块链技术中最常见的轻量级验证方法之一。
前面提到,CSFS 借助 OP_CAT 可以实现通用的 Covenant 方案。实际上,即使没有 CSFS,利用 Schnorr 签名的结构,OP_CAT 本身也可以实现交易内省。
在Schnorr签名中,需要签名的消息由以下字段组成:
这些字段包含交易的主要元素。通过将它们放在 scriptPubKey 或 Witness 中,并使用 OP_CAT 结合 OP_SHA256,我们可以构造 Schnorr 签名并使用 OP_CHECKSIG 进行验证。如果验证通过,堆栈将保留已验证的交易数据,从而实现交易自省。这使我们能够提取和“检查”交易的各个部分,例如其输入、输出、目标地址或所涉及的比特币金额。
关于具体的密码学原理,可以参考Andrew Poelstra的文章《CAT and Schnorr Tricks》。
总而言之,OP_CAT 的多功能性使其能够模拟几乎任何 Covenant 操作码。许多 Covenant 操作码都依赖于 OP_CAT 的功能,这大大提升了其在合并列表中的位置。从理论上讲,仅依靠 OP_CAT 和现有的比特币操作码,我们就有希望构建一个信任最小化的 BTC ZK Rollup。Starknet、Chakra 和其他生态系统合作伙伴正在积极推动这一目标的实现。
当我们探索扩展比特币和增强其可编程性的各种策略时,很明显,前进的道路涉及原生改进、链下计算和复杂脚本功能的融合。
如果没有灵活的基础层,就不可能构建更灵活的二层。
链下计算扩展是未来的趋势,但比特币的可编程性需要突破,才能更好地支持这种扩展性并成为真正的全球货币。
然而,比特币上的计算性质与以太坊上的计算性质有着根本区别。比特币只支持“验证”作为一种计算形式,无法执行一般计算,而以太坊本质上是计算性的,验证是计算的副产品。从一点可以看出这种区别:以太坊对无法执行的交易收取 Gas Fee,而比特币则不收取。
契约是一种基于验证而非计算的智能合约形式。除了少数中本聪原教旨主义者外,似乎所有人都认为契约是改进比特币的好选择。然而,社区仍在激烈争论应该采用哪种方法来实现契约。
APO、OP_VAULT、TLUV 偏向直接应用,选择这三种方式可以更便宜更高效地实现特定应用。闪电网络爱好者会选择 APO 来实现 LN-Symmetry;想要实现 Vault 的用户最好使用 OP_VAULT;而对于搭建 CoinPool,TLUV 可以提供更好的隐私性和效率。OP_CAT 和 TXHASH 功能更丰富,出现安全漏洞的概率更小,与其他操作码结合可以实现更多用例,但代价可能是脚本复杂度增加。CTV 和 CSFS 调整了区块链处理方式,CTV 实现延迟输出,CSFS 实现延迟签名。MATT 以乐观执行和欺诈证明的策略脱颖而出,利用 Merkle Trie 结构实现通用智能合约,但内省功能仍需要新的操作码。
我们看到比特币社区正在积极讨论通过软分叉获得 Covenants 的可能性。Starknet 已正式宣布加入比特币生态,计划在 OP_CAT 合并后六个月内在比特币网络上实现结算。Chakra 将继续关注比特币生态的最新动态,推动 OP_CAT 软分叉的合并,并利用 Covenants 带来的可编程性构建更安全、更高效的比特币结算层。