Witness Data 是附在交易输入上的数据,用于验证 SegWit 的花费条件。输入指向此前收到、现在要花费的币。Witness 可以包含签名、公钥或脚本。它属于交易本身,并不是另一个存放资金的地方。
安娜此前收到 Bitcoin,现在想用它付给彼得。原来的付款创建了一个输出,记录金额以及日后花费的条件。新交易通过输入引用这个输出。但仅仅声称币属于安娜还不够。普通付款时,钱包生成一个签名,别人不必知道私钥就能验证它。钱包是接收和发送比特币的应用程序或设备。私钥是用于生成这种签名的秘密数值。在 SegWit 格式中,这些验证数据作为该输入的 witness 提交。不过,有签名并不意味着签名正确。 [1] [4] [5]
可以想象“出示有效证件”的要求与实际拿出的证件之间的区别。Bitcoin 没有人工裁判,而是通过规则检查两者是否相符。Witness program 是此前输出所记录条件的一部分,其版本决定验证方式。Witness 则由后来花费该输出的新交易提供。从技术上说,它是每个输入对应的一组有序数据项,并不自动等同于可执行程序,也不是所有未花费币的副本。 [1] [7]
Witness 可能公开签名、公钥或实际使用的脚本;脚本是描述花费条件的程序。公钥用于验证签名,不需要保密。它不是加密信箱。私钥留在你手里,用来签名,而不是代替签名被发送到网络。Witness 和公开签名都不能替代 Seed Phrase,也就是用于恢复钱包的一组词。如果私钥和备份都丢了,仅凭公开付款历史,无法重新获得为后续转账签名的能力。 [1] [3] [4]
区块浏览器是用于查询特定网络上的交易和区块的应用。区块浏览器可能同时显示 txid 和 wtxid。它们都是哈希,即对精确的数据表示连续应用两次 SHA-256 得到的简短指纹。txid 使用不含 witness 的表示,wtxid 使用含 witness 的完整表示。它们不是收款地址,也不是两笔不同付款。交易没有 witness 时,使用原有格式,两者相同。在 Bitcoin Core v29.0 中,decoderawtransaction 的 hash 字段给出完整标识符,输入的 witness 数据可见于 txinwitness。 [1] [7] [8]
一笔交易可以在另一笔交易确认前就引用它。如果有人仅通过修改签名数据就能改变前一笔交易的标识符,引用就对不上了。只修改 witness 不会改变 txid,这有助于使用相互依赖交易的协议,例如 Lightning Network。但这不保证整笔交易不可修改。其他字段或非 SegWit 的旧式输入仍可能影响 txid,改过的 witness 也仍须符合相应验证规则。 [1] [6]
完整交易表示传输时会携带 witness,交易被收录后,它属于区块数据。它不是免费的链外存储。witness 序列化新增的一个字节计为 1 WU,基础数据字节计为 4 WU;WU 是权重单位。Full Node 独立检查规则,需要相应数据来验证花费。较低的权重既不允许跳过必要检查,也不意味着数据不占存储空间。 [1] [7]
在旧格式中,花费证据写在 scriptSig 字段。原生 SegWit 版本 0 要求该字段为空,所需证据位于 witness。还有一种封装在 P2SH 中的形式;P2SH 是按照脚本哈希指定支付条件的旧方法。在这种形式中,scriptSig 必须恰好压入相应的 witness program,不能任意附加指令。花费证据仍在 witness。同一种目的可以有不同表示,不能只凭字段名理解它。 [1] [5]
P2WPKH 提供签名与公钥,节点检查公钥哈希是否符合原有条件,以及签名是否有效。P2WSH 支持由整个脚本哈希指定的条件。最后一个 witness 数据项称为 witnessScript,其哈希必须匹配输出中的程序;此前的数据项为脚本执行提供初始数据,例如签名。BIP 143 规定此版本的待签名消息如何构成,其中包括被花费输出的金额。仅仅成功读取数据,并不证明条件已经满足。 [1] [2] [5]
Taproot 使用原生 witness 版本 1,区分密钥路径和脚本路径。判断路径前,会先移开可能存在的 annex 这一特殊附加字段;它的数据仍计入权重,也仍被签名覆盖。若只剩一个数据项,就按密钥路径签名解释。脚本路径公开所使用的脚本及 control block,后者是证明脚本与原输出存在联系的数据,并不是新的区块链区块。若前面还有数据项,则为脚本提供输入数据。版本 0 的规则不能直接照搬。 [3] [5]
密码学承诺(commitment)是一种将数据与其具体内容绑定的指纹。需要对 witness 数据作出这种承诺时,BIP 141 通过 Coinbase Transaction 将这些证据与区块其余部分联系起来;这是用于矿工奖励的第一笔交易。由 wtxid 哈希组成的树产生一个根,概括包含的数据。奖励交易在该树中使用全零的 wtxid。根与一个保留的 32 字节值组合,再进行两次哈希,得到记录在其输出中的承诺。若所有交易都没有 witness,承诺是可选的。它用于绑定公开证据,不是密钥备份,也不能替代实际验证。 [1]
要获得更完整的理解,请将本词条与以下词条结合阅读: SegWit, Block Weight, Bitcoin Script, Taproot, Bitcoin, Seed Phrase. 反向关联还来自: Block Weight, Miniscript, Compact Block Filters.