该BIP提议激活一个新的操作码OP_CHECKOUTPUTSHASHVERIFY,用于Tapscript版本0。
JeremyRubin/ bips-archive Public
forked from TheBlueMatt/bips
op-checkoutputshashverify
Search this repository
/
Copy path
BlameMore file actions
BlameMore file actions
Improve abstract with motivation hint, add design risks and tradeoffs…
Open commit details
May 20, 2019
b53d120 · May 20, 2019
Open commit details
View commit history for this file.
293 lines (220 loc) · 13.4 KB
/
Top
Preview
Code
Blame
293 lines (220 loc) · 13.4 KB
Copy raw file
Download raw file
Outline
Edit and raw actions
BIP: bip-coshv
Title: OP_CHECKOUTPUTSHASHVERIFY
Author: Jeremy Rubin <j@rubin.io>
Status: Draft
Type: Standards Track
Created:
License: BSD-3-Clause
## Table of Contents<br>Permalink: Table of Contents<br>- Abstract<br>- Summary<br>- Motivation <br> - Congestion Controlled Transactions<br> - Channel Factories<br> - Wallet Vaults<br> - CoinJoin<br>- Design <br> <br> <br> - The following script is a minimal data push of 32 bytes<br> - There is only one input spent in this transaction<br> - The SHA256 double-hash of the serialized outputs matches the value provided<br> - Design Tradeoffs and Risks<br>- Specification<br>- Deployment<br>- Implementations<br>- References<br>- Copyright |
这个BIP提出了一个新的操作码,OP_CHECKOUTPUTSHASHVERIFY,用于在Tapscript版本0中激活。
这个新的操作码有多种应用,包括交易拥塞控制和支付通道实例化等,这些都在本BIP的动机部分中描述。
CHECKOUTPUTSHASHVERIFY 在 Tapscript 执行期间使用操作码 OP_RESERVED1 (0x89)。
CHECKOUTPUTSHASHVERIFY 验证以下条件:
如果 CHECKOUTPUTSHASHVERIFY 之后的操作不是 32 字节的数据推送,则忽略它。 否则,如果不满足条件,执行失败。
Covenants(或对币的使用方式的限制,超出密钥所有权)是构建智能合约的一种非常强大的结构。 然而,鉴于它们的复杂性和引入同质化风险的可能性,到目前为止,它们还没有被认真考虑纳入比特币。
本 BIP 旨在引入一个最小可行的 covenant,以启用一组有限的实用功能。 例如:
Permalink: Congestion Controlled Transactions
当对区块空间的需求很大时,进行支付可能会变得非常昂贵。 通过使用 CHECKOUTPUTSHASHVERIFY,大型支付处理商可以将所有支付聚合到单个 O(1) 交易中以进行确认。 然后,在稍后的某个时间,当对区块空间的需求减少时,可以将支付从该 UTXO 中扩展出来。
如果没有 CHECKOUTPUTSHASHVERIFY,仍然可以使用 Schnorr 签名(即使使用 ECDSA,考虑到多方方案)来实现这一点。 然而,不可能以非交互方式进行,这从根本上限制了这种方法的可行性。
要构建拥塞控制交易,用户有多种选择——它可以简单地是从 1 个输出到 N 个输出的单步,或者,用户可以使用 CHECKOUTPUTSHASHVERIFY 提交到输出树,这允许他们确认任意数量的支付。 此外,Taproot 可以提交到可变大小的扩展——例如,一个节点可以扩展 2 个、4 个、8 个等。这允许在交易开销和立即可用的区块空间之间进行权衡。 在这种情况下,Merkle 树查找是 O(log(log(N))) 的额外开销,但树可以进行 Huffman 编码,使其成为 E[O(1)],具体取决于区块需求。 树的每个节点也可以尝试“选择加入”以优先使用基于 Taproot 签名的花费,但如果参与者离线或恶意,则扩展可以进行到更小的组。
从每个用户的角度来看,这种方法的总体开销(没有优化)是 O(log(N)) 交易,预计只有 1 笔额外的交易,从网络的角度来看是 2N。 然而,考虑到此类交易不需要签名,实际开销较小。
下图展示了这些交易与普通交易和批量交易相比的结构。
下面显示了一个模拟,说明了在 5% 的网络采用率和 50% 的网络采用率的情况下,这对内存池积压可能产生的影响。 该模拟的代码在本 BIP 的子目录中提供。
此用例与上述用例类似,只是叶节点应该设置为通道(可能在付款人和收款人之间或收款人选择的目标之间),而不是支付。
对于设置来说,这些通道已经对时间不敏感,因为所有惩罚都可以相对于实际实例化进行相对时间锁定。
这允许使用这种延迟方法发送的币即时获得流动性。
当冷存储解决方案需要更高的安全性时,可以有默认的 Tapscript 路径,将资金从一个目标转移到另一个目标。
例如,可以设置一个冷钱包,其中一个客户支持部门可以在没有进一步授权的情况下,将一部分资金(使用多个预设金额)转移到一个由隔离的支持部门运营的半温钱包中。 然后,支持部门可以将一些资金发放给热钱包,并将剩余的资金通过类似的提款机制返回到冷存储中。
所有这些都可以在没有 CHECKOUTPUTSHASHVERIFY 的情况下实现,但 CHECKOUTPUTSHASHVERIFY 消除了对协调和在线签名者的需求,并降低了支持部门不当转移资金的能力。
此外,所有这些设计都可以与相对时间锁结合使用,以便合规和风险部门有时间进行干预。
这种方法使得设置一个无需信任的 CoinJoin 变得更加容易。
所有参与者都同意一个提交到其输出哈希的 UTXO,然后参与者可以使用他们喜欢的任何输入来资助交易。
然后,可以确认该交易。
如果需要,Tapscript 路径可以被基于签名的花费所取代,以提高同质性。
CHECKOUTPUTSHASHVERIFY 的目标是对现有代码库的影响最小——未来,随着我们意识到更复杂但显示为安全的使用案例,可能会启用新的 covenant 类型。
至关重要的是,因为这是一个 Tapscript,所以参与者可以协作将 Tapscript 路径替换为签名。 如果可以更新其他依赖项(如通道状态),这将取消了输出必须单独花费并且输出哈希必须完全匹配的要求。
下面我们将逐一讨论这些规则:
Permalink: The following script is a minimal data push of 32 bytes
CHECKOUTPUTSHASHVERIFY 使用操作码之后的推送,而不是操作码之前的推送。 如果 CHECKOUTPUTSHASHVERIFY 使用堆栈中的数据,则可以在脚本中构建提交的数据。 通过使用数据前瞻,我们确保在花费时已知输出。
脚本程序员仍然可以有条件地检查哪个哈希,例如OP_IF OP_CHECKOUTPUTSHASHVERIFY <outputs 1> OP_ELSE <outputs 2> OP_ENDIF
。 但是,通过保持输出文字哈希,我们限制了可能性。
无论如何,考虑到 Tapscript 的 API,用户更有可能将具有多个 OP_CHECKOUTPUTSHASHVERIFY
操作的任何代码编译到单独的分支中。
Permalink: There is only one input spent in this transaction
如果我们允许多个输入在交易中花费,那么两个输出可能会请求支付到同一组输出,从而导致一半的预期支付被丢弃。 虽然有安全的方法来允许多个输入,但设计要复杂得多,并且用例不太清楚。
此外,对哪些输入可以共同花费的限制对于需要稳定 TXID 的支付通道结构至关重要。
Permalink: The SHA256 double-hash of the serialized outputs matches the value provided
这是一个已经计算出的哈希,因此我们可以节省额外的验证开销。 因此,OP_CHECKOUTPUTSHASHVERIFY
不会带来大量的额外验证开销。
在堆栈上公开此哈希可能会允许解析输出,这不是一个问题,因为在脚本构建时已经完全知道它们。
Permalink: Design Tradeoffs and Risks
Covenants 在历史上一直存在争议,因为它们存在同质性风险——可能会铸造对如何花费或不花费的永久性限制的币。
在这里提出的方法中,covenants 受到以下严格限制。 所有 covenants 都用基于多重签名的密钥包装,该密钥可以抢占 covenant 的要求。 此外,OP_CHECKOUTPUTSHASHVERIFY covenants 的结构使得输出在构建时必须完全已知。 因此,只能创建以有限数量的步骤扩展的 covenants,并且在安全意义上等同于创建所有可到达最终状态的输入的一组交易。 此外,covenants 仅限于作为单个输入可花费,从而防止了“半花费”问题。
这些 covenants,尽管受到限制,仍然存在一些风险。 提供给 OP_CHECKOUTPUTSHASHVERIFY 的 preImage 可能是未知的,或者 Taproot 是使用具有未知私钥的公钥构建的。 知道可以从中花费地址与发送者花费到任何地址(尤其是 OP_RETURN)的能力不兼容。 如果发送者需要知道接收者可以在花费之前删除 covenant,他们可以请求接收者对挑战字符串的签名。 最后一个风险是滥用“转发地址合约”。 转发地址是可以自动以预定义方式执行的脚本。 例如,热钱包可能有一些币可以在相对超时后自动转移到冷存储地址。 问题是重用此类密钥可能非常不安全。 例如,假设创建一个地址,将 1 BTC 转发到冷存储。 创建一个输出到此地址,金额少于 1 BTC 将被冻结,直到使用 Taproot 签名路径。 如果支付给该地址的金额超过 1 BTC,并且 redeemscript 是公开已知的,那么任何人都可以导致超过 1 BTC 的资金作为大量矿工费支付。 以后可能会引入提交到最多应花费多少费用或其他限制的操作码,这将使可重用密钥更安全地使用。 目前,最好不要重用 Taproot 密钥,除非你确定所有分支都与你想要的支付兼容。 这种限制和风险并非 OP_CHECKOUTPUTSHASHVERIFY 独有,Taproot 脚本可能包含许多逻辑分支,这些分支多次花费是不安全的(例如,哈希时间锁分支每次使用时都应使用唯一的哈希进行实例化)。
如果实施了 MES16 提出的更强大的 covenants,将使 OP_CHECKOUTPUTSHASHVERIFY 类型的 covenant 变得多余。 它们还将带来一些好处,例如提高调整费用等因素的能力,而不是依赖于子为父付费或其他机制。 然而,这些功能带来了大大增加的复杂性和意外行为的空间。 或者,基于 CHECKSIGFROMSTACK 或 SIGHASH_NOINPUT 的 covenant 设计也可能能够实施 covenants。 SIGHASH_NOINPUT 带来了额外的风险,使其无法包含在比特币中。 CHECKSIGFROMSTACK 比 OP_CHECKOUTPUTSHASHVERIFY 更难使用,并且增加了 OP_CHECKOUTPUTSHASHVERIFY 中没有的额外验证开销。 鉴于这种方法易于实施和分析,以及用户应用程序可实现的好处,因此提出了 OP_CHECKOUTPUTSHASHVERIFY 方法。
以下代码是验证 OP_CHECKOUTPUTSHASHVERIFY
的主要逻辑。
case OP_CHECKOUTPUTSHASHVERIFY:
{
// Don't verify before enabled...
if (flags & SCRIPT_VERIFY_OUTPUTS_HASH) {
CScript::const_iterator lookahead = pc;
opcodetype argument;
// Read ahead one opcode as a lookahead argument
if (!script.GetOp(lookahead, argument, vchPushValue))
return set_error(serror, SCRIPT_ERR_BAD_OPCODE);
// If lookahead argument was exactly 32 bytes, check OutputHash
// This is so that we can later add different semantics for this opcode
if (vchPushValue.size() == 32) {
// Argument should be == 0x20 -- will fail later anyways
if (!CheckMinimalPush(vchPushValue, argument)) {
return set_error(serror, SCRIPT_ERR_MINIMALDATA);
}
// If multiple inputs allowed, two inputs with the same OutputsHashVerify
// would pay only half intended amount!
if (!checker.CheckOnlyOneInput()) {
return set_error(serror, SCRIPT_ERR_OUTPUTSHASHVERIFY);
}
// Lastly, check that the outputs hash matches the passed value
if (!checker.CheckOutputsHash(vchPushValue)) {
return set_error(serror, SCRIPT_ERR_OUTPUTSHASHVERIFY);
}
}
}
}
break;
该部署旨在与 Tapscript 一起完成 https://github.com/sipa/bips/blob/bip-schnorr/bip-tapscript.mediawiki。
一个实现和测试可以在这里找到:https://github.com/JeremyRubin/bitcoin/tree/congestion-control。
本文档基于 3 条款 BSD 许可获得许可。
- 原文链接: github.com/JeremyRubin/b...
- 登链社区 AI 助手,为大家转译优秀英文文章,如有翻译不通的地方,还请包涵~
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!