关于 OP-CHECKOUTPUTSHASHVERIFY 的 bips-archive/bip-coshv.mediawiki

该BIP (Bitcoin Improvement Proposal) 提议引入一个新的操作码 OP_CHECKOUTPUTSHASHVERIFY,用于Tapscript版本0。这个新的操作码可以用于交易拥塞控制和支付通道的实例化等。该操作码验证输出的 SHA256 双哈希是否与提供的值匹配,从而实现有限的智能合约功能,例如拥塞控制交易、通道工厂和钱包保险库,同时尽量减少对现有代码库的影响。

跳转到内容Skip to content

JeremyRubin/ bips-archive Public

forked from TheBlueMatt/bips

折叠文件树

文件

op-checkoutputshashverify

搜索此仓库

/

bip-coshv.mediawiki

复制路径

BlameMore file actions

BlameMore file actions

最新提交

JeremyRubinJeremyRubin

使用动机提示改进摘要,添加设计风险和权衡…

打开提交详情

May 20, 2019

b53d120 · May 20, 2019

历史

历史

打开提交详情

查看此文件的提交历史。

293 lines (220 loc) · 13.4 KB

/

bip-coshv.mediawiki

顶部

文件元数据和控件

  • 预览

  • 代码

  • Blame

293 lines (220 loc) · 13.4 KB

Raw

复制 raw 文件

下载 raw 文件

概要

编辑和 raw 操作

  BIP: bip-coshv
  Title: OP_CHECKOUTPUTSHASHVERIFY
  Author: Jeremy Rubin <j@rubin.io>
  Status: Draft
  Type: Standards Track
  Created:
  License: BSD-3-Clause
## 目录<br>固定链接:目录<br>- 摘要<br>- 概要<br>- 动机 <br> - 拥塞控制交易<br> - 通道工厂<br> - 钱包保险库<br> - 币合<br>- 设计 <br> <br> <br> - 以下脚本是 32 字节的最小数据推送<br> - 此交易中只花费了一个输入<br> - 序列化输出的 SHA256 双哈希与提供的值匹配<br> - 设计折衷和风险<br>- 规范<br>- 部署<br>- 实现<br>- 参考文献<br>- 版权

摘要

固定链接:摘要

本 BIP 提议一个新的操作码 OP_CHECKOUTPUTSHASHVERIFY,在 Tapscript version 0 中激活。

这个新的操作码具有交易拥塞控制和支付通道实例化等应用,这些应用在本 BIP 的动机部分中描述。

概要

固定链接:概要

CHECKOUTPUTSHASHVERIFY 在 Tapscript 执行期间使用操作码 OP_RESERVED1 (0x89)。

CHECKOUTPUTSHASHVERIFY 验证以下条件:

  • 以下脚本是 32 字节的最小数据推送
  • 此交易中只花费了一个输入
  • 序列化输出的 SHA256 双哈希与提供的值匹配

如果 CHECKOUTPUTSHASHVERIFY 之后的操作不是 32 字节的数据推送,则忽略它。 否则,如果不满足条件,执行失败。

动机

固定链接:动机

Covenants -- 或对一枚币如何花费的限制,超越了密钥所有权 -- 是构建智能合约的非常强大的结构。 然而,考虑到它们的复杂性以及引入同质化风险的可能性,到目前为止,人们还没有认真考虑将它们纳入比特币。

此 BIP 旨在引入一个最小可行的 covenant,它启用了一组有限的实用功能。 例如:

拥塞控制交易

固定链接:拥塞控制交易

当对区块空间的需求很大时,进行支付可能会变得非常昂贵。 通过使用 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% 的网络采用率下,这可能对 mempool 积压产生的影响。 此模拟的代码在此 BIP 的子目录中提供。

通道工厂

固定链接:通道工厂

这个用例与上面的用例类似,只是叶节点应该设置为一个通道(可能在付款人和收款人之间或收款人选择的目标)。

对于设置,这些通道已经对时间不敏感,因为所有惩罚都可以相对于实际实例化进行时间锁定。

这允许使用这种延迟方法发送的币获得即时流动性。

钱包保险库

固定链接:钱包保险库

当冷存储解决方案需要更高的安全性时,可以有默认的 Tapscript 路径,将资金从一个目标移动到另一个目标。

例如,可以设置一个冷钱包,一个客户支持部门可以在没有进一步授权的情况下,将一部分资金(使用多个预设金额)移动到一个由隔离的支持部门运营的温钱包中。 然后,支持部门可以将一些资金发放给一个热钱包,并将剩余的资金发送回冷存储,并采用类似的提款机制。

所有这些都可以在没有 CHECKOUTPUTSHASHVERIFY 的情况下实现,但 CHECKOUTPUTSHASHVERIFY 消除了对协调和在线签名者的需求,并减少了支持部门不当转移资金的能力。

此外,所有这些设计都可以与相对时间锁结合使用,以便合规和风险部门进行干预。

币合

固定链接:币合

这种方法使得建立一个无需信任的币合变得更加容易。

所有参与者都同意一个提交到其输出哈希的 UTXO,然后参与者可以使用他们喜欢的任何输入来资助该交易。

然后,可以确认该交易。

如果需要,Tapscript 路径可以被基于签名的花费所取代,以提高同质化。

设计

固定链接:设计

CHECKOUTPUTSHASHVERIFY 的目标是对现有代码库产生最小的影响 -- 在未来,当我们意识到更复杂但被证明是安全的使用案例时,可能会启用新的 covenant 类型。

至关重要的是,由于这是一个 Tapscript,因此参与者可以合作使用签名替换 Tapscript 路径。 如果可以更新其他依赖项(如通道状态),这会消除输出被单独花费的要求和输出哈希的完全匹配。

下面我们将逐一讨论这些规则:

以下脚本是 32 字节的最小数据推送

固定链接:以下脚本是 32 字节的最小数据推送

CHECKOUTPUTSHASHVERIFY 使用操作码之后的推送,而不是操作码之前的推送。 如果 CHECKOUTPUTSHASHVERIFY 使用堆栈中的数据,则可以在脚本中构造提交的数据。 通过使用数据前瞻,我们确保在花费时知道输出。

脚本程序员仍然能够有条件地检查哪个哈希,例如OP_IF OP_CHECKOUTPUTSHASHVERIFY &lt;outputs 1> OP_ELSE &lt;outputs 2> OP_ENDIF。 然而,通过保持输出字面哈希,我们限制了可能性。

在任何情况下,考虑到 Tapscript 的 API,用户更有可能将具有多个OP_CHECKOUTPUTSHASHVERIFY操作的任何代码编译到单独的分支中。

此交易中只花费了一个输入

固定链接:此交易中只花费了一个输入

如果我们允许在交易中花费多个输入,那么两个输出可能请求支付到同一组输出,导致一半的预期支付被丢弃。 虽然有安全的方法来允许多个输入,但该设计要复杂得多,并且用例不太清楚。

此外,对哪些输入可以共同花费的限制对于需要稳定 TXID 的支付通道结构至关重要。

序列化输出的 SHA256 双哈希与提供的值匹配

固定链接:序列化输出的 SHA256 双哈希与提供的值匹配

这是一个已经计算出的哈希,因此它可以使我们免于额外的验证开销。 因此,OP_CHECKOUTPUTSHASHVERIFY不会带来大量的额外验证开销。

在堆栈上公开此哈希可能会允许解析输出,但这并不是一个问题,因为它们在脚本构造时已经完全已知。

设计折衷和风险

固定链接:设计折衷和风险

Covenants 从历史上看一直存在争议,因为它们存在同质化风险 -- 可以铸造对它们的支出方式有永久性限制的币。

在此处介绍的方法中,covenants 受到以下严格限制。 所有 covenants 都用一个基于多重签名的密钥包装,该密钥可以抢占 covenant 的要求。 此外,OP_CHECKOUTPUTSHASHVERIFY covenants 的结构使得输出必须在构建时精确已知。 因此,只能创建以有限的步长扩展的 covenants,并且在安全意义上等同于创建所有可到达最终状态的输入的交易集。 此外,covenants 被限制为仅可作为单个输入花费,从而防止了“半花费”问题。

这些 covenants,就像它们受到的限制一样,也存在一些风险。 提供给 OP_CHECKOUTPUTSHASHVERIFY 的原像可能是未知的,或者 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:
    {
        // 当未启用时,不要验证...
        if (flags & SCRIPT_VERIFY_OUTPUTS_HASH) {
            CScript::const_iterator lookahead = pc;
            opcodetype argument;
            // 预读一个操作码作为前瞻参数
            if (!script.GetOp(lookahead, argument, vchPushValue))
                return set_error(serror, SCRIPT_ERR_BAD_OPCODE);
            // 如果前瞻参数正好是 32 字节,检查 OutputHash
            // 这是为了我们以后可以为此操作码添加不同的语义
            if (vchPushValue.size() == 32) {
                // Argument 应该 == 0x20 -- 无论如何稍后都会失败
                if (!CheckMinimalPush(vchPushValue, argument)) {
                    return set_error(serror, SCRIPT_ERR_MINIMALDATA);
                }
                // 如果允许多个输入,则具有相同 OutputsHashVerify 的两个输入
                // 将仅支付一半的预期金额!
                if (!checker.CheckOnlyOneInput()) {
                    return set_error(serror, SCRIPT_ERR_OUTPUTSHASHVERIFY);
                }
                // 最后,检查输出哈希是否与传递的值匹配
                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-clause BSD 许可证获得许可。

  • 原文链接: github.com/JeremyRubin/b...
  • 登链社区 AI 助手,为大家转译优秀英文文章,如有翻译不通的地方,还请包涵~
点赞 0
收藏 0
分享
本文参与登链社区写作激励计划 ,好文好收益,欢迎正在阅读的你也加入。

0 条评论

请先 登录 后评论
JeremyRubin
JeremyRubin
江湖只有他的大名,没有他的介绍。