描述符的核心卖点本是”从密钥推导脚本”——但有一批需求根本不带密钥:手上只有一个别人给的历史地址、只有一段从旧备份里翻出的脚本十六进制,想把这些目标交给节点扫描或工具索引。BIP-385 给这类需求配了两个”包装函数”:raw() 把任意十六进制输出脚本、addr() 把任意地址,原样装进描述符语法。状态 Deployed,Bitcoin Core 自 0.17 支持。描述符的基本语法读 ‘BIP380输出描述符语法怎么读?’ 即可,本文只讲这对包装函数的分工与陷阱。
两个包装器的分工
raw 的参数是一段十六进制,它代表的脚本会被逐字节当作输出脚本使用——脚本内容可以完全不合常规,校验只看”是不是合法十六进制、长度是否与声明匹配”。addr 的参数是一个比特币地址,描述符产出该地址对应的输出脚本,等价于先按地址格式规则解码再交给脚本生成。选型规则很短:有脚本原文用 raw,只有地址用 addr,两者结果应当一致时可互换;地址解码失败(比如校验字符错了一位)时 addr 写法直接报错,反而比”先手工解码成十六进制再塞 raw”更安全——少一次人工转换就少一次抄错的机会。校验码如何逮住抄错的细节见 ‘钱包恢复时少了一串地址:派生路径、扫描窗口与找零导致的两种看不见’。
硬边界:只能顶层,不许嵌套
规范明确两者都只能作为整条描述符使用。sh(raw(…)) 或 wsh(addr(…)) 这类写法被列为非法——包装器的语义是”这整条脚本我不推导了”,而 sh/wsh 的语义是”往里装再套一层哈希”,两套语义打架,规范直接禁止。想表达”某脚本哈希下还有一层”,正确路线是老老实实写 sh(witness_script(…)) 或对应真实结构的表达式,而不是把包装器塞进去。工具报解析错误时,先查是不是有人试图嵌套。
扫描可得、签名不可得
描述符在节点里有两种消费方式:索引扫描(这个脚本下有什么历史)与签名供给(花这里的钱时从描述符取密钥)。raw 与 addr 包装的对象大多不含你自己的密钥,于是天然只能服务前者:你可以把它们导入钱包做观察(与 ‘importdescriptors如何导入观察钱包?’ 讲的观察钱包思路相同,只是入口从 xpub 换成了现成脚本/地址),查得到余额与交易,发起支付时节点会明确报”没有密钥可签”。把”导入成功”误读成”可以动用”,是对这两个包装器最危险的误解。
活动查询的组合用法
节点上”这个描述符名下有没有活动”的查询命令会把表达式展开后逐脚本查索引,用法在 ‘getdescriptoractivity怎么用?’ 讲过。raw/addr 是这条链路的万能适配器:无论目标最初是地址字符串、脚本十六进制还是异种工具导出的片段,先包装成合法描述符,才能喂给描述符系工具。审计场景常见的三步是:拿到目标地址、addr 包装、跑活动查询核对——全程不导入任何私钥,攻击面最小。
一个容易混淆的对照:包装器与观察钱包不是一回事
两者都”不带私钥”,但信任假设不同:用 xpub 建观察钱包时,地址仍由你自己从公钥派生,软件只负责查;用 addr 包装时,脚本内容本身是外部输入,工具连”这个地址结构合不合法、逻辑上归谁管”都不判断。换句话说,xpub 路线的可信环节是”派生对不对”,包装器路线的可信环节是”材料来没来对”。审计脚本里这两类目标要分开登记,复盘时才知道某笔漏查是派生配置错还是材料抄错。
使用纪律三条
第一,来源核对优先:addr 里的地址、raw 里的十六进制都必须来自你亲手复制并有出处记录的材料,包装动作不会给内容增加任何可信度。第二,长度与字节序自查:raw 的参数是脚本的序列化十六进制,从第三方工具复制时留意对方是否把长度前缀、签名字段一并塞进来,与链上真实脚本逐字节比对一次再入库。第三,把包装描述符标记为”只读目标”:在自己的台账里给它们打上只读标签,避免几个月后自己都忘了这些地址根本动不了,白白在签名环节浪费时间。
发表评论
还没有评论,来说两句吧。
评论区为展示样式,提交不会被处理。