首页
/ Bitcoin Core 23.0 版本发布全解析:网络、钱包与 RPC 的里程碑式更新

Bitcoin Core 23.0 版本发布全解析:网络、钱包与 RPC 的里程碑式更新

2026-09-06 18:42:03作者:宣聪麟

本指南以 Bitcoin Core 23.0 官方发布说明(doc/release-notes/release-notes-23.0.md)为主线,逐一解析该版本在 P2P 网络、手续费估算、钱包、RPC、配置项与系统兼容性等维度的核心变更,并结合本仓库源码与测试给出实现层面的佐证。读完本篇,你将掌握 23.0 相对旧版本的差异要点、升级迁移时的注意项,以及 descriptor 钱包、Taproot、BIP-350 Bech32m、CJDNS 等新能力下的正确使用姿势。

升级与兼容性须知

如何从旧版本升级

Bitcoin Core 23.0 的升级遵循标准的二进制替换流程:

  1. 先完全关停正在运行的旧版本节点(bitcoind / bitcoin-qt);
  2. 等待进程完全退出——在数据量大或磁盘较慢时,安全关停可能需要数分钟,请务必耐心等待而不要中途强制结束;
  3. 覆盖安装新版本:
    • Windows:运行新版安装程序;
    • macOS:替换 /Applications/Bitcoin-Qt
    • Linux:替换 bitcoind / bitcoin-qt 可执行文件。

即使从已经到达生命周期终点(EOL)的旧版本直接升级也是可行的,但如果数据目录需要迁移(例如钱包文件格式升级),启动阶段可能耗时较长。旧版钱包格式通常仍被支持,不会因升级而无法打开。

系统支持范围

按官方说明,Bitcoin Core 23.0 主要在以下平台经过充分测试与支持:基于 Linux 内核的操作系统、macOS 10.15+、Windows 7 及更新版本。多数其他 Unix-like 系统理论上也可运行,但测试频率较低,官方不建议在未支持的系统上部署节点。

注意:本文引用的版本说明与源码行为均以当前仓库为准。仓库内的 -cjdnsreachablegetdeploymentinfo 等能力在后续版本中可能继续演进,部署前请以对应版本文档为准。

P2P 与网络层关键变更

地址广播(Addr Relay)策略调整:#21528

本版本改变了节点对外散布地址信息的默认行为:一个 bitcoind 节点默认不再向入站(inbound)对等节点“广而告之”自己已知的网络地址。入站对等方只有在先向本节点发送了 ADDRADDRV2GETADDR 消息后,本节点才具备向其进行地址 gossip 的资格。

该改动让地址信息的分发从“单向主动推送”变为“基于请求的回应”,有助于减少无谓的地址广播流量。地址簿的实现位于 src/addrman.cppsrc/addrman.h,P2P 消息处理逻辑则在 src/net_processing.cpp

不再偏好 8333 标准端口:#23542

在此之前,Bitcoin Core 强烈倾向于只连接监听 8333 端口(比特币默认 P2P 端口)的对等节点,导致监听非标准端口的节点很难被 Core 节点主动连接。23.0 移除了这一偏好:只要对等节点在网络上可被发现,无论其 P2P 监听端口是否为 8333,Core 节点都可以与其建立出站连接。这一改动让使用自定义端口的个人与小型矿池节点更容易获得 Core 节点的对等连接。

完整支持 CJDNS 网络:-cjdnsreachable,#23077

23.0 首次为 CJDNS 网络加入了一等公民支持。CJDNS 是一个基于 IPv6 fc00::/8 地址空间、自带加密与去中心化路由的覆盖网络。启用方式是在启动参数中加入:

-cjdnsreachable

该参数的作用在源码中写得很明确,见 src/init.cpp

If set, then this host is configured for CJDNS (connecting to fc00::/8 addresses would lead us to the CJDNS network)

初始化的强制校验逻辑位于 src/init.cpp:如果配置了 -onlynet=cjdns 却未提供 -cjdnsreachable,节点会直接拒绝启动并报错 Outbound connections restricted to CJDNS (-onlynet=cjdns) but -cjdnsreachable is not provided。一旦设置了该参数,g_reachable_nets 中关于 CJDNS 网络的可达性由以下两个条件共同决定:

  1. 提供了 -cjdnsreachable
  2. 且(未设置 -onlynet,或 -onlynet 中包含 cjdns)。

换句话说,仅当主机实际接入 CJDNS 网络时,才应设置此参数。网络地址解析侧的相关逻辑可见 src/netbase.h。配套的部署与配置指南见 doc/cjdns.md

另外,-rpcallowip 的校验规则也随 CJDNS 支持而调整:RFC 4193(ULA,本地唯一地址)格式的 IP 仅当 -cjdnsreachable=0 时被允许作为 RPC 白名单来源,相关错误提示见 src/httpserver.cpp

手续费估算与 RBF

将 RBF 手续费纳入估算模型:#22539

费用估算现在会把 RBF(Replace-By-Fee,手续费替换)交易的费率纳入统计。此前估算器只观察普通(最终确认)的交易,替换交易因其特殊性质(替换交易不一定被挖出,且费率往往高于一般交易)会拉偏估算结果。23.0 之后估算器会考虑 RBF 交易的费率样本,使得估算出的“建议费率”更贴近真实挖矿竞争环境。

钱包与启动参数变更

-rescan 启动参数被移除:#23123

-rescan 这一启动参数在 23.0 中被正式删除:

  • 若钱包因损坏等原因确实需要重扫,节点在启动时仍会自动执行重扫(该兜底行为被保留);
  • 其余需要主动触发重扫的场景,请改用 RPC 命令 rescanblockchain

描述符钱包成为默认钱包类型

这是 23.0 对钱包影响最深远的变更:新创建的钱包默认使用描述符(Descriptor)钱包体系。旧式“传统钱包”(legacy wallet)仍可用,但必须显式要求:

  • 通过 createwallet RPC 创建时带上 descriptors=false
  • 或在 GUI 中取消勾选 Descriptor wallet 复选框。

需要特别注意的是:描述符钱包不支持部分旧的 wallet RPC,例如 importmultidumpprivkey 等在描述符钱包中无法使用。如果你的客户端代码在创建钱包时没有指定 descriptors=false、且依赖上述命令,则必须更新你的代码。描述符钱包的导入导出逻辑可见 src/wallet/export.cpp,其中 importdescriptors / listdescriptors 类 RPC 被用于替代旧式的密钥导入导出。

自动生成 Taproot tr() 描述符

新创建的描述符钱包会自动包含一个 tr() 描述符,用于生成单密钥 Taproot(SegWit v1)收款地址。这意味着新钱包开箱即可配合 BIP-341 Taproot 地址收发,进一步推动 Taproot 落地。

升级钱包时的自动密钥池刷新:#23093

当使用 upgradewallet 从非 HD 钱包升级到 HD(分层确定性)钱包时,keypool 会被自动清空并重新填充,以便立即开始使用新生成的 HD 密钥,无需手动干预。

新增 RPC:newkeypool

配合上述行为,本版本还新增了 newkeypool RPC:调用后会将 keypool 整体清空并重新填充。它适合在隐私敏感场景下抛弃已有派生密钥、强制钱包使用全新的密钥序列。描述符钱包中与 keypool 尺寸、结构相关的信息可见钱包地址 RPC 文档 src/wallet/rpc/addresses.cpp,其中默认每个描述符钱包持有 4 个激活的范围描述符(对应常见输出类型),每个 keypool 默认 1000 个条目。

listunspent 增加祖先交易信息:#12677

listunspent 现在对仍停留在 mempool 中的每个交易输出额外返回三个字段:

  • ancestorcount:该输出所在交易在 mempool 中的祖先交易数量;
  • ancestorsize:包含祖先在内的累计虚拟大小;
  • ancestorfees:包含祖先在内的累计手续费。

这些信息配合手续费替换与 CPFP(子为父付费)场景非常实用。

lockunspent 支持持久化锁:#23065

lockunspent 新增可选第三参数 persistent。置为 true 时,锁定信息会被持久化写入钱包数据库,因此即使节点重启甚至崩溃,UTXO 锁定状态也不会丢失。GUI 中锁定 UTXO 的行为同样改为持久化存储。

receivedby 系列 RPC 纳入 coinbase:#14707

原先以下钱包 RPC 排除 coinbase 交易getreceivedbyaddressgetreceivedbylabellistreceivedbyaddresslistreceivedbylabel。23.0 起这些 RPC 会统计 coinbase 产出的收款。若要恢复旧行为,可临时使用 -deprecatedrpc=exclude_coinbase(未来版本会移除)。

同时这些 RPC 新增布尔参数 include_immature_coinbase(默认 false),决定是否计入未成熟 coinbase——即确认数不超过 100 个、尚不可花费的 coinbase 交易。由于 coinbase 需 100 个确认后才可花费,默认不计入更贴合“可用余额”的语义。

RPC 接口更新

新增 RPC:getdeploymentinfo(软分叉状态查询)

此前软分叉(soft fork)状态内嵌在 getblockchaininfo 中,且只能查询链尖状态。23.0 将软分叉信息抽取到新的 getdeploymentinfo RPC,支持查询任意区块高度而非仅链尖的软分叉状态。相关实现与注册见 src/rpc/blockchain.cpp,返回对象包括:

  • hash:查询区块哈希;
  • height:查询区块高度;
  • deployments:各软分叉的部署状态详情。

getblockchaininfo 中是否保留软分叉字段可通过 -deprecatedrpc=softforks 暂时恢复,但该兼容开关会在未来版本移除。另请注意:无论通过哪种方式查看,status 字段的含义从“下一区块的状态”调整为“当前区块的状态”。

getblock verbosity 3 返回 prevout:#23508 相关区块能力

getblock RPC 新增 verbosity 3 级别,除完整交易数据外,还包含每笔交易输入(vin)中被花费输出的 prevout 信息。每个 vin 会带一个 prevout 子对象,含以下键:

  • generated:被花费的输出是否为 coinbase(true/false);
  • height:该输出被打包进链的区块高度;
  • value:输出金额(BTC 计);
  • scriptPubKey:该输出的锁定脚本。

REST 端点 /rest/block/ 同样被扩展以包含这些数据。该能力依赖 UTXO 撤销数据(undo data),因此在已裁剪(pruned)区块上不可用。实现细节见 src/rpc/blockchain.cpp

validateaddress 返回错误位置:#16807

validateaddress RPC 对无效地址新增返回 error_locations 数组:当检测到地址中包含无效字符时,给出其字符索引位置。例如对 Bech32 地址,会尝试定位至多两处 Bech32 校验错误,并仅在替换错误少于两处时保证成功与正确性。同时,解码失败时 error 字段会给出更具体的错误描述。

底层实现上,Bech32 解码在 src/bech32.cpp 中会返回出错位置列表;validateaddress 的地址解码路径见 src/rpc/output_script.cpp,其调用 DecodeDestination(定义于 src/key_io.h),错误位置会原样映射到 error_locations 数组。

移除 -deprecatedrpc=addresses 选项:#22650

在 22.0 中被标记废弃的 addressesreqSigs 字段,从以下 RPC 与 REST 端点的返回中被彻底移除:

  • RPC:gettxoutgetrawtransactiondecoderawtransactiondecodescriptgettransaction verbose=true
  • REST:/rest/tx/rest/getutxos/rest/block

如果你依赖这些字段,需要改而解析 scriptPubKey 中的地址信息。依赖它们调用 -deprecatedrpc=addresses 也不再有效(该配置项已被移除)。

mempool 交易费用字段层级化:#22689

getmempoolentrygetrawmempool(verbose=true)getmempoolancestors(verbose=true)getmempooldescendants(verbose=true) 返回结果中的顶层费用字段 feemodifiedfeeancestorfeesdescendantfees 被标记废弃,下一主版本将移除(本版本可临时通过 -deprecated=fees 恢复)。

等价的费用信息统一通过返回对象中的 fees 对象访问。重要警告:废弃字段 ancestorfeesdescendantfeessats 为单位,而 fees 对象内所有字段均以 BTC 为单位——迁移解析逻辑时务必换算,避免数量级错误。

多签地址创建返回 warnings:#23113

createmultisigaddmultisigaddress 现在都会返回 warnings 字段:当使用未压缩公钥却请求非 legacy 地址类型(如 Bech32/Bech32m)时会给出相应警告。

getblockchaininfo 新增 time 字段:#22407

getblockchaininfo 返回值中新增 time 字段,给出链尖区块的时间戳。

配置文件与数据文件变更

封禁列表迁移到 JSON:#22570

启动时,封禁主机与网络(来自 setban RPC)的读取规则改为:只读取 banlist.json,忽略 banlist.dat

  • Bitcoin Core 22.x 是唯一既能读取 banlist.dat、又能将其转换为 banlist.json 的版本;
  • banlist.json 已存在,22.x 不会尝试再把 banlist.dat 转成 json;
  • 从更早版本升级时,建议先用 22.x 完成一次转换,再升级到 23.0;
  • 升级后可用 listbanned RPC 校验解析出的封禁条目是否完整正确。

当前仓库中封禁数据库由 src/banman.cpp 管理:LoadBanlist()src/banman.cpp)在启动时读入,DumpBanlist()src/banman.cpp)在变更时写出,全程基于 m_ban_db 这一数据库后端抽象完成序列化。

-persistmempool 布尔语义修正:#23061

在早期版本中,不带值地传入 -persistmempool 会错误地禁用 mempool 持久化。23.0 将其修正为与其他布尔选项一致的语义:裸写 -persistmempool 等价于 -persistmempool=1(即启用)。而显式传 -persistmempool=0-persistmempool=1-nopersistmempool 的行为不受影响。

-maxuploadtarget 支持人类可读单位:#23249

-maxuploadtarget 现在允许附带字节单位后缀 [k|K|m|M|g|G|t|T],例如:

-maxuploadtarget=500g

规则为:不允许空白、+/- 号或小数;未提供后缀时默认按 M(MB) 解释。此前必须手动换算成纯字节数,现在可以直接按人类习惯配置带宽上限。

-proxy-noonion 的交互语义:#22834

若同时传入 -proxy=-noonion,则新语义下该代理不会被用作访问 Tor 网络的代理——这意味着无法再通过它建立到 Tor 网络的主动连接(例如通过 addnode RPC 手动添加 onion 节点)。

若想复现旧行为(使用代理但仅绕过 Tor),可改用 -proxy= 配合 -onlynet=,在 -onlynet= 中列出除 onion 之外所有希望连接的网络。

命令行工具与 GUI

-getinfo 输出优化:#21832

bitcoin-cli -getinfo 的输出格式被重新设计为更友好、占用更少纵向空间的数据展示方式,适合人工快速浏览节点状态。

-addrinfo 的 onion 统计字段合并:#22544

bitcoin-cli -addrinfo 原先分别输出 torv2torv3 两个字段,由于 22.0 起已移除 Tor V2 地址支持,本版本将二者合并为单一的 onion 字段,表示节点已知的 onion 地址总数。

GUI:地址类型下拉框与持久化 UTXO 锁

  • 地址类型选择从复选框改为下拉框:Bech32 复选框被替换为涵盖全部地址类型的下拉选择器,其中包括面向 Taproot 钱包的 Bech32m(BIP-350) 标准,方便在 P2PKH(legacy)、P2SH-SegWit、Bech32、Bech32m 之间切换;
  • GUI 锁定的 UTXO 持久化:在 GUI 中锁定的 UTXO 会持久化写入钱包数据库,节点关闭或崩溃后不会丢失。

低层变更与测试

新增 USDT 追踪点(Tracepoints)支持

Linux 上的发布二进制现在内置了实验性的追踪点(tracepoints),作为进程内部事件的观测接口,可用于审计、调试、监控等场景。

需要注意,tracepoint API 是半稳定的:虽然 API 本身经过测试,但进程内部结构可能随版本变化,导致追踪点需随之调整。现有追踪点的说明见 doc/tracing.md,仓库内提供了多种可直接使用的观测脚本:

以上脚本基于 BPF/BCC(如 bpftrace)运行,可直接对照源码理解内部事件触发点。追踪点的宏封装定义于 src/util/trace.h:其中 TRACEPOINT_SEMAPHORE 提供“是否已有观测器挂载”的计数信号量,TRACEPOINT_ACTIVE 用于在准备昂贵的追踪参数前判断是否有消费者,避免无谓开销。

regtest 软分叉激活高度

regtest 网络中,多个软分叉的激活高度被设置为区块高度 1,可通过运行期参数调整:

-testactivationheight=<name>@<height>

例如可指定某软分叉在特定高度激活,方便测试链与功能测试编写。例如设置 -testactivationheight=segwit@1 表示在高度 1 激活 segwit。

迁移清单:从 22.x 升级到 23.0 的检查要点

综合以上变更,升级时建议重点核对以下事项:

关注点 22.x 行为 23.0 行为 需采取的动作
钱包类型 默认 legacy 默认 descriptor 依赖 importmulti/dumpprivkey 等 RPC 的代码需显式 descriptors=false 或改造代码
地址字段 gettxout 等含 addresses/reqSigs 已移除 改用 scriptPubKey 解析;-deprecatedrpc=addresses 已删除
费用字段 顶层 fee/ancestorfees 迁移到 fees 对象(BTC 单位) 解析逻辑迁移;注意旧字段为 sats、新字段为 BTC
软分叉查询 getblockchaininfo 改用 getdeploymentinfo RPC 调用方更新
封禁列表 banlist.dat 仅读 banlist.json 提前用 22.x 完成转换并用 listbanned 校验
重扫钱包 -rescan 已删除 rescanblockchain RPC
入站地址广播 主动 rumour 地址 收到 ADDR/ADDRV2/GETADDR 才可广播 节点行为自动改变,无需配置

此外,新钱包默认即含 Taproot tr() 描述符与 Bech32m 地址支持,可结合 doc/tracing.md 进行 USDT 观测,并在 regtest 中通过 doc/release-notes/release-notes-23.0.md 所述的参数完成软分叉高度配置后再上线正式网络。

结语

Bitcoin Core 23.0 通过“描述符钱包默认化 + Taproot 描述符 + Bech32m 地址支持”的组合拳,将 SegWit v1 的可用性推向默认路径;在 P2P 层同步落地 CJDNS 网络支持与更克制的地址广播策略;RPC 层则通过 getdeploymentinfogetblock verbosity 3、validateaddress 错误定位等接口,为开发者与节点运维者提供更精确的观测与排障能力。对钱包/区块浏览器/交易所等下游开发者而言,最优先的行动项是核对上表中的 RPC 返回结构与单位变更,尽早完成适配迁移。

登录后查看全文
热门项目推荐
相关项目推荐