术语表 /协议与升级
脚本路径花费
- 脚本路径花费是什么?
- 脚本路径花费通过披露一个叶子脚本、满足该脚本的输入以及一个证明该地址已承诺此叶子的控制块,来解锁 Taproot 输出。
规定于 BIP-341。
脚本路径花费是花费 Taproot 输出的后备路径,用于各方原本期待的协作签名始终没有出现的情形。证明数据放在控制块中,控制块为33字节,树的每多一层再增加32字节,而 BIP-341将该树限制在128层以内。走这条路径会公开您所使用的分支,因此您实际依赖的那个条件不再是私密的。
运作方式
节点在验证脚本路径花费时,会从后往前读取见证栈,因为最后一个元素承担了大部分工作。
最后一个元素就是控制块,其长度会最先被检查。它必须恰好为33 + 32m 字节,其中 m 为介于0和128之间的整数,任何其他长度都会直接验证失败。BIP-341将上限设为128,是因为经过最优打包的树只有在某个叶子被使用的概率低于1/2^128时才会更深。
第一个字节包含两项互不相关的内容。用0xfe 对其做掩码,得到的是叶子版本,0xc0 对应 tapscript 规则;被掩掉的那一位是输出密钥 Y 坐标的奇偶性,设置它是为了让该花费可以批量验证。接下来的32个字节是内部公钥,即本应对协作花费签名的那把公钥;其后的全部内容是默克尔路径,每层占32个字节。
随后节点重建承诺。它将叶子版本与披露的脚本一起哈希,得到 tapleaf 哈希,再依次并入路径中的每个元素。方向从不传输:每一步的两个32字节值在哈希前按字典序排序,因此由比较结果决定顺序,不发送任何方向位。默克尔根与内部密钥生成一个调整值(tweak),调整后的密钥必须与地址中的32个字节一致,包括奇偶位,脚本才允许运行。
一个字节就可能改变它之前的一切。如果见证包含至少两个元素,且最后一个元素以0x50 开头,该元素会在验证开始前作为附注(annex)被剥离。BIP-341没有为它定义任何含义,并警告说包含附注可能导致"PERMANENT FUND LOSS"。
在哪里会遇到它
在区块浏览器上,脚本路径花费表现为这样一种 Taproot 输入:其见证在不计附注的情况下包含多于一个元素。
BIP-341自带的示例是一棵由五个脚本(A 至 E)组成的树。使用脚本 D 花费时,会公布 D,以及一个包含内部密钥和三个哈希的控制块:C、E,以及 A 与 B 的组合哈希。对于一个含五个条件的合约,该控制块为129字节,其余四个脚本从不公开。
这份证明也会泄露一些信息。BIP-341的安全部分指出,所披露叶子的深度会泄露该树的最小深度,这"suggests specific wallet software that created the output and helps clustering"。BIP-341建议的防范办法是偏离叶子概率本来会使之达到最优的那棵树。
同一部分对密钥复用的态度很明确。所有叶子上的密钥都必须是全新的,而不只是您花费的那一片,因为重复的分支会在之后的证明中以重复的哈希再次出现,而共用密钥的叶子会使未披露的脚本更容易被暴力破解。
脚本路径花费 vs Tapscript
脚本路径花费是路径,tapscript 是路径尽头所使用的语言。BIP-341定义了执行开始之前的一切:控制块、排序后的默克尔折叠、调整值检查、奇偶位。之后运行什么,由叶子版本决定。
目前只有0xc0 表示 tapscript。携带任何其他版本的叶子并不算错误,因为 BIP-341要求对未知叶子版本的执行必须成功。这正是让日后的软分叉能够在同一种 bc1p 地址格式内定义另一种脚本语言的接口,也使脚本路径花费成为这一组合中更持久的一半。