金额为假设;未生成可支付二维码。标签不能作为身份认证。
金额为假设;未生成可支付二维码。标签不能作为身份认证。

图片资料:官方来源

查看完整图片 ↗

比特币支付链接和二维码里常见的 bitcoin: 开头字符串,属于 BIP21 定义的 URI 方案。BIP21 状态为 Closed,已被 BIP321 取代;但旧链接、旧二维码和部分钱包的兼容入口仍会沿用这种格式。本文只处理这类传统链接中 amount、地址、label 等字段的核对方法,不展开 BIP321 的新功能。

先拆开一条URI

假设看到这样一条演示字符串(地址为不可支付占位符):

bitcoin:1PlaceholderAddressNotPayable?amount=0.0005&label=DemoShop&message=Order%20123

可以分成三块:

  • bitcoin::方案名,大小写不敏感;
  • 1PlaceholderAddressNotPayable:收款地址,位于问号之前;
  • amount=0.0005&label=DemoShop&message=Order%20123:查询参数,用 & 分隔。

核对时,地址和金额要分开看。地址决定币付给谁,金额决定付多少,两者互不替代。

amount的单位是BTC

BIP21 规定,amount 必须以十进制 BTC 表示,整数与小数之间用英文句点,不能带千位逗号。amount=50.00 和 amount=50 都表示 50 BTC;amount=50,000.00 属于无效写法。

换算时按假设算例:0.0005 BTC = 50,000 sat,因为 1 BTC = 100,000,000 sat。若钱包界面显示 50000 sat 或 0.0005 BTC,两者一致。若显示 0.5 BTC 或 500,000 sat,前者是正确值的 1000 倍,后者是 10 倍,都应停下重新核对。常见的偏差还包括钱包把 BTC 换算成 sat 显示、金额被四舍五入到界面位数,以及链接本身没有 amount、需要手动填写。前两种要看清单位标签,第三种则不能把“空白金额”当成“零元”。

label不是身份认证

label 只是给地址附加的说明文字,例如收款方名称;message 是给付款人看的备注。它们都属于 URI 里的可读字段,不构成身份认证,也不证明地址属于某个商户。地址本身才是支付对象。

同理,扫码不等于授权付款。BIP21 要求客户端在未获用户授权时不得执行 URI,通常应让用户逐笔确认。二维码被替换、链接被篡改时,label 仍可能显示成熟悉的名字,所以核对重点是地址与金额,而不是标签文字。

费用另算

URI 中的 amount 是付给收款地址的金额,不包含矿工费或钱包服务费。实际扣款可能高于 amount,具体取决于钱包的费用设置和交易大小。看到“应付 0.0005 BTC”时,应把预计手续费加进去再判断余额是否足够。

核对顺序

  1. 确认地址完整,没有被截断或替换;不要只比对首尾几位。
  2. 确认 amount 使用句点、无逗号,并按 BTC 理解。
  3. 换算 sat 后与钱包显示的单位逐位对照。
  4. 把 label 当备注,不当身份凭证。
  5. 在钱包确认页再次核对地址和最终扣款总额,费用单列。
  6. 若链接带有 req- 前缀参数而当前钱包并不支持,按 BIP21 规则整个 URI 应视为无效;钱包实现了该参数则另当别论,不能只看前缀就一概拒绝。

旧格式仍会出现,核对逻辑不变:地址看对、金额看单位、标签不当真、费用另算。

资料来源