错误信息
Address does not refer to key
也可能输出为
- error code: -3 error message: Address does not refer to key
`bitcoin-cli` 会在这段文本之前的几行打印“error code: -3”和“error message:”。JSON-RPC 客户端看到的是 `{"code": -3, "message": "Address does not refer to key"}`。
Bitcoin Core RPC — verifymessage / signmessage with a non-P2PKH address
含义
Bitcoin Core 的消息签名(`signmessage`/`verifymessage`)实现的是最初的“Bitcoin Signed Message”方案,它只适用于传统的 P2PKH 地址:从签名中恢复出公钥,Core 再将其哈希与地址比较。原生 SegWit(`bc1q…`)、Taproot(`bc1p…`)和 P2SH(`3…`)地址都不是这种意义上的“密钥”地址,因此 Core 会以 RPC 错误 -3 拒绝它们,而不是返回 true 或 false。
原因
原生 SegWit 地址
常见如今大多数钱包默认使用 `bc1q…` 地址。交易所和储备金证明流程如果要求用这类地址签名一条消息,就无法使用 Core 的传统方案。
Taproot 或 P2SH 地址
偶见`bc1p…` 和 `3…`(嵌套 SegWit、多重签名)地址没有单一的公钥哈希可供 Core 比较。
其他钱包为 SegWit 地址生成的签名
偶见Electrum、Trezor 等钱包要么为 SegWit 扩展了传统格式(BIP-137 头部字节值 35~42),要么使用 BIP-322。Core 的 `verifymessage` 两者都不接受。
修复方法
- 1.
在 Core 中用传统地址签名
如果对方只需要证明你控制着钱包中的某个密钥,就专门为此创建一个传统地址。
bash # Bitcoin Core signs and verifies messages only for legacy P2PKH addresses (1... / m... / n...) addr=$(bitcoin-cli getnewaddress "proof" legacy) sig=$(bitcoin-cli signmessage "$addr" "I own this address") bitcoin-cli verifymessage "$addr" "$sig" "I own this address" - 2.
SegWit 和 Taproot 地址使用 BIP-322
BIP-322 为所有地址类型定义了消息签名。使用实现了它的库或钱包,并与验证方约定采用该方案。
js // SegWit / Taproot addresses: BIP-322 "simple" signatures, e.g. with the bip322-js library import { Verifier } from "bip322-js"; const ok = Verifier.verifySignature("bc1q...", "I own this address", signatureBase64);