协议演进 / BIP/比特币改进提案 / BIP-329
BIP-329
用 JSON Lines 为交易、地址、公钥、输入、输出、xpub 等记录定义统一的标签导出格式,让标签能在钱包之间迁移。本 BIP 目前处于草案状态。
一、档案卡
| 编号 | BIP-329 |
|---|---|
| 标题 | Wallet Labels Export Format |
| 作者 | Craig Raw <[email protected]> |
| 指定日期 | 2022-08-23 |
| 层级 | Applications(应用) |
| 类型 | Informational(信息类) |
| 状态 | Draft(草案) |
| 阅读版 | https://bips.dev/329 |
| 官方原文 | https://github.com/bitcoin/bips/blob/master/bip-0329.mediawiki |
二、放在哪一族
钱包互操作族。资金本身的迁移早已有成熟标准——助记词、扩展密钥与派生路径一整套,本篇在档案卡的相关文档中对应的是:
BIP-39:助记码
BIP-32:分层确定性钱包
BIP-44:确定性钱包的多账户层级
BIP-380:输出脚本描述符通用操作,本篇的可选 origin 字段用它的缩略描述符语法
BIP-392:静默支付输出脚本描述符,本篇 spscan 类型的引用格式由它定义
这些标准让用户能自由换钱包,却都不管“标签”这类钱包元数据。BIP-329 补的正是这一块:它站在既有格式(SLIP-0015、Electrum 的标签 JSON)的经验之上,给出一个自描述、可独立使用的统一格式。
三、它要解决什么
用户会给钱包里的交易、地址、公钥、输入、输出、xpub 等记录打标签。在 UTXO 模型下,标签格外有价值:它标明资金来源——是外部收到的,还是上一笔交易的找零。花钱时若不小心把不同来源混在一起,会造成不必要的隐私泄露,因此标签对选币有实际指导作用;在一些钱包中,标签甚至已成为花费前必须参考的信息。
但此前没有定义好的标准来迁移标签:换钱包,标签就丢了,用户实际上被锁定在原来的钱包应用里。此外,许多钱包还允许把某个未花费输出冻结为不可花,这类与标签性质相近的钱包元数据同样无处安放,本格式一并收纳。
原文也交代了为何不直接沿用既有格式:SLIP-0015 定义了地址与输出标签的导出格式,但要求用与钱包种子关联的私钥加密,无法被接触不到私钥的协调类钱包独立使用;Electrum 的标签 JSON 格式可以扩展到其他记录类型,但格式本身不自描述,难以判定记录类型。
四、规则本身
4.1 载体:JSON Lines
格式选用 JSON,并采用 JSON Lines(换行分隔的 JSON):导出文件是 UTF-8 编码的文本文件,每行一条记录、每条是一个合法 JSON 对象,行间以 \n 分隔,值不得跨多行。这样文件可以被切分、流式处理或增量追加,单行格式错误也不会让整份导入失效,也便于命令行按行处理。
4.2 每条记录的字段
每个 JSON 对象包含 3 到 4 个键值对:
type:记录类型,取值之一为tx、addr、pubkey、input、output、xpub、spscan;ref:对具体记录的引用,如交易 ID(十六进制)、地址(base58 或 bech32)、公钥(十六进制),输入与输出则写成“交易 ID:下标”,xpub 为 BIP-32 扩展公钥,spscan 为静默支付扫描密钥表达式;label:用户打的标签;origin(可选):密钥来源信息;spendable(可选):true或false,表示该输出是否应可被钱包花费。
其中 type 与 ref 必填;label、origin、spendable 可选。若 label 或 spendable 被省略,导入方不得改动原有对应值。spendable 只应出现在 type 为 output 的记录上。
4.3 origin 的写法
origin 若出现,必须是一个缩略的输出脚本描述符(按 BIP-380 定义),描述一个兼容 BIP-32 的来源钱包:包含全部密钥来源信息,但不含任何实际密钥、不含子路径元素、不带校验和。它的用途是在同一份导出里区分来自不同钱包的交易标签,尤其适用于从同一种子派生出多个账户的情形。
4.4 可选的附加字段
在最低限度的标签之外,规范还列了一组可选字段,供导出方在数据现成时一并给出(例如交易的区块高度、时间、手续费、金额、汇率,地址与输入输出的密钥路径、金额、公允价值等),方便导入工具直接使用这些难以事后重建的信息。其中高度字段有特别约定:交易确认不足 6 个区块时应省略高度或填 0,以免把可能因重组而变动的高度当成定数。
4.5 导入与隐私注意事项
导入方可以忽略自己不存储的记录,必要时可截断标签(建议默认上限 255 个字符,截断时应考虑提醒用户);导入公钥记录时可由公钥推导地址再与已知地址匹配;导入 xpub 时可与多签设置中的签名者匹配。对未在本规范定义的类型,合规的导入方应忽略。
标签数据隐私敏感:原文要求在不可信网络上传输时强烈建议加密,静态存储时也应考虑加密,未加密的导出应尽快删除。出于安全原因,格式不定义任何私钥类型。
五、谁必须动
普通持币人:受益者。钱包支持本格式后,换钱包时可把标签与冻结状态一并导出、导入,不再被单一应用锁定;同时要按原文提醒保管好导出文件,它本身就是敏感数据。
钱包开发者:导出方按 JSON Lines 写出合规记录,导入方按上述规则宽容处理(忽略不认识的记录与类型、缺省字段不覆盖、截断要提醒)。格式天然可扩展到其他记录类型。
全节点与矿工:无事可做。这纯粹是钱包本地数据的交换格式,不上链、不进网络协议。
共识层:不涉及。
六、现在算不算数,以及一个常见误读
状态为 Draft(草案),类型为 Informational(信息类)。它还是一份草案阶段的格式建议:不强制任何钱包实现,也不保证任意两个钱包今天就能无缝互导标签。原文给出了参考实现(Python-BIP329 包),但没有给出钱包采用情况的清单,本页不臆测。
常见误读:
“BIP-329 的导出文件里可以带上私钥或种子,方便一次性搬家。”
不对。原文明确:出于安全原因,不定义任何私钥类型。导出的只有标签、origin 描述与 spendable 这类元数据;资金本身的迁移仍走 BIP-39、BIP-32 等既有标准,两条线不要混为一谈。
七、延伸
- 阅读版:https://bips.dev/329
- 官方原文:https://github.com/bitcoin/bips/blob/master/bip-0329.mediawiki
- 相关:BIP-32 分层确定性钱包、BIP-380 描述符通用操作、BIP-392 静默支付描述符
- 仓库总目录:https://github.com/bitcoin/bips
