与像以太坊这样的图灵完备区块链相比,比特币的脚本被认为是高度限制的,仅能进行基本操作,甚至不支持乘法和除法。更重要的是,区块链自身的数据几乎无法被脚本访问,这导致灵活性和可编程性的显著缺乏。因此,长期以来一直致力于使比特币脚本能够实现内省功能。
内省指的是比特币脚本能够检查和约束交易数据的能力。这使得脚本可以根据特定的交易细节控制资金的使用,从而实现更复杂的功能。目前,大多数比特币操作码要么将用户提供的数据推送到栈上,要么操作栈上现有的数据。然而,内省操作码可以将当前交易中的数据(如时间戳、金额、交易ID等)推送到栈上,从而允许对UTXO支出进行更精细的控制。
目前,比特币脚本中只有三个主要的操作码支持内省:CHECKLOCKTIMEVERIFY、CHECKSEQUENCEVERIFY,以及CHECKSIG及其变体CHECKSIGVERIFY、CHECKSIGADD、CHECKMULTISIG和CHECKMULTISIGVERIFY。
契约,简单来说,就是对如何转移比特币的限制,允许用户指定UTXO的分配方式。许多契约是通过内省操作码实现的,关于内省的讨论现在被归类为比特币Optech中的契约话题。
比特币目前有两个契约:CSV(CheckSequenceVerify)和CLTV(CheckLockTimeVerify),这两个时间基础的契约是许多扩容方案(如闪电网络)的基础。这表明,比特币的扩容方案在很大程度上依赖于内省和契约。
如何在转移比特币时添加条件?在加密领域,我们最常用的方法是通过承诺,通常通过哈希实现。为了证明转移要求已满足,还需要签名机制进行验证。因此,契约中涉及许多对哈希和签名的调整。
下面,我们将描述广泛讨论的契约操作码提案。
CTV(CheckTemplateVerify)是比特币的升级提案,包含在BIP-119中,并引起了社区的广泛关注。CTV允许输出脚本指定用于支出交易的模板,包括字段如 nVersion、nLockTime、scriptSig 哈希、输入计数、序列哈希、输出计数、输出哈希、输入索引。这些模板限制通过哈希承诺实现,当资金被支出时,脚本检查支出交易中指定字段的哈希值是否与输入脚本中的哈希值匹配。这有效地限制了该UTXO未来交易的时间、方式和金额。
值得注意的是,输入交易ID(TXID)被排除在这个哈希之外。这种排除是必要的,因为在使用默认的 SIGHASH_ALL 签名类型的传统交易和隔离见证交易中,TXID 取决于 scriptPubKey 中的值。包括 TXID 会导致哈希承诺中的循环依赖,使其无法构造。
CTV 通过直接提取指定交易信息进行哈希,并将其与栈上的承诺进行比较来实现内省。这种内省方法对链上的空间要求较低,但灵活性较差。
比特币二层解决方案,如闪电网络,的基础是预签名交易。预签名通常指的是提前生成和签署交易,但在满足某些条件之前不会广播它们。从本质上讲,CTV 实现了一种更严格的预签名形式,将预签名的承诺发布到链上,并限制在预定义的模板中。
CTV 最初是为了缓解比特币网络的拥堵,也可以称为拥堵控制。在高拥堵时期,CTV 可以在单个交易中承诺多个未来交易,避免在高峰时段广播多个交易,并在拥堵缓解后完成实际交易。这在交易所银行挤兑期间尤其有用。此外,该模板还可用于实施保险库(Vaults),以防止黑客攻击。由于资金方向是预定的,黑客无法使用 CTV 脚本将 UTXO 转移到自己的地址。
CTV 可以显著增强二层网络。例如,在闪电网络中,CTV 可以通过将单个 UTXO 扩展为 CTV 树,创建超时树(Timeout Trees)和频道工厂(Channel Factories),只需一个交易和一个确认即可打开多个状态通道。此外,CTV 还通过 ATLC 支持 Ark 协议中的原子交易。
BIP-118 引入了一种新的签名哈希标志类型,用于 Taproot 脚本(tapscript),旨在实现更灵活的支出逻辑,即 SIGHASH_ANYPREVOUT。APO 和 CTV 具有许多相似之处。在处理 scriptPubKeys 和 TXIDs 之间的循环问题时,APO 的方法是排除相关的输入信息,仅签署输出,从而允许交易动态绑定到不同的 UTXO 上。
从逻辑上讲,签名验证操作 OP_CHECKSIG(及其变体)执行三个功能:
组装支出交易的各部分。
对这些部分进行哈希。
验证该哈希是否由给定的密钥签名。
签名的具体细节具有很大的灵活性,决定哪些交易字段需要签名由 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 和输入 TXIDs 之间的循环,APO 可以通过在见证区块中添加输出数据来实现内省,尽管这仍然需要额外的见证区块空间消耗。
对于像闪电网络和保险库这样的链下协议,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 实现保险库需要考虑成本问题,特别是恢复交易的成本。可能的解决方案包括 CPFP(子交易支付父交易费用)、临时锚定和新的 SIGHASH_GROUP 签名哈希标志。
TLUV 方案围绕 Taproot 构建,旨在有效解决从共享 UTXO 退出的问题。其指导原则是,当 Taproot 输出被支出时,可以通过加密转换和 Taproot 地址的内部结构对内部密钥和 MAST(tapscript trie)进行部分更新,如 TLUV 脚本所述。这使得契约功能的实现成为可能。
具体而言,TLUV 接受三个输入:
指定如何更新内部公钥。
指定 Merkle 路径的新步骤。
指定是否移除当前脚本和/或修剪 Merkle 路径的多少步。
TLUV 操作码计算更新后的 scriptPubKey,并验证与当前输入对应的输出是否支出到此 scriptPubKey。
TLUV 的灵感来源于 CoinPool 概念。目前,共同池可以通过预签名交易创建,但如果要实现未经许可的退出,则需要创建指数级增长数量的签名。然而,TLUV 允许无需任何预签名即可实现未经许可的退出。例如,一组合伙人可以使用 Taproot 创建一个共享 UTXO,将他们的资金汇集在一起。他们可以使用 Taproot 密钥内部移动资金或联合签署以发起外部支付。个人可以随时退出共享资金池,移除他们的支付路径,而其他人仍然可以通过原始路径完成支付,并且个人的退出不会暴露关于其他人的额外信息。这种模式相比非池化交易更加高效和私密。
TLUV 操作码通过更新原始的 Taproot Trie 实现了部分支出限制,但它并未实现对输出金额的内省。因此,还需要一个新的操作码 IN_OUT_AMOUNT。这个操作码将两个项推送到栈上:此输入的 UTXO 金额和对应输出的金额,然后使用 TLUV 的人应通过数学运算符验证在更新后的 scriptPubKey 中资金是否得到适当保留。
输出金额的内省增加了复杂性,因为金额以 satoshi 表示需要最多 51 位,而脚本仅允许 32 位数学操作。这需要重新定义操作码行为以升级脚本中的运算符,或使用 SIGHASH_GROUP 替代 IN_OUT_AMOUNT。
TLUV 在去中心化 Layer 2 资金池方面具有潜力,尽管在调整 Taproot Trie 方面的可靠性仍需确认。
MATT(Merkleize All The Things)旨在实现三个目标:Merkle 化状态、Merkle 化脚本和 Merkle 化执行,从而启用通用智能合约。
Merkle 化执行
要实现 MATT,Bitcoin 脚本语言需要具备以下功能:
强制输出具有特定脚本(及其金额)
将一段数据附加到输出
从当前输入(或其他输入)读取数据
第二点至关重要:动态数据意味着状态可以通过支出者提供的输入数据计算,从而实现状态机的模拟,确定下一个状态和附加数据。MATT 方案通过 OP_CHECKCONTRACTVERIFY(OP_CCV)操作码实现这一点,该操作码是之前提议的 OP_CHECKOUTPUTCONTRACTVERIFY 和 OP_CHECKINPUTCONTRACTVERIFY 操作码的合并,使用附加的标志参数来指定操作的目标。
控制输出金额:最直接的方法是直接内省;然而,输出金额是 64 位数字,需要 64 位算术,这在 Bitcoin 脚本中具有相当大的复杂性。OP_CCV 采用了类似 OP_VAULT 的延迟检查方法,其中所有指向具有 CCV 的相同输出的输入金额被累加,作为该输出金额的下限。延迟的原因是,这项检查发生在交易处理过程中,而不是在输入的脚本评估期间。
考虑到欺诈证明的普遍性,某些 MATT 合约变体应能够实现所有类型的智能合约或 Layer 2 构造,尽管需要准确评估额外要求(如资本锁定和挑战期延迟);进一步的研究需要评估哪些应用适用于交易。例如,使用加密承诺和欺诈挑战机制来模拟 OP_ZK_VERIFY 功能,实现 Bitcoin 上的无信任 Rollups。
在实践中,已经有所进展。Johan Torås Halseth 使用 MATT 软件分叉提案中的 OP_CHECKCONTRACTVERIFY 操作码实现了 elftrace,这允许任何支持 RISC-V 编译的程序在 Bitcoin 区块链上进行验证,使得合约协议中的一方可以通过合约验证访问资金,从而实现 Bitcoin 原生验证的桥接。
从 APO 操作码的引入中,我们了解到 OP_CHECKSIG(及其相关操作)负责组装交易、进行哈希计算和验证签名。然而,这些操作所验证的消息是通过操作码对交易进行序列化而得出的,并且不允许指定任何其他消息。简单来说,OP_CHECKSIG(及其相关操作)的作用是通过签名机制验证作为交易输入的 UTXO 是否已被签名者授权支出,从而保护 Bitcoin 的安全性。
CSFS,顾名思义,即“从栈中检查签名”。CSFS 操作码从栈中接收三个参数:签名、消息和公钥,然后验证签名的有效性。这意味着用户可以通过 Witness 将任何消息传递到栈中,并通过 CSFS 进行验证,从而在 Bitcoin 上实现一些创新。
CSFS 的灵活性使其能够实现诸如支付签名、授权委托、预言机合约、双重支付保护担保等机制,更重要的是,还可以实现交易内省。使用 CSFS 进行交易内省的原理相当简单:如果通过 Witness 将 OP_CHECKSIG 使用的交易内容推送到栈中,并且使用相同的公钥和签名通过 OP_CSFS 和 OP_CHECKSIG 进行验证,并且两者验证都成功,那么传递给 OP_CSFS 的任意消息内容就与 OP_CHECKSIG 隐式使用的序列化支出交易(以及其他数据)相同。我们从栈中获得经过验证的交易数据,这些数据可以用于通过其他操作码对支出交易施加限制。
CSFS 通常与 OP_CAT 一起出现,因为 OP_CAT 可以连接交易的不同字段以完成序列化,从而允许更精确地选择需要进行内省的交易字段。如果没有 OP_CAT,脚本不能从可以单独检查的数据中重新计算哈希值,因此它真正能够做的只是检查哈希是否对应于一个特定的值,这意味着这些币只能通过一个特定的交易进行支出。
CSFS 可以实现像 CLTV、CSV、CTV、APO 等操作码,使其成为一个多功能的内省操作码。因此,它也有助于 Bitcoin Layer2 的扩展解决方案。缺点是它需要在栈上添加已签名交易的完整副本,这可能显著增加使用 CSFS 进行内省的交易的大小。相比之下,像 CLTV 和 CSV 这样的单用途内省操作码开销较小,但每添加一个新的特殊内省操作码都需要共识变更。
OP_TXHASH 是一种简单的内省操作码,使操作员能够选择并将特定字段的哈希值推送到栈上。具体来说,OP_TXHASH 从栈中弹出一个 txhash 标志,并根据该标志计算一个(标记的)txhash,然后将结果哈希值推送回栈中。
由于 TXHASH 和 CTV 之间的相似性,社区内对这两者进行了大量讨论。
TXHASH 可以被视为 CTV 的通用升级,提供了更高级的交易模板,允许用户显式指定支出交易的各个部分,从而解决了与交易费用相关的许多问题。与其他 Covenant 操作码不同,TXHASH 不需要在 Witness 中复制必要的数据,进一步减少了存储需求;与 CTV 不同,TXHASH 不兼容 NOP,只能在 tapscript 中实现;TXHASH 和 CSFS 的组合可以作为 CTV 和 APO 的替代方案。
从构建 Covenant 的角度来看,TXHASH 更有利于创建“加法 Covenant”,在这种情况下,你希望固定的所有交易数据部分都被推送到栈上,全部哈希在一起,并验证生成的哈希值是否匹配固定值;而 CTV 更适合创建“减法 Covenant”,在这种情况下,你希望保持自由的所有交易数据部分都被推送到栈上。然后,使用滚动的 SHA256 操作码,从一个固定的中间状态开始哈希,这个中间状态对交易哈希数据的前缀进行承诺。自由部分会被哈希到这个中间状态中。
TXHASH 规范中定义的 TxFieldSelector 字段预计将扩展到其他操作码,例如 OP_TX。
与 TXHASH 相关的 BIP 目前在 GitHub 上处于草案状态,并未分配编号。
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 和 Schnorr 技巧》。
总之,OP_CAT 的多功能性使其能够模拟几乎任何 Covenant 操作码。许多 Covenant 操作码依赖于 OP_CAT 的功能,这大大提升了它在合并列表中的地位。从理论上讲,依靠 OP_CAT 和现有的比特币操作码,我们有望构建一个信任最小化的 BTC ZK Rollup。Starknet、Chakra 和其他生态系统合作伙伴正在积极推动这一进程。
在探索比特币的各种扩展策略和提升其可编程性的过程中,我们可以清楚地看到,前进的道路涉及本地改进、链下计算和复杂的脚本功能的结合。
没有灵活的基础层,就无法构建更灵活的第二层。
链下计算扩展是未来的趋势,但比特币的可编程性需要突破,以更好地支持这种扩展,成为真正的全球货币。
然而,比特币上的计算性质与以太坊上的计算本质上不同。比特币仅支持“验证”作为计算的一种形式,无法执行通用计算,而以太坊本质上是计算型的,验证是计算的副产品。这种差异从一个点上可以看出:以太坊对执行失败的交易收取 Gas 费,而比特币则不收取。
Covenants 代表了一种基于验证而非计算的智能合约形式。除了少数几个比特币原教旨主义者外,似乎每个人都认为 Covenants 是改善比特币的好选择。然而,社区对应采用哪种方式实现 Covenants 仍在激烈辩论。
APO、OP_VAULT 和 TLUV 倾向于直接应用,选择它们可以以更便宜、更高效的方式实现特定应用。闪电网络爱好者可能更倾向于使用 APO 实现 LN 对称性;那些希望实现 Vault 的用户最好选择 OP_VAULT;对于构建 CoinPool,TLUV 提供了更多的隐私和效率。OP_CAT 和 TXHASH 更具通用性,具有较小的安全漏洞概率,可以与其他操作码结合实现更多用例,但可能会增加脚本复杂性。CTV 和 CSFS 调整了区块链处理,其中 CTV 实现了延迟输出,CSFS 实现了延迟签名。MATT 通过乐观执行和欺诈证明的策略脱颖而出,利用 Merkle Trie 的结构实现通用智能合约,尽管它仍需要新的操作码来实现内省能力。
我们看到,比特币社区正在积极讨论通过软分叉获得 Covenants 的可能性。Starknet 已正式宣布进入比特币生态系统,计划在 OP_CAT 合并后的六个月内在比特币网络上实现结算。Chakra 将继续关注比特币生态系统的最新发展,推动 OP_CAT 软分叉的合并,并利用 Covenants 带来的可编程性来构建一个更安全、更高效的比特币结算层。
与像以太坊这样的图灵完备区块链相比,比特币的脚本被认为是高度限制的,仅能进行基本操作,甚至不支持乘法和除法。更重要的是,区块链自身的数据几乎无法被脚本访问,这导致灵活性和可编程性的显著缺乏。因此,长期以来一直致力于使比特币脚本能够实现内省功能。
内省指的是比特币脚本能够检查和约束交易数据的能力。这使得脚本可以根据特定的交易细节控制资金的使用,从而实现更复杂的功能。目前,大多数比特币操作码要么将用户提供的数据推送到栈上,要么操作栈上现有的数据。然而,内省操作码可以将当前交易中的数据(如时间戳、金额、交易ID等)推送到栈上,从而允许对UTXO支出进行更精细的控制。
目前,比特币脚本中只有三个主要的操作码支持内省:CHECKLOCKTIMEVERIFY、CHECKSEQUENCEVERIFY,以及CHECKSIG及其变体CHECKSIGVERIFY、CHECKSIGADD、CHECKMULTISIG和CHECKMULTISIGVERIFY。
契约,简单来说,就是对如何转移比特币的限制,允许用户指定UTXO的分配方式。许多契约是通过内省操作码实现的,关于内省的讨论现在被归类为比特币Optech中的契约话题。
比特币目前有两个契约:CSV(CheckSequenceVerify)和CLTV(CheckLockTimeVerify),这两个时间基础的契约是许多扩容方案(如闪电网络)的基础。这表明,比特币的扩容方案在很大程度上依赖于内省和契约。
如何在转移比特币时添加条件?在加密领域,我们最常用的方法是通过承诺,通常通过哈希实现。为了证明转移要求已满足,还需要签名机制进行验证。因此,契约中涉及许多对哈希和签名的调整。
下面,我们将描述广泛讨论的契约操作码提案。
CTV(CheckTemplateVerify)是比特币的升级提案,包含在BIP-119中,并引起了社区的广泛关注。CTV允许输出脚本指定用于支出交易的模板,包括字段如 nVersion、nLockTime、scriptSig 哈希、输入计数、序列哈希、输出计数、输出哈希、输入索引。这些模板限制通过哈希承诺实现,当资金被支出时,脚本检查支出交易中指定字段的哈希值是否与输入脚本中的哈希值匹配。这有效地限制了该UTXO未来交易的时间、方式和金额。
值得注意的是,输入交易ID(TXID)被排除在这个哈希之外。这种排除是必要的,因为在使用默认的 SIGHASH_ALL 签名类型的传统交易和隔离见证交易中,TXID 取决于 scriptPubKey 中的值。包括 TXID 会导致哈希承诺中的循环依赖,使其无法构造。
CTV 通过直接提取指定交易信息进行哈希,并将其与栈上的承诺进行比较来实现内省。这种内省方法对链上的空间要求较低,但灵活性较差。
比特币二层解决方案,如闪电网络,的基础是预签名交易。预签名通常指的是提前生成和签署交易,但在满足某些条件之前不会广播它们。从本质上讲,CTV 实现了一种更严格的预签名形式,将预签名的承诺发布到链上,并限制在预定义的模板中。
CTV 最初是为了缓解比特币网络的拥堵,也可以称为拥堵控制。在高拥堵时期,CTV 可以在单个交易中承诺多个未来交易,避免在高峰时段广播多个交易,并在拥堵缓解后完成实际交易。这在交易所银行挤兑期间尤其有用。此外,该模板还可用于实施保险库(Vaults),以防止黑客攻击。由于资金方向是预定的,黑客无法使用 CTV 脚本将 UTXO 转移到自己的地址。
CTV 可以显著增强二层网络。例如,在闪电网络中,CTV 可以通过将单个 UTXO 扩展为 CTV 树,创建超时树(Timeout Trees)和频道工厂(Channel Factories),只需一个交易和一个确认即可打开多个状态通道。此外,CTV 还通过 ATLC 支持 Ark 协议中的原子交易。
BIP-118 引入了一种新的签名哈希标志类型,用于 Taproot 脚本(tapscript),旨在实现更灵活的支出逻辑,即 SIGHASH_ANYPREVOUT。APO 和 CTV 具有许多相似之处。在处理 scriptPubKeys 和 TXIDs 之间的循环问题时,APO 的方法是排除相关的输入信息,仅签署输出,从而允许交易动态绑定到不同的 UTXO 上。
从逻辑上讲,签名验证操作 OP_CHECKSIG(及其变体)执行三个功能:
组装支出交易的各部分。
对这些部分进行哈希。
验证该哈希是否由给定的密钥签名。
签名的具体细节具有很大的灵活性,决定哪些交易字段需要签名由 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 和输入 TXIDs 之间的循环,APO 可以通过在见证区块中添加输出数据来实现内省,尽管这仍然需要额外的见证区块空间消耗。
对于像闪电网络和保险库这样的链下协议,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 实现保险库需要考虑成本问题,特别是恢复交易的成本。可能的解决方案包括 CPFP(子交易支付父交易费用)、临时锚定和新的 SIGHASH_GROUP 签名哈希标志。
TLUV 方案围绕 Taproot 构建,旨在有效解决从共享 UTXO 退出的问题。其指导原则是,当 Taproot 输出被支出时,可以通过加密转换和 Taproot 地址的内部结构对内部密钥和 MAST(tapscript trie)进行部分更新,如 TLUV 脚本所述。这使得契约功能的实现成为可能。
具体而言,TLUV 接受三个输入:
指定如何更新内部公钥。
指定 Merkle 路径的新步骤。
指定是否移除当前脚本和/或修剪 Merkle 路径的多少步。
TLUV 操作码计算更新后的 scriptPubKey,并验证与当前输入对应的输出是否支出到此 scriptPubKey。
TLUV 的灵感来源于 CoinPool 概念。目前,共同池可以通过预签名交易创建,但如果要实现未经许可的退出,则需要创建指数级增长数量的签名。然而,TLUV 允许无需任何预签名即可实现未经许可的退出。例如,一组合伙人可以使用 Taproot 创建一个共享 UTXO,将他们的资金汇集在一起。他们可以使用 Taproot 密钥内部移动资金或联合签署以发起外部支付。个人可以随时退出共享资金池,移除他们的支付路径,而其他人仍然可以通过原始路径完成支付,并且个人的退出不会暴露关于其他人的额外信息。这种模式相比非池化交易更加高效和私密。
TLUV 操作码通过更新原始的 Taproot Trie 实现了部分支出限制,但它并未实现对输出金额的内省。因此,还需要一个新的操作码 IN_OUT_AMOUNT。这个操作码将两个项推送到栈上:此输入的 UTXO 金额和对应输出的金额,然后使用 TLUV 的人应通过数学运算符验证在更新后的 scriptPubKey 中资金是否得到适当保留。
输出金额的内省增加了复杂性,因为金额以 satoshi 表示需要最多 51 位,而脚本仅允许 32 位数学操作。这需要重新定义操作码行为以升级脚本中的运算符,或使用 SIGHASH_GROUP 替代 IN_OUT_AMOUNT。
TLUV 在去中心化 Layer 2 资金池方面具有潜力,尽管在调整 Taproot Trie 方面的可靠性仍需确认。
MATT(Merkleize All The Things)旨在实现三个目标:Merkle 化状态、Merkle 化脚本和 Merkle 化执行,从而启用通用智能合约。
Merkle 化执行
要实现 MATT,Bitcoin 脚本语言需要具备以下功能:
强制输出具有特定脚本(及其金额)
将一段数据附加到输出
从当前输入(或其他输入)读取数据
第二点至关重要:动态数据意味着状态可以通过支出者提供的输入数据计算,从而实现状态机的模拟,确定下一个状态和附加数据。MATT 方案通过 OP_CHECKCONTRACTVERIFY(OP_CCV)操作码实现这一点,该操作码是之前提议的 OP_CHECKOUTPUTCONTRACTVERIFY 和 OP_CHECKINPUTCONTRACTVERIFY 操作码的合并,使用附加的标志参数来指定操作的目标。
控制输出金额:最直接的方法是直接内省;然而,输出金额是 64 位数字,需要 64 位算术,这在 Bitcoin 脚本中具有相当大的复杂性。OP_CCV 采用了类似 OP_VAULT 的延迟检查方法,其中所有指向具有 CCV 的相同输出的输入金额被累加,作为该输出金额的下限。延迟的原因是,这项检查发生在交易处理过程中,而不是在输入的脚本评估期间。
考虑到欺诈证明的普遍性,某些 MATT 合约变体应能够实现所有类型的智能合约或 Layer 2 构造,尽管需要准确评估额外要求(如资本锁定和挑战期延迟);进一步的研究需要评估哪些应用适用于交易。例如,使用加密承诺和欺诈挑战机制来模拟 OP_ZK_VERIFY 功能,实现 Bitcoin 上的无信任 Rollups。
在实践中,已经有所进展。Johan Torås Halseth 使用 MATT 软件分叉提案中的 OP_CHECKCONTRACTVERIFY 操作码实现了 elftrace,这允许任何支持 RISC-V 编译的程序在 Bitcoin 区块链上进行验证,使得合约协议中的一方可以通过合约验证访问资金,从而实现 Bitcoin 原生验证的桥接。
从 APO 操作码的引入中,我们了解到 OP_CHECKSIG(及其相关操作)负责组装交易、进行哈希计算和验证签名。然而,这些操作所验证的消息是通过操作码对交易进行序列化而得出的,并且不允许指定任何其他消息。简单来说,OP_CHECKSIG(及其相关操作)的作用是通过签名机制验证作为交易输入的 UTXO 是否已被签名者授权支出,从而保护 Bitcoin 的安全性。
CSFS,顾名思义,即“从栈中检查签名”。CSFS 操作码从栈中接收三个参数:签名、消息和公钥,然后验证签名的有效性。这意味着用户可以通过 Witness 将任何消息传递到栈中,并通过 CSFS 进行验证,从而在 Bitcoin 上实现一些创新。
CSFS 的灵活性使其能够实现诸如支付签名、授权委托、预言机合约、双重支付保护担保等机制,更重要的是,还可以实现交易内省。使用 CSFS 进行交易内省的原理相当简单:如果通过 Witness 将 OP_CHECKSIG 使用的交易内容推送到栈中,并且使用相同的公钥和签名通过 OP_CSFS 和 OP_CHECKSIG 进行验证,并且两者验证都成功,那么传递给 OP_CSFS 的任意消息内容就与 OP_CHECKSIG 隐式使用的序列化支出交易(以及其他数据)相同。我们从栈中获得经过验证的交易数据,这些数据可以用于通过其他操作码对支出交易施加限制。
CSFS 通常与 OP_CAT 一起出现,因为 OP_CAT 可以连接交易的不同字段以完成序列化,从而允许更精确地选择需要进行内省的交易字段。如果没有 OP_CAT,脚本不能从可以单独检查的数据中重新计算哈希值,因此它真正能够做的只是检查哈希是否对应于一个特定的值,这意味着这些币只能通过一个特定的交易进行支出。
CSFS 可以实现像 CLTV、CSV、CTV、APO 等操作码,使其成为一个多功能的内省操作码。因此,它也有助于 Bitcoin Layer2 的扩展解决方案。缺点是它需要在栈上添加已签名交易的完整副本,这可能显著增加使用 CSFS 进行内省的交易的大小。相比之下,像 CLTV 和 CSV 这样的单用途内省操作码开销较小,但每添加一个新的特殊内省操作码都需要共识变更。
OP_TXHASH 是一种简单的内省操作码,使操作员能够选择并将特定字段的哈希值推送到栈上。具体来说,OP_TXHASH 从栈中弹出一个 txhash 标志,并根据该标志计算一个(标记的)txhash,然后将结果哈希值推送回栈中。
由于 TXHASH 和 CTV 之间的相似性,社区内对这两者进行了大量讨论。
TXHASH 可以被视为 CTV 的通用升级,提供了更高级的交易模板,允许用户显式指定支出交易的各个部分,从而解决了与交易费用相关的许多问题。与其他 Covenant 操作码不同,TXHASH 不需要在 Witness 中复制必要的数据,进一步减少了存储需求;与 CTV 不同,TXHASH 不兼容 NOP,只能在 tapscript 中实现;TXHASH 和 CSFS 的组合可以作为 CTV 和 APO 的替代方案。
从构建 Covenant 的角度来看,TXHASH 更有利于创建“加法 Covenant”,在这种情况下,你希望固定的所有交易数据部分都被推送到栈上,全部哈希在一起,并验证生成的哈希值是否匹配固定值;而 CTV 更适合创建“减法 Covenant”,在这种情况下,你希望保持自由的所有交易数据部分都被推送到栈上。然后,使用滚动的 SHA256 操作码,从一个固定的中间状态开始哈希,这个中间状态对交易哈希数据的前缀进行承诺。自由部分会被哈希到这个中间状态中。
TXHASH 规范中定义的 TxFieldSelector 字段预计将扩展到其他操作码,例如 OP_TX。
与 TXHASH 相关的 BIP 目前在 GitHub 上处于草案状态,并未分配编号。
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 和 Schnorr 技巧》。
总之,OP_CAT 的多功能性使其能够模拟几乎任何 Covenant 操作码。许多 Covenant 操作码依赖于 OP_CAT 的功能,这大大提升了它在合并列表中的地位。从理论上讲,依靠 OP_CAT 和现有的比特币操作码,我们有望构建一个信任最小化的 BTC ZK Rollup。Starknet、Chakra 和其他生态系统合作伙伴正在积极推动这一进程。
在探索比特币的各种扩展策略和提升其可编程性的过程中,我们可以清楚地看到,前进的道路涉及本地改进、链下计算和复杂的脚本功能的结合。
没有灵活的基础层,就无法构建更灵活的第二层。
链下计算扩展是未来的趋势,但比特币的可编程性需要突破,以更好地支持这种扩展,成为真正的全球货币。
然而,比特币上的计算性质与以太坊上的计算本质上不同。比特币仅支持“验证”作为计算的一种形式,无法执行通用计算,而以太坊本质上是计算型的,验证是计算的副产品。这种差异从一个点上可以看出:以太坊对执行失败的交易收取 Gas 费,而比特币则不收取。
Covenants 代表了一种基于验证而非计算的智能合约形式。除了少数几个比特币原教旨主义者外,似乎每个人都认为 Covenants 是改善比特币的好选择。然而,社区对应采用哪种方式实现 Covenants 仍在激烈辩论。
APO、OP_VAULT 和 TLUV 倾向于直接应用,选择它们可以以更便宜、更高效的方式实现特定应用。闪电网络爱好者可能更倾向于使用 APO 实现 LN 对称性;那些希望实现 Vault 的用户最好选择 OP_VAULT;对于构建 CoinPool,TLUV 提供了更多的隐私和效率。OP_CAT 和 TXHASH 更具通用性,具有较小的安全漏洞概率,可以与其他操作码结合实现更多用例,但可能会增加脚本复杂性。CTV 和 CSFS 调整了区块链处理,其中 CTV 实现了延迟输出,CSFS 实现了延迟签名。MATT 通过乐观执行和欺诈证明的策略脱颖而出,利用 Merkle Trie 的结构实现通用智能合约,尽管它仍需要新的操作码来实现内省能力。
我们看到,比特币社区正在积极讨论通过软分叉获得 Covenants 的可能性。Starknet 已正式宣布进入比特币生态系统,计划在 OP_CAT 合并后的六个月内在比特币网络上实现结算。Chakra 将继续关注比特币生态系统的最新发展,推动 OP_CAT 软分叉的合并,并利用 Covenants 带来的可编程性来构建一个更安全、更高效的比特币结算层。