每一笔 Blocknet 付款都可以附带一条简短的加密备注。你可以用它写账单号、订单号,或者给收款人留言,而且只有你们两人能读到。本指南介绍发送 BNT 时如何添加备注、谁能读取备注、为什么备注在链上从不显眼,以及在哪里查看你收到的备注。
什么是 Blocknet 备注?
Blocknet 备注是附加在每个交易输出上的一个 128 字节加密字段。它最多可容纳 124 字节你自己的文字或数据,比如账单号或一句简短留言。它使用只有发送方和接收方共享的秘密加密,并经过填充,让空备注看起来和写满的备注一样。
备注是交易格式本身的一部分。链上的每个输出都有一个备注,包括把币找回到你自己钱包的找零输出。这带来三个实用的特性:
- 默认私密。 内容针对该输出的接收方加密,其他人看不到你写了什么。
- 固定大小。 无论你写了什么,这个字段在链上始终是 128 字节。
- 始终存在。 由于每个输出都带有备注,带留言的付款和不带留言的付款看起来完全一样。
备注里可以写什么?
任何能放进 124 字节的内容。纯文本以 UTF-8 存储,所以英文可以写 124 个字母、数字和空格。拉丁字母以外的字符占用更多字节:一个汉字占三个字节,因此一条备注大约能写 41 个汉字。
常见用途:
- 账单。 把账单号写进备注,收款人无需询问就能把这笔付款对应到正确的账单。
- 订单号。 商店或服务可以请顾客附上订单号,然后直接从收到的付款中读取。
- 留言。 “十一月房租”“谢谢帮忙”“晚饭 AA”这样的话可以随币一起送达。
- 二进制数据。 钱包也接受以十六进制书写的原始字节,适合由软件生成和读取的参考代码。
发送 BNT 时如何添加备注?
在命令行钱包中,把备注写在金额后面:send @rock 100 “invoice 1042”。钱包会在确认界面上把备注和手续费一起显示出来,针对接收方加密,并在你确认后发送付款。原始字节也可以发送,只需加上 hex: 前缀。
钱包的 send 命令把备注作为可选的最后一个参数:
send <address> <amount> [memo|hex:<memo_hex>]
备注可以包含空格,两边的引号可加可不加。钱包会在加密前去掉一对匹配的引号。下面是一笔附带账单号、付给 Blocknet ID 名称的付款:
> send @rock 100 "invoice 1042"
Resolved @rock -> <address> ✓ verified
# Send
Building transaction...
Send 100 BNT to @rock?
Fee: <fee>
Address: <address>
Memo: "invoice 1042"
Confirm [y/N]: y
确认步骤会显示接收方将读到的备注,所以你可以在发送之前核对备注。如果备注超过 124 字节,钱包会在构建交易之前停下并提示 memo too long: max 124 bytes,你缩短后再试一次即可。
要发送原始字节,请在备注前加上 hex:。钱包会解码十六进制并加密这些字节:
send @rock 100 hex:494e562d31303432
付款链接也可以携带备注。把 blocknet:// 链接或 bntpay.com 链接粘贴到钱包中,它会为你填好地址、金额和备注,等你确认,因此收款人可以事先设好账单号。关于名称和链接的更多内容,请阅读 Blocknet ID 指南。
从你自己的软件添加备注
钱包 API 允许为一次发送中的每个收款人分别设置备注。在发往 POST /api/wallet/send 的请求中,为每个收款人提供 memo_text(纯文本)或 memo_hex(原始字节)中的一个:
{
"recipients": [
{ "address": "@rock", "amount": 10000000000, "memo_text": "invoice 1042" },
{ "address": "$shop", "amount": 2500000000, "memo_hex": "4f524445522d3737" }
]
}
这里的金额以原子单位表示,1 BNT 等于 100,000,000 个单位,所以这个示例分别发送 100 BNT 和 25 BNT。每个收款人都有自己的备注,只针对他们自己的钱包加密。同样适用 124 字节的上限。
谁能读取 Blocknet 备注?
发送方和接收方。每条备注都使用两个钱包针对该输出共享的秘密加密,这个秘密也正是生成接收方一次性隐身地址的那个秘密。其他任何人,包括节点运营者和区块浏览器,看到的都只是 128 字节看似随机的数据,也无法判断里面是否有留言。
你的钱包构建付款时,会把一个新生成的随机交易密钥与接收方的公开查看密钥结合,得到一个共享秘密。正是这个秘密生成了接收方的一次性隐身地址,钱包也用它来加密备注。钱包把这个秘密连同该输出在交易中的位置和网络标识符一起用 SHA3-256 哈希,生成一个 128 字节的掩码,再把掩码与备注结合。每个输出都有自己的掩码,所以同一笔交易中的两条备注是分别加密的。
接收方的钱包在扫描每个区块时,用自己的私有查看密钥从另一端算出同一个秘密。它解密备注,并把备注和这笔付款保存在一起。在你这一端,钱包会在发送记录中保留你写过的备注。
有两点值得了解:
- 只读钱包也能显示备注。 读取收款靠的是你的私有查看密钥,所以用它创建的只读钱包能看到每笔付款的金额和备注。请只把这个密钥分享给你愿意让其查看收款的人。
- 挖矿奖励的备注为空。 共识规则要求每个区块奖励的备注必须为空,因此链上的 coinbase 输出永远不能被用作公开的消息通道。
为什么每条备注在链上看起来都一样
如果备注暴露了自身长度,就会泄露信息。30 字节的留言和 100 字节的留言看起来不同,空备注又会和两者都不一样。Blocknet 钱包用固定布局和随机填充解决了这个问题。
加密之前,钱包会把备注打包进一个 128 字节的信封:
| 字节数 | 内容 |
|---|---|
| 1 | 信封版本 |
| 1 | 备注长度 |
| 2 | 备注校验和 |
| 0 到 124 | 你的备注 |
| 其余部分 | 随机填充 |
填充来自系统的密码学随机数生成器,因此未使用的空间无法预测。加密之后,短留言、写满的留言和空备注都是 128 字节看似随机的数据。找零输出也会带上自己的空备注并经过填充,所以就连你找回给自己的币也同样不显眼。
校验和让接收方的钱包在显示备注之前确认解密正确。节点还会拒绝任何包含备注字段全为零的输出的区块,因此链上的每个输出都带有正确填充的备注。
在哪里查看收到的备注
命令行钱包在列出付款的地方都会显示备注:
history列出收入和支出的付款,带有备注的付款下方会有一行memo:。outputs tx <txid>显示你的钱包在该交易中拥有的每个输出,包括备注。outputs <n>对列表中的单个输出做同样的事。- 钱包 API 通过
GET /api/wallet/history以memo_hex返回每个收到的输出的备注,可直接供订单系统与账单对账。
文本备注会显示在引号中。不是可打印文本的备注,比如用 hex: 发送的原始字节,会以十六进制显示。
如果某笔付款需要核实,发送方可以证明它。钱包的 prove <txid> 命令会显示你发出的某笔付款的交易密钥。任何人只要有这个密钥、交易 ID 和接收方地址,就可以通过 POST /api/verify-proof 端点核实这笔付款,无需钱包。它会确认这笔交易,并显示该地址收到的输出、金额和备注。
挖到你要发送的 BNT
获得第一批 BNT 的一个简单方法就是挖矿。seine 在你自己的电脑上运行,边挖边自动调优,并通过 bntpool.com 直接把收益支付到你的地址或 @name。挖矿指南几分钟就能让它运行起来。
常见问题
Blocknet 备注最长可以有多长?
一条备注最多容纳 124 字节。纯文本以 UTF-8 存储,所以英文可以写 124 个字母、数字或标点;中文每个字占三个字节,大约可以写 41 个汉字。备注超长时,钱包会在构建交易之前就拦下它,并提示 124 字节的上限。
区块浏览器能读取 Blocknet 备注吗?
不能。浏览器只会把备注字段显示为 128 字节的密文,并标注为已加密。密钥来自发送方和接收方针对该输出共享的秘密,因此只有他们两人的钱包能打开。由于每条备注都会填充到完整长度,浏览器甚至看不出哪些输出带有备注。
备注会让 Blocknet 交易变大吗?
不会。无论你是否写了备注,每个输出本来就带有一个 128 字节的加密备注字段。添加备注只是填入原本就存在的空间,所以带账单号的付款和不带账单号的同一笔付款大小完全相同,在链上看起来也一模一样。
向 Blocknet ID 名称付款时可以加备注吗?
可以。把名称填在地址的位置,把备注写在金额后面,例如 send @rock 100 "invoice 1042"。钱包会解析名称,显示已验证的地址、手续费和备注,然后请你确认。备注会针对该名称所指向的钱包进行加密。