Bitcoin Core 0.9.0 版本技术解读:钱包/CLI 拆分、手续费改革与可锻性修复
本篇文章围绕 Bitcoin Core 官方仓库(integration/staging tree)中的 0.9.0 版本发布说明 展开,系统梳理这一里程碑版本在 RPC 接口、命令行选项、交易验证、钱包、挖矿与 P2P 协议层面的全部变更,并结合当前仓库源码验证其中仍然沿用的设计(如 walletpassphrase 语义、bitcoin-cli 职责拆分、minrelaytxfee 参数体系)。读完本文,你将掌握 0.9.0 升级注意事项、walletpassphrase 行为变更细节、手续费阈值模型、OP_RETURN 可修剪输出的设计动机,以及该版本对今日 Bitcoin Core 架构的直接遗产。
版本定位与升级指南
Bitcoin Core 0.9.0 是一个新的主版本(major version)发布,同时带来新功能与大量缺陷修复。官方当时通过 bitcoin.org 的 bin/0.9.0/ 目录提供二进制包,并通过 GitHub issue tracker 接收缺陷报告(详见原发布说明开头)。本文作为对该发布说明的技术档案解读,所有特性描述均以该文档及当前仓库中的延续性实现为准。
升级操作步骤
对于运行旧版本的用户,官方给出的升级流程为:
- 完全关闭正在运行的旧版本客户端;
- 等待进程完全退出——旧版本可能需要几分钟才能彻底停机,务必不要在中途强行重启;
- 卸载所有更早版本的 Bitcoin 程序;
- 重新安装:Windows 直接运行安装包;macOS 覆盖
/Applications/Bitcoin-Qt;Linux 覆盖bitcoind与bitcoin-qt可执行文件。
自 0.7.2 及更早版本升级的注意事项
若从 0.7.2 或更早版本直接升到 0.9.0,首次运行会对区块链文件重新索引(re-index)。根据机器性能不同,这一过程耗时约 30 分钟到数小时。这是因为更早期版本的区块存储布局与 0.9.0 不同,必须重建本地数据库后才能继续同步。
Windows 用户:注意 32/64 位差异
- 0.9.0 首次提供 Windows 64 位版客户端;
- 32 位系统在初始同步阶段容易出现虚拟内存耗尽的问题,官方因此强烈建议支持 64 位的机器安装 64 位版本;
- 升级到 64 位版前,务必先卸载所有更早版本的 Bitcoin 客户端,避免两个版本并存导致数据目录冲突;
- 0.9.0 发布候选 2(RC2)的 Windows 二进制未经代码签名,需要借助 PGP 与
SHA256SUMS.asc校验文件确认二进制完整性;最终正式版(final)的setup.exe已做代码签名。这一"通过校验和文件验证二进制"的做法延续至今,当前仓库的构建产物说明可参考 contrib/verify-binaries/。
macOS:最低系统要求提升
0.9.0 起不再支持 OS X 10.5 与 32 位 Mac,最低要求调整为:
- 支持 64 位运算的 CPU;
- Mac OS 10.6 或更高版本。
降级风险警告(Downgrading warnings)
0.9.0 的链状态数据(chainstate)并非总是与旧版本兼容。如果在 0.9 上运行后再切回 0.8.x,旧版本启动时可能报区块链校验错误,原因在于:
- 0.9.0 引入了 "被修剪的输出"(pruned outputs) 机制,即部分可证明不可花费(provably-unspendable)的输出不再计入未花费交易输出(UTXO)索引;
- 0.8.x 的数据结构不认识这种省略,因而在一致性校验时报错。
解决方法是:使用旧版本时加 -reindex 参数启动,让旧版本重建其 chainstate 数据结构以修正问题。
另一个降级影响发生在钱包层:0.9 钱包首次被 0.8.x 打开时,会为了找回"丢失的已花费币"而重新扫描区块链,典型机器上耗时可达数十分钟。这类"扫描全链以修复状态"的思路,在后续版本中以生日(birthday)优化重扫描等机制继续演进(见下文钱包部分)。
品牌重构:正式更名 Bitcoin Core
为避免"Bitcoin 网络"与"Bitcoin 软件"两个概念之间的混淆,官方在 0.9.0 将参考客户端正式更名为 Bitcoin Core。这是项目品牌史上的一次关键转变,此后 Qt 图形客户端 bitcoin-qt 与守护进程 bitcoind 共同构成 Bitcoin Core 发行版,这一命名沿用至今(见 README.md)。
OP_RETURN 与"链上数据存储":可修剪输出的设计动机
0.9.0 中的 OP_RETURN 功能在社区中引发不少误读,发布说明专门澄清了两点:
- 这不是对"把任意数据写入区块链"的背书。此前一些方案(有的已经上线)把图片等任意数据编码成永远无法花费(forever-unspendable)的交易输出,导致比特币 UTXO 数据库无谓膨胀——每个这类输出都必须被每个全节点永久保留;
- 新方案把
OP_RETURN输出设计为可证明可修剪(provably-prunable)的输出,即从协议上可证明该输出永远无法再被花费,从而允许节点在存储时将其从 UTXO 集中剔除。
发布说明同时给出明确态度:在区块链中存储任意数据依然是坏主意,存储非货币数据放在链外更廉价也更高效。这一"标准交易必须可被裁剪、UTXO 集只保留可能被花费的输出"的治理原则,从代码层面看已沉淀进共识与策略代码,例如 src/consensus/consensus.h 中的 MAX_OP_RETURN_RELAY 等上限约束,并沿用至今。
Autotools 构建系统迁移
0.9.0 将原先散落的各独立 (q)makefile 统一迁移到 autotools 构建系统,标准流程变为:
./autogen.sh
./configure
make
这一改动让熟悉开源生态的开发者可以更平滑地为项目贡献。官方同时提醒:从源码构建前务必先查阅对应平台的 doc/build-*.md 文档。
需要说明的是,从该仓库当前主分支的构建基础设施可以看到构建体系在 0.9 之后又经历了新一轮演进——根目录已是 CMakeLists.txt 与 CMakePresets.json,并配套 doc/CMakeLists.txt、doc/build-unix.md 等新式文档;0.9.0 所代表的 autotools 阶段则是这一演进链路中承前启后的关键一环。为某历史版本做源码构建时,应以该版本 tag 附带的文档为准。
bitcoin-cli:RPC 客户端与服务器职责分离
0.9.0 之前,bitcoind 可执行文件同时充当服务器与 RPC 客户端(即"让正在运行的守护进程执行某操作"的能力内置其中)。0.9.0 把 RPC 客户端功能抽离为独立的 bitcoin-cli 可执行文件。当时计划逐步从 bitcoind 中移除 RPC 客户端代码,但为向后兼容会保留一两个版本。
这一职责拆分从当前仓库的代码结构看已经成为持久性架构:源码根目录下存在独立的 bitcoin-cli.cpp 入口(对应构建目标),其命令行手册见 bitcoin-cli.1,同时 bitcoin-tx.cpp、bitcoin-wallet.cpp、bitcoin-util.cpp 也都各自独立成可执行文件,构成"一个守护进程 + 一组瘦客户端工具"的现代形态。RPC 接口的通用文档可参考 JSON-RPC-interface.md。
walletpassphrase RPC 行为变更:解锁窗口的覆盖语义
0.9.0 对 walletpassphrase 在钱包已经处于解锁状态时的行为做了语义调整,这是钱包加密使用中极易踩坑的细节,发布说明用两段对比讲得很清楚。
0.8 旧行为:重复解锁报错
旧版本在钱包已解锁时再次调用 walletpassphrase 会直接失败,且不改变原有解锁截止时间:
> walletpassphrase 1000
walletunlocktime = now + 1000
> walletpassphrase 10
Error: Wallet is already unlocked (old unlock time stays)
0.9 新行为:新解锁时间覆盖旧值
0.9.0 起,重复调用会用新的 timeout 重新计算解锁截止时间并覆盖旧值:
> walletpassphrase 1000
walletunlocktime = now + 1000
> walletpassphrase 10
walletunlocktime = now + 10 (overriding the old unlock time)
从当前仓库源码看该语义的沉淀
"覆盖旧解锁时间"这一行为在当前仓库的 walletpassphrase RPC 实现中仍被明确写入帮助文本:src/wallet/rpc/encrypt.cpp 中的文档字符串写着 "Issuing the walletpassphrase command while the wallet is already unlocked will set a new unlock time that overrides the old one.",与该版本发布说明完全一致。进一步看其实现逻辑:
- timeout 参数不允许为负(否则会立即重新上锁),见
nSleepTime < 0的校验分支; - timeout 被钳制在约 3 年(
100000000秒)以内以避免计算重新上锁时间时溢出; - passphrase 为空会被拒绝;口令错误时抛出
RPC_WALLET_PASSPHRASE_INCORRECT,并在口令包含空字符(\0)时给出专门提示(历史上某些旧版本设置的口令存在空字符问题,见源码注释中引用的 issue #27067); - 实际解锁最终落到 CWallet::Unlock 与 CWallet::Unlock(const CKeyingMaterial&) 两条路径:前者会遍历
mapMasterKeys中的多个主密钥(master key),逐一尝试用口令解密,成功后才真正解锁并升级描述符缓存;后者持有cs_wallet锁并设置解锁截止时间。
walletpassphrasechange(改密)与 walletlock(立即锁上)在同一文件中,三者共同构成加密钱包日常操作的完整闭环。
交易可锻性(Transaction Malleability)相关修复
0.9.0 针对交易 ID(TXID)可锻性问题做了一批针对性修复:
-nospendzeroconfchange命令行选项:避免花费零确认的找零(change)输出,从而减少因找零可锻性引发的连锁问题;- 收紧
IsStandard()交易规则:阻止中继与挖矿接收被"变异"的交易; listtransactions/gettransaction输出新增冲突信息:报告钱包中因花费相同输出而互相冲突的交易;- 修复
getbalance/listaccounts余额计算缺陷:此前对双花(double-spent)或变异交易会报告错误余额; - 新增
-zapwallettxes选项:重建钱包的交易信息,清除钱包层记录的、与链上状态不一致的陈旧交易记录(该历史选项后来在后续主版本中被移除,0.9.0 文档记录的是当时的设计)。
从功能语义上,这些修复直接支撑了后来 RPC 层 "conflicted(冲突)" 交易概念的落地——冲突交易在钱包中的确认数显示为 -1,参见下文 RPC 条目。该"识别并标记冲突"的机制在现代钱包代码中通过比较交易输入花费集实现,可结合当前仓库钱包实现进一步跟踪。
交易手续费政策改革:费率阈值与区块填充模型
0.9.0 对手续费政策的调整是理解 Bitcoin 费用市场的重要一课。
中继/挖矿最低费率降至 0.01 mBTC/KB
新版本将交易在网络上中继、以及矿工把交易纳入区块所要求的最低费率从之前的默认值降到 0.01 mBTC 每千字节(即 10 satoshi/B 量级的历史门槛)。
矿工打包规则并未与中继规则画等号
发布说明特别强调:交易被网络中继不保证会被矿工打包。默认情况下矿工先用约 50 KB 空间装"高优先级"交易,再用约 700 KB 装"每千字节费率最高"的交易。
相关配置参数与历史混淆
- 最低中继/挖矿费率(按每千字节)可用
minrelaytxfee选项调整; - 此前版本错误地使用
mintxfee设置来决定哪些低优先级交易应被纳入区块——0.9.0 对此做了纠正; - 钱包代码在构造低优先级交易时默认费率仍为 0.1 mBTC/千字节;在交易量高峰期,即使这个费率也未必能保证交易快速确认,可用
mintxfee选项覆盖默认值。
从当前仓库看参数体系延续
minrelaytxfee 与 mintxfee 这两个参数名在现代 Bitcoin Core 中依然存在并作为核心费用策略参数,可在 src/node/mempool_args.cpp、src/policy/policy.h、src/interfaces/chain.h 与 src/init.cpp 中找到它们被解析、传递与使用的链路,相关 RPC(如 getmempoolinfo 展示 minrelaytxfee)实现见 src/rpc/mempool.cpp。0.9.0 确立的"区块填充从高费率到低费率排序、区分中继策略与挖矿策略"的基本框架,是理解后续费率估算器(estimatefee)等机制的历史起点。
0.9.0 完整变更条目详解
原发布说明后半部分按功能域给出了完整条目,下面逐类展开。
RPC 接口变更
新增"冲突交易"概念与相关能力:
- conflicted 交易:钱包中相互冲突的交易被标记为确认数
-1; listreceivedbyaddress:新增返回交易 ID(txid);gettransaction:输出新增原始交易 hex;getreceivedby(account|address):更新帮助文本与测试;getblock:接受第 2 个verbose参数(类似getrawtransaction),默认仍为 1 以保持向后兼容;- 新增
verifychain:运行时校验链数据库; - 新增
dumpwallet/importwallet:导出/导入钱包文本(含私钥); keypoolrefill:新增可选 size 参数;- 新增
getbestblockhash:返回最佳链顶端哈希; getblock输出新增chainwork(自创世块以来全网完成的总工作量);- RPC 口令校验对时序攻击免疫化;
- 澄清帮助信息并补充示例;
- 新增
getrawchangeaddress:为原始交易获取找零地址; sendrawtransaction默认拒绝高得离谱的手续费;- 新增
decodescript:解码十六进制脚本; validateaddress返回redeemScript;- 新增
getnetworkhashps:计算全网哈希率; - 新增
ping命令,getpeerinfo输出新增pingtime与pingwait字段; getpeerinfo输出新增addrlocal字段;getrawmempool:新增 verbose 布尔参数;- 新增
getunconfirmedbalance:获取未确认余额; importprivkey:显式确保钱包处于解锁状态,并校验密钥有效性。
命令行选项变更
- 新增
-nospendzeroconfchange:绝不花费未确认找零; - 新增
-zapwallettxes:重建钱包交易信息; - 将
-tor更名为-onion,以更准确表达其用途(控制 Tor/Onion 可达性); - 新增
-disablewallet:即使二进制带钱包编译,也可让bitcoind完全无钱包运行; - 更新默认
-rpcsslciphers,纳入 TLSv1.2; -logtimestamps默认开启,并重写帮助文本;- RPC 客户端新增
-rpcwait:等待服务器启动后再发起请求; - 移除
-logtodebugger; - 允许
bitcoind使用-noserver。
区块链处理与存储
- leveldb 升级到 1.15;
- 校验正确创世块,防止误加载来自错误网络的数据目录;
- 支持移除 txindex 并新增重索引对话框;
- 记录被中止的区块数据库重建日志;
- 孤儿块(orphan blocks)以序列化形式存储以节省内存;
- 内存中孤儿块数量上限设为 750;
- 修复非标准断连交易导致的 mempool 孤儿问题;
- 在区块 279,000 处新增检查点(checkpoint)。
钱包
- 修复并新增回归测试:正确计算包含双花(或变异)交易的钱包余额;
- 存储密钥创建时间,计算整个钱包的"生日"(birthday);
- 优化重扫描:跳过早于生日前的区块;
- 支持用
-wallet=foo.dat指定钱包文件; - 生成币的成熟高度由 120 改为 101 块;
- 缩短钱包加载时间;
- 计算优先级时不计入 txin,鼓励"扫币"(sweeping)行为;
- 读损坏钱包时不再创建空交易;
- 修复
importprivkey后重扫描须从头开始的问题; - 签名只使用低 S 值(low-S),为隔离见证时代的规范化签名打下基础。
挖矿
- 默认
-blockmaxsize/prioritysize提升到 750K / 50K; getblocktemplate不再要求密钥即可生成区块模板;- 挖矿代码的费用策略与中继费用策略对齐。
协议与网络
- 中继费率降至 0.01 mBTC/KB;
- version 消息附带交易中继标志;
- 新增 P2P
reject消息(对应 BIP 61 草案); - 地址每 15 分钟 dump 一次(此前为 10 秒);
OP_RETURN数据输出作为标准交易类型被中继;- 中继时移除 CENT 输出免手续费规则;
- 降低免手续费交易的创建体积上限;
- mempool 超过
MAX_INV_SZ时拆分多条 inv 消息发送; MIN_PROTO_VERSION拆分为INIT_PROTO_VERSION与MIN_PEER_PROTO_VERSION;- 广播时不再把
fFromMe交易特殊对待; - 收到的消息逐条处理、消息间不再 sleep;
- 改进连接失败日志;
- 协议版本升至 70002;
- 增加若干网络可观测性日志;
- 新增来自 bitcoinstats.com 的 DNS seed。
验证(Validation)
- 记录非标准交易被拒的具体原因;
- 修剪可证明不可花费的输出,并同步调整一致性检查;
- 检测足够长的分叉并给出警告;
- 发现长分叉或非法分叉时调用
-alertnotify脚本; - 修复多区块重组(reorg)时的交易"复活"问题;
- 拒绝非规范编码的序列化大小;
- 验证阶段拒绝粉尘(dust)金额;
- 接受在下一个区块即达成 final 的
nLockTime交易。
构建系统
- 切换到 autotools 构建系统(见前文);
- 可传
--disable-wallet给 configure 实现无钱包构建,从而移除 BerkeleyDB 依赖; - 升级 gitian 依赖(libpng、libz、libupnpc、boost、openssl)到更新版本;
- Windows 64 位构建支持;
- Solaris 兼容性修复;
- 校验 gitian 输入源码压缩包完整性;
- 全平台开启 GCC 栈粉碎(Stack-smashing)保护。
GUI(bitcoin-qt)
- Windows 构建切换到 Qt 5.2.0;
- 新增支付请求(BIP 70)支持;
- 改进选项对话框;
- 新发送确认对话框展示交易手续费;
- 概览页展示总余额;
- 首次启动、数据目录缺失或传入
-choosedatadir时,允许用户选择数据目录; - 保存并恢复窗口位置;
- 交易详情对话框的交易 id 中加入 vout 索引;
- 调试窗口新增网络流量图;
- 新增打开 URI 对话框;
- 新增 Coin Control(币种控制)功能;
- 改进收款流程:
Receive标签改为付款请求表单,历史地址列表移入 File 菜单; - 品牌改为
Bitcoin Core; - 初始化/关闭移到独立线程,避免启动时"未响应",关闭时展示窗口;
- 不再每次启动都重建自启动链接;
- 显示并存储普通
bitcoin:URI 的消息; - 修复老版本 Qt 上的富文本检测挂死问题;
- OS X:使用 10.8+ 用户通知中心展示类似 Growl 的通知;
- OS X:Info.plist 增加
NSHighResolutionCapable,改善 Retina 字体渲染; - OS X:修复点击 Dock 图标导致 bitcoin-qt 启动崩溃的问题;
- Linux:修复 Gnome 的
bitcoin:URI 处理器。
其他杂项
- 新增 Linux 脚本 contrib/qos/tc.sh,基于 tc 限制外发带宽(该脚本在当前仓库仍保留在
contrib/qos/下); - 新增
-regtest模式:类似 testnet 但完全私有,可通过setgenerateRPC 实现即时出块——regtest 至今仍是本地开发与 功能测试 的默认基础设施; - 新增 contrib/linearize/ 的
linearize.py:用于生成 bootstrap.dat(原始发布说明称为linearize-hashes.py配套流程,当前仓库中的 linearize-data.py 即其延续); - 引入独立的 bitcoin-cli 客户端(见前文)。
总结与延伸阅读
Bitcoin Core 0.9.0 是一个承上启下的版本:它在品牌上确立 "Bitcoin Core",在工具形态上完成 bitcoind/bitcoin-cli 职责分离,在验证层奠定"可修剪输出"与低 S 值签名的基线,在费用层厘清中继费率与打包费率,并首次提供 Windows 64 位、regtest 与 Qt 支付请求等至今仍在使用的关键能力。许多机制——如 walletpassphrase 的覆盖语义、minrelaytxfee 参数链、RPC 客户端工具集——都能在当前仓库源码中直接找到延续实现,本文引用的 encrypt.cpp、wallet.cpp、mempool_args.cpp 即为继续深入阅读的起点。
若希望进一步探究,可查阅本仓库中该版本相关的配套历史文档(doc/release-notes/ 下以版本号命名的相邻发布说明)、doc/JSON-RPC-interface.md 与 doc/man/ 手册页。注意:0.9.0 距今久远,部分选项(如 -zapwallettxes、-nospendzeroconfchange)与 autotools 构建流程在后续主版本中已演进或移除,实际使用应以你所构建的具体版本为准。
atomcodeClaude Code 的开源替代方案。连接任意大模型,编辑代码,运行命令,自动验证 — 全自动执行。用 Rust 构建,极致性能。 | An open-source alternative to Claude Code. Connect any LLM, edit code, run commands, and verify changes — autonomously. Built in Rust for speed. Get StartedRust0627
Hy4-previewHy4 preview 是由腾讯混元团队研发的新一代混合专家(MoE)旗舰模型。模型总参数量 770B,每个 token 激活 49B,主干共包含78层,第一层采用标准 FFN,其余 77 层均为 MoE 结构,每层包含 256 个路由专家与 1 个共享专家,每个 token 激活 top-8 路由专家及共享专家。主干之外原生内置 1 层 MTP(总参数量 10B,激活 0.7B)以支持投机解码。Python00
GLM-5.3GLM-5.3 与 GLM-5.2 使用相同的基座模型——所有提升均来自后训练。与 GLM-5.2 相比,它在复杂编程和长程任务上的表现显著提升。Jinja00
GLM-5.3-FlashGLM-5.3-Flash (320B-A18B),是GLM-5系列的首个原生多模态模型。320B总参数,能力超过GLM-5.2Jinja00
Spark-X2.5-4BSpark-X2.5-4B 旨在让强大的 AI 更实用、更高效、更易获得。在广泛日常任务中表现强劲,涵盖对话、写作、翻译、推理、编码、工具调用以及智能体工作流,并在同等规模的开源模型中取得领先成绩。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00
Spark-X2.5-1.7BSpark-X2.5-1.7B 旨在让强大的 AI 更加实用、高效且易于获取。这些模型在广泛的日常任务中表现出色,涵盖对话、写作、翻译、推理、编程、工具调用和智能体工作流,并在同等规模的开源模型中取得领先结果。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00