vault · jl2012/bips 中的 bips/bip-0114.mediawiki

  • jl2012
  • 发布于 2025-05-04 23:29
  • 阅读 35

该BIP(比特币改进提案)提出了“Merklized Script”的概念,旨在通过使用 Merkle 树编码脚本中的互斥分支,实现更复杂的赎回条件,提高隐私性,并允许包含非共识强制数据。它通过 Merkle 根编码互斥的条件脚本分支,从而减少赎回栈的大小,并实现 O(log n) 的可扩展性。

跳到内容

jl2012/ bips 公开

bitcoin/bips fork

折叠文件树

文件

vault

搜索此仓库

/

bip-0114.mediawiki

复制路径

BlameMore 文件操作

BlameMore 文件操作

最新提交

jl2012jl2012

更新 BIP114 并添加与 Merklized Script Version 0 相关的 BIP

2017年9月8日

ce4a698 · 2017年9月8日

历史

历史

打开提交详情

查看此文件的提交历史。

191 行 (131 loc) · 16.9 KB

/

bip-0114.mediawiki

顶部

文件元数据和控件

  • 预览

  • 代码

  • Blame

191 行 (131 loc) · 16.9 KB

Raw

复制原始文件

下载原始文件

大纲

编辑和原始操作

  BIP: 114
  Layer: Consensus (soft fork)
  Title: Merklized Script
  Author: Johnson Lau <jl2012@xbt.hk>
  Comments-Summary: No comments yet.
  Comments-URI: https://github.com/bitcoin/bips/wiki/Comments:BIP-0114
  Status: Draft
  Type: Standards Track
  Created: 2016-04-02
  License: BSD-3-Clause
           CC0-1.0
## 目录<br>永久链接: 目录<br>- 摘要<br>- 动机 <br> - 比特币脚本系统的演变<br> - 见证中的附加脚本<br>- 规范 <br> - Merklized Script <br> - Merklized Script Version 0<br> - MSV0 中的新脚本功能<br> - 可升级性<br>- 原理<br>- 示例 <br> - 脚本 Merkle 根的计算<br> - 不平衡 एमएस<br> - 带超时的 Escrow<br> - 哈希时间锁合约<br> - 大型多重签名结构<br> - 额外数据的承诺<br>- 向后兼容性<br>- 部署<br>- 鸣谢<br>- 参考实现<br>- 参考<br>- 版权

摘要

永久链接: 摘要

此 BIP 定义了一种新的见证程序类型,该类型使用 Merkle 树来编码脚本中互斥的分支。 这使得当前不可能实现的复杂赎回条件成为可能,通过隐藏未执行的脚本来提高隐私性,并允许以非常低或零的额外成本包含非共识强制执行的数据。

动机

永久链接: 动机

比特币脚本系统的演变

永久链接: 比特币脚本系统的演变

比特币使用脚本系统来指定交易输出的赎回条件。 在其原始设计中,赎回条件由资金发送者直接记录在 scriptPubKey 中。 这种模式有几个缺点,特别是对于复杂的脚本:

  1. 接收者可能难以指定条件;
  2. 大型脚本占用更多 UTXO 空间;
  3. 发送者将为额外的区块空间付费;
  4. 为了防止 DoS 攻击,脚本限制为 10,000 字节和 201 个操作码;
  5. 脚本中任何未执行的分支和非共识强制执行的数据都对公众可见,消耗区块空间,同时损害隐私。

BIP16(Pay-to-script-hash,“P2SH”)通过在 scriptPubKey 中使用固定长度的 20 字节脚本哈希并将提供脚本的责任转移给赎回者来解决前 3 个问题。 但是,由于脚本中的数据推送大小限制,P2SH 脚本的大小可能不超过 520 字节。 此外,P2SH 仍然要求赎回者发布脚本的所有未执行分支。

BIP141 定义了 2 种支持隔离见证的新脚本类型。 pay-to-witness-script-hash (P2WSH) 在许多方面与 P2SH 相似。 通过在见证中提供脚本,P2WSH 恢复了原始的 10,000 字节脚本限制。 但是,它仍然需要发布未执行的分支。

Merkelized Abstract Syntax Tree (MAST) 的想法是使用 Merkle 树来编码脚本中的操作。 在花费时,用户可能只提供他们正在执行的分支,以及将分支连接到固定大小 Merkle 根的哈希值。 这将赎回栈的大小从 O(n) 减少到 O(log n)(n 作为操作的数量)。 这使得由于脚本大小和操作码限制而当前不可能实现的复杂赎回条件成为可能,通过隐藏未执行的分支来提高隐私性,并允许以非常低或零的额外成本包含非共识强制执行的数据。

此提案是简化且特殊的 MAST 案例。 Merkle 根不是编码单个操作,而是编码互斥的条件脚本分支。 尽管这不是 MAST 的完整实现,但它提供了相同级别的隐私和 O(log n) 可扩展性。

见证中的附加脚本

永久链接: 见证中的附加脚本

在比特币的原始设计中,允许用户在 scriptSig 中包含功能性脚本(即,不仅仅是数据推送)。 然而,由于密钥持有者没有签署脚本的机制,这种设计没有带来任何功能,而是可延展性的来源 (BIP62)。 当通过 BIP141 引入隔离见证时,也不可能在见证中包含其他脚本。

然而,通过适当的设计,允许在交易输入中添加其他脚本可能会允许现有系统无法实现的功能。 例如,密钥持有者可以委托花费权给其他密钥,无论是否附加其他条件,例如锁定时间。 它也可以与其他提议的功能一起使用,例如检查区块哈希,这在创建输出时可能未知。

本提案定义了一种机制,允许将此类附加脚本作为见证的一部分。 在 BIPYYY 中进一步定义,以确保此类脚本不是第三方可延展的。

规范

永久链接: 规范

Merklized Script

永久链接: Merklized Script

BIP141 中,版本字节为 1 或更大的见证程序被认为是任何人都可以花费的脚本。 如果见证程序版本字节为 1 并且程序大小为 32 字节,则应用以下新验证规则。 见证程序是 Script Merkle Root(定义如下)。

要赎回这种输出,见证必须至少包含 3 个项目。

Key Code 是最后一个见证项目。 它必须不小于 33 个字节,但没有上限。 Key Code HashKey Code 的单个 SHA256 值

Path 是倒数第二个见证项目。 它是 Key Code Hash 的序列化 Merkle 路径。 Path 的大小必须是 32 字节的倍数,并且必须不大于 1024 字节。 每个 32 字节的字都是连接到 Script Merkle Root 的 Merkle 分支中的双 SHA256 Merkle 节点(或者,如果它是另一个 Key Code Hash 的哈希值,则为单个 SHA256)。 树的 Depth(0 到 32) 是 Path 的大小除以 32。

Position 是倒数第三个见证项目。 它指示 Key Code Hash 在 Merkle 树中的位置,0 表示最左边的位置。 它是带符号的 CScriptNum 整数。 Position 必须按照 BIP62 中的描述进行最小编码,非负数,并且必须不大于树的 Depth 允许的最大项目数。 例如,如果 Depth 为 4,则 Position 的有效范围为 0 到 15 (24-1)。

Script Merkle Root 是由 ComputeMerkleRootFromBranch 函数计算的 Merkle 根,使用 Key Code HashPathPosition

如果 Script Merkle Root 与见证程序不匹配,则脚本评估失败。

Merklized Script Version 0

永久链接: Merklized Script Version 0

如果 Key Code 的第一个字节是 0,则将其解释为 Merklized Script Version 0 (MSV0) 并进一步处理。

Key Code HashPathPosition 从见证栈中移除。 剩余的栈必须至少有 1 个项目,否则评估失败。

最后一个见证栈项目是 nScriptWitCode,它必须是 0 到 5 的最小编码值,否则评估失败。

排除 nScriptWitCode 项目,剩余的栈项目数必须不小于值 nScriptWitCode,否则评估失败。

如果 nScriptWitCode 不为 0,则 nScriptWitCode 之前的见证项目是 scriptWitCode0scriptWitCode0 之前的项目是 scriptWitCode1,依此类推。 最高索引 scriptWitCode 的大小不得为 0(在这种情况下,应使用较小的nScriptWitCode 值,并省略大小为 0 的 scriptWitCode)。

未使用的栈项目(如果有)将被视为脚本评估的 Input Stack

scriptWitCode(如果有)会一个接一个地进行评估,从索引最高的那个开始。 scriptKeyCode 是删除了前导 0 版本字节的 Key Code。 所有 scriptWitCode 之后评估 scriptKeyCode

类似于评估旧版 scriptSigscriptPubKey

  • 脚本的结果栈会被下一个脚本继承
  • Altstack 在两个脚本之间重置为空
  • 条件操作(OP_IFOP_NOTIFOP_ELSEOP_ENDIF必须在每个脚本中单独平衡
  • 所有 scriptWitCodescriptKeyCode 必须不能失败

类似于评估版本 0 见证脚本:

  • 任何 Input Stack 项目的大小必须不大于 520 字节
  • 最终栈必须只包含一个 TRUE 项目
  • 在执行任何 Opcode 之后,栈和 altstack 项目的总数必须不高于 1000

在以下任一条件下,评估也必须失败:

  • 所有 scriptWitCodescriptKeyCode(不带前导 0 版本字节)的总大小大于 10,000 字节
  • 所有 scriptWitCodescriptKeyCode 的非推送操作(nOpCount)的总数超过 201。 值等于或高于 0x61 的每个 Opcode,除了 OP_CHECKMULTISIGOP_CHECKMULTISIGVERIFY 之外,都计为 1 个 nOpCount。 对于 m-of-n OP_CHECKMULTISIGOP_CHECKMULTISIGVERIFY,它们 被计为 m+1 个 nOpCount。 [ 1]

MSV0 中的新脚本功能

永久链接: MSV0 中的新脚本功能

新的脚本功能在 MSV0 中引入,在不同的 BIP 中描述。

BIPVVV 描述了 pay-to-witness-public-key (P2WPK),如果花费输出的唯一条件是来自单个公钥的签名,则这是一种使用 MSV0 所有功能的更有效方式。

BIPWWW 描述了重新启用和重新定义禁用的字符串和按位运算,包括 OP_CATOP_LEFTOP_RIGHTOP_SUBSTROP_INVERTOP_ANDOP_OROP_XOROP_RSHIFTOP_LSHIFT

BIPXXX 描述了重新启用和重新定义禁用的数值运算,包括 OP_2MULOP_MULOP_2DIVOP_DIVOP_MOD 以及重新定义现有的数值运算,包括 OP_CHECKLOCKTIMEVERIFYOP_CHECKSEQUENCEVERIFYOP_1ADDOP_1SUBOP_NEGATEOP_ABSOP_NOTOP_0NOTEQUALOP_ADDOP_SUBOP_BOOLANDOP_BOOLOROP_NUMEQUALOP_NUMEQUALVERIFYOP_NUMNOTEQUALOP_LESSTHANOP_GREATERTHANOP_LESSTHANOREQUALOP_GREATERTHANOREQUALOP_MINOP_MAXOP_WITHIN

BIPYYY 描述了 OP_CHECKSIGOP_CHECKSIGVERIFYOP_CHECKMULTISIGOP_CHECKMULTISIGVERIFY 的重新定义,以及新 OP_CHECKSIGFROMSTACKVERIFY 的引入。

BIPZZZ 描述了新 OP_PUSHTXDATA 的引入。

可升级性

永久链接: 可升级性

如果见证程序版本字节为 1,但程序大小既不是 32 也不是 33 字节,则脚本返回成功而不进行进一步评估。

对于 Merklized Script,如果 Script Merkle Root 匹配,但 Key Code 的第一个字节不是 0,则脚本返回成功而不进行进一步评估。

在这些情况下,SigOpsCost 计为 0。

原理

永久链接: 原理

最小 33 字节大小要求和对 Key Code 使用单 SHA256: 如果双 SHA256 用于哈希 Key Code 和 64 字节的连接 Merkle 哈希,如果任何连接的哈希是有效的 Key Code,则输出可能会被盗。 另一方面,如果单 SHA256 用于 Key Code,而双 SHA256 用于连接的 Merkle 哈希,如果任何连接的哈希的单 SHA256 是有效的 Key Code,则输出可能会被盗。 通过拒绝任何 32 字节的 Key Code,足以避免后一种情况。 然而,由于压缩公钥大小为 33 字节,因此很明显,任何小于 33 字节的 Key Code 要么无效,要么任何人都可以花费 [ 2]。 因此,拒绝任何小于 33 字节的 Key Code 不会损失任何功能。

Key Code 的开头标记 Merklized Script 版本: Merklized Script 版本可以在 scriptPubKeywitness 中标记,但 witness 占用的区块空间更少。 此外,在 Key Code 中标记意味着我们可以在一个输出中混合使用不同版本的脚本,如果隐藏了特殊脚本版本的使用,这可以提高隐私性。

scriptWitCode 设计: scriptWitCode 设计允许输出的密钥持有者包含其他脚本。 在 BIPYYY 中对其进行了进一步描述。

示例

永久链接: 示例

脚本 Merkle 根的计算

永久链接: 脚本 Merkle 根的计算

(待完成)

不平衡 MS

永久链接: 不平衡 MS

在构造 MS 时,如果用户认为某些分支更有可能被执行,他们可能会将它们更靠近 Script Merkle Root。 当实际执行首选分支时,它将节省一些见证空间。 例如,在支付通道构造中,“合作”脚本比“非合作”脚本更有可能被执行。

带超时的 Escrow

永久链接: 带超时的 Escrow

以下是 BIP112 中的“带超时的 Escrow”示例:

    IF
        2 &lt;Alice's pubkey> &lt;Bob's pubkey> &lt;Escrow's pubkey> 3 CHECKMULTISIG
    ELSE
        "30d" CHECKSEQUENCEVERIFY DROP
        &lt;Alice's pubkey> CHECKSIG
    ENDIF

使用压缩公钥,此脚本的大小为 150 字节。

使用 MSV0,此脚本可以分解为 2 个互斥的分支:[ 3]

    2 &lt;Alice's pubkey> &lt;Bob's pubkey> &lt;Escrow's pubkey> 3 CHECKMULTISIG (105 字节)
    "30d" CHECKSEQUENCEVERIFY &lt;Alice's pubkey> CHECKSIG (42 字节)

由于只会发布一个分支,因此区块链分析师更难确定托管的详细信息。

哈希时间锁合约

永久链接: 哈希时间锁合约

以下是 BIP112 中的“哈希时间锁合约”示例:

    HASH160 DUP &lt;R-HASH> EQUAL
    IF
        "24h" CHECKSEQUENCEVERIFY
        2DROP
        &lt;Alice's pubkey>
    ELSE
        &lt;Commit-Revocation-Hash> EQUAL
        NOTIF
            "Timestamp" CHECKLOCKTIMEVERIFY DROP
        ENDIF
        &lt;Bob's pubkey>
    ENDIF
    CHECKSIG

使用 MSV0,它被展平为 3 个互斥的分支:

    HASH160 &lt;R-HASH> EQUALVERIFY "24h" CHECKSEQUENCEVERIFY &lt;Alice's pubkey> CHECKSIG
    HASH160 &lt;Commit-Revocation-Hash> EQUALVERIFY &lt;Bob's pubkey> CHECKSIG
    "Timestamp" CHECKLOCKTIMEVERIFY &lt;Bob's pubkey> CHECKSIG

这大大提高了可读性,并减少了赎回时的见证大小。

大型多重签名结构

永久链接: 大型多重签名结构

当前的 OP_CHECKMULTISIG 最多支持 20 个公钥。 尽管可以通过使用多个 CHECKSIG 将其扩展到 20 个密钥以上,但构造可能非常复杂,并且很快就会用完 10,000 字节和 201 个 nOpCount 限制。

使用 MSV0,大型且复杂的多重签名结构可以展平为许多简单的 OP_CHECKMULTISIG 条件。 例如,3-of-2000 多重签名方案可以表示为 1,331,334,000 个 3-of-3 OP_CHECKMULTISIG, 形成一个 31 级 MS。 scriptPubKey 仍然保持 34 字节的固定大小,并且赎回见证将非常紧凑,小于 1,500 字节。

额外数据的承诺

永久链接: 额外数据的承诺

目前,在 scriptPubKey 中提交额外数据需要使用 OP_RETURN,这会占用额外的区块空间。 使用 MS,用户可以将此类数据作为分支提交。 根据可执行分支的数量,包含此类承诺可能不会产生额外的见证空间,或者最多 32 个字节。

一个有用的案例是指定“消息签名密钥”,这些密钥对于花费无效,但允许用户在不接触冷存储“资金密钥”的情况下签署任何消息。

向后兼容性

永久链接: 向后兼容性

作为软分叉,旧软件将继续运行而无需修改。 但是,未升级的节点会将 Merklized Script 和 P2WPKV0 程序视为任何人都可以花费的脚本。 钱包应始终警惕任何人都可以花费的脚本,并谨慎对待它们。

部署

永久链接: 部署

确切细节待定。

鸣谢

永久链接: 鸣谢

Merklized script 基于 Merklized Abstract Syntax Tree 的思想,该思想起源于 Russell O’Connor、Pieter Wuille 和 Peter Todd

参考实现

永久链接: 参考实现

https://github.com/jl2012/bitcoin/commits/vault

参考

永久链接: 参考

版权

永久链接: 版权

本文档已获得 BSD 3-clause 和 Creative Commons CC0 1.0 Universal 的双重许可。

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

0 条评论

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