
Zcash 2.1.1 RC1 版本解析z_mergetoaddress 转正与选项解析行为变更【免费下载链接】zcashZcash - Internet Money项目地址: https://gitcode.com/GitHub_Trending/zc/zcash本文以 Zcash 2.1.1 RC1 发布说明doc/release-notes/release-notes-2.1.1-rc1.md为主线系统讲解该版本中三个核心变更z_mergetoaddress从实验特性正式转为稳定 RPC、命令行选项解析规则改为后者覆盖前者、以及裸多重签名bare multisig输出不再被钱包自动识别为收款。通过源码级佐证帮助开发者理解这些变更背后的实现原理、对既有脚本与钱包管理的影响以及相应的适配方法。一、z_mergetoaddress正式转正告别实验特性1.1 什么是 z_mergetoaddressz_mergetoaddress是一个用于合并资金的 RPC 接口它从 t-地址透明地址、z-地址屏蔽地址或两者同时收集资金并将其发送到单个 t-地址或 z-地址。该接口在 v1.0.15 中作为实验特性引入目标就是简化把大量零散 UTXO 和 note 合并成少量较大面额的过程——这是钱包整理、批量收款后归集、降低未来交易手续费与链上占用体积的常见操作。从 2.1.1 RC1 开始该接口被正式从实验状态提升为稳定 RPC。发布说明明确承诺此后对它的任何变更都只会是增量式additive即不会破坏既有调用方式这为依赖该接口的自动化运维与钱包工具提供了稳定的 API 契约。1.2 与大多数 RPC 的本质区别按数量而非金额操作发布说明特别强调与大多数 RPC 方法不同z_mergetoaddress操作的是一批特定数量的 UTXO 和 note而不是一笔特定金额的 ZEC。这是理解该接口行为的关键默认情况下它每次合并50 个 UTXO 和 10 个 note这两个上限可以通过参数transparent_limit和shielded_limit调整。从源码看默认值在 src/wallet/rpcwallet.cpp 中定义且比发布说明描述得更细#define MERGE_TO_ADDRESS_DEFAULT_TRANSPARENT_LIMIT 50 #define MERGE_TO_ADDRESS_DEFAULT_SPROUT_LIMIT 20 #define MERGE_TO_ADDRESS_DEFAULT_SAPLING_LIMIT 200即透明 UTXO 默认 50 个Sprout note 默认 20 个Sapling note 默认 200 个发布说明中10 个 note对应的是早期 2.1.1 时代的旧默认值当前仓库源码已演进为按池分别设定。若将transparent_limit或shielded_limit设为0则表示不限制数量按交易体积能容纳多少就合并多少但任何限额都受共识规则的约束——交易大小不得超过 Sapling 激活前的MAX_TX_SIZE_BEFORE_SAPLING与激活后的MAX_TX_SIZE_AFTER_SAPLING上限见 src/wallet/rpcwallet.cpp。1.3 返回值可驱动自动化合并z_mergetoaddress还会返回给定地址中剩余的 UTXO 与 note 数量这使合并过程可以被脚本自动化驱动例如不断执行合并直到某地址的 UTXO 数量低于某个阈值为止。结果对象包含以下字段源码见 src/wallet/rpcwallet.cpp字段类型含义remainingUTXOsnumeric仍可用于合并的 UTXO 数量remainingTransparentValuenumeric仍可用于合并的透明资金价值remainingNotesnumeric仍可用于合并的 note 数量remainingShieldedValuenumeric仍可用于合并的屏蔽资金价值mergingUTXOsnumeric本次正在合并的 UTXO 数量mergingTransparentValuenumeric本次正在合并的透明资金价值mergingNotesnumeric本次正在合并的 note 数量mergingShieldedValuenumeric本次正在合并的屏蔽资金价值opidstring操作 ID传给z_getoperationstatus获取异步操作结果1.4 完整调用签名与参数说明在钱包可用EnsureWalletIsAvailable的前提下z_mergetoaddress的函数签名与参数如下src/wallet/rpcwallet.cppz_mergetoaddress [fromaddress, ... ] toaddress ( fee ) ( transparent_limit ) ( shielded_limit ) ( memo ) ( privacyPolicy )参数明细基于 src/wallet/rpcwallet.cpp 的帮助文本整理fromaddresses数组必填一个 JSON 数组可包含 taddr 或 zaddr。支持三个特殊字符串ANY_TADDR合并钱包中任意 t-地址下的 UTXOANY_SPROUT合并钱包中任意 Sprout z-地址下的 noteANY_SAPLING合并钱包中任意 Sapling z-地址下的 note。注意事项不能同时从 Sprout 与 Sapling 地址发送资金若指定了特殊字符串再显式给出同类型地址会被视为重复并报错源码校验逻辑见 src/wallet/rpcwallet.cpp。统一地址Unified Address持有的资金当前不能通过z_mergetoaddress合并见 src/wallet/rpcwallet.cpp。toaddress字符串必填资金去向的 taddr 或 zaddr。fee数值可选默认 null交易手续费ZEC 单位。默认按 ZIP 317 计算常规费用GetConventionalFee见 src/wallet/asyncrpcoperation_mergetoaddress.cpp。transparent_limit数值可选最大合并 UTXO 数默认 50设为 0 表示按交易体积尽量多合。shielded_limit数值可选最大合并 note 数默认 Sprout 20 / Sapling 200设为 0 同理。memo字符串可选十六进制编码。当 toaddress 是 zaddr 时会写入新 note 的 memo 字段。privacyPolicy字符串可选默认LegacyCompat允许的信息泄露策略取值包括FullPrivacy、LegacyCompat、AllowRevealedAmounts、AllowRevealedRecipients、AllowRevealedSenders、AllowFullyTransparent、AllowLinkingAccountAddresses、NoPrivacy从全屏蔽逐步放宽到完全透明。1.5 异步执行与锁机制z_mergetoaddress是异步操作被选中的 UTXO 会先被锁定lock若执行出错则自动解锁可通过listlockunspent查看当前锁定的 UTXO 列表见 src/wallet/rpcwallet.cpp。从实现层面看该接口通过AsyncRPCOperation_mergetoaddress::main()src/wallet/asyncrpcoperation_mergetoaddress.cpp在后台线程执行内部捕获各种异常JSON 错误、运行时错误、逻辑错误、未知错误并设置对应的错误码与错误消息成功时输出txid与SUCCESS状态失败则置为FAILED。核心构建逻辑在main_impl()src/wallet/asyncrpcoperation_mergetoaddress.cpp它调用effects.ApproveAndBuild()构建交易、SendTransaction()广播并在任何路径下都会调用effects.UnlockSpendable(wallet)释放锁定保证异常时资金不被永久锁定。1.6 命令行使用示例发布说明指出可运行zcash-cli help z_mergetoaddress查看 API 细节与用法。参考帮助文本中的示例src/wallet/rpcwallet.cpp命令行调用形如zcash-cli z_mergetoaddress [ANY_SAPLING, t1M72Sfpbz1BPpXFHz9m3CdqATR44Jvaydd] \ ztestsapling19rnyu293v44f0kvtmszhx35lpdug574twc0lwyf4s7w0umtkrdq5nfcauxrxcyfmh3m7slemqsj对应 RPC 形式{ method: z_mergetoaddress, params: [ [ANY_SAPLING, t1M72Sfpbz1BPpXFHz9m3CdqATR44Jvaydd], ztestsapling19rnyu293v44f0kvtmszhx35lpdug574twc0lwyf4s7w0umtkrdq5nfcauxrxcyfmh3m7slemqsj ] }1.7 测试覆盖仓库中为z_mergetoaddress准备了专门的测试套件用于验证 Sapling 激活前后、统一地址与混合 note 等场景qa/rpc-tests/mergetoaddress_helper.py公共测试辅助代码定义MergeToAddressHelper与assert_mergetoaddress_exception用于搭建多节点测试链、断言异常消息qa/rpc-tests/mergetoaddress_sapling.py、qa/rpc-tests/mergetoaddress_mixednotes.py、qa/rpc-tests/mergetoaddress_ua_sapling.py、qa/rpc-tests/mergetoaddress_ua_nu5.py覆盖 Sapling 地址、混合 note、统一地址UA在 NU5 前后的合并行为src/wallet/test/rpc_wallet_tests.cpp包含z_mergetoaddress相关的钱包级单元测试。二、命令行选项解析行为变更严格按书写顺序后者胜出2.1 变更内容2.1.1 RC1 修改了命令行选项的解析规则选项现在严格按照书写顺序解析。此前存在一个反直觉的行为当同时给出-X与-noX时结果总是 X 被设置-X的优先级高于-noX。这一行为被废除新的规则与大多数软件一致——最后一次指定的值生效zcashd -X -noX # 结果是 X 被关闭-noX 后写 zcashd -noX -X # 结果是 X 被打开-X 后写2.2 源码层面的实现佐证发布说明中提到的修复来自 Wladimir J. van der Laan 的提交 Fix argument parsing oddity with -noX。从当前仓库源码看-noX的语义由 src/util/system.cpp 中的InterpretNegativeSetting()实现/** Turn -noX into -X0 (and -noX0 into -X1) */ static void InterpretNegativeSetting(std::string strKey, std::string strValue) { if (strKey.length()3 strKey[0]- strKey[1]n strKey[2]o)即将-noX转换为-X0、-noX0转换为-X1。结合解析时按命令行顺序处理、后出现的赋值覆盖先前的赋值最终实现最后一个值生效。2.3 迁移建议该变更属于破坏性行为变更。如果你的脚本或启动配置中同时出现了-X与-noX形式的同一个选项请检查其书写顺序确保与期望结果一致更稳妥的做法是统一只用一种写法避免歧义。这也提醒运维人员在升级到 2.1.1 后应重新审查zcashd的启动参数与zcash.conf中选项的叠加顺序。三、低层 RPC 变更裸多重签名输出不再自动视为收款3.1 变更内容自本版本起发往我们密钥的裸多重签名bare multisig输出不再被自动视为收款。此前这类输出只有在钱包持有其全部私钥时才会被识别而相比单密钥方案这种场景基本没有实际用途同时此类输出没有定义对应的地址格式钱包软件难以向它发送资金。因此这些输出不再出现在listtransactions、listunspent中不再计入余额除非被显式监视通过importaddress或importmulti传入 hex script 参数否则对钱包不可见signrawtransaction*系列命令对它们仍然可用。3.2 实现原理该变更对应的提交是 Pieter Wuille 的 Do not treat bare multisig as IsMine。钱包判断输出是否属于自己IsMine的核心逻辑位于 src/script/ismine.cpp当脚本无法按标准模板匹配、且钱包中只有监视watch-only脚本而没有可求解的私钥时IsMineInner()返回ISMINE_WATCH_UNSOLVABLE当脚本完全无法识别时返回ISMINE_NO。裸多重签名不再作为IsMine匹配结果正是通过收紧IsMine的模板匹配逻辑实现的相关提交还包括 Remove template matching and pseudo opcodes 与 Do not expose SigVersion argument to IsMine。配套单元测试见 src/test 与 src/wallet/test 目录下的脚本标准模板测试如 Unit tests for script/standard functions 提交新增的用例。3.3 钱包适配指导若你确实持有裸多重签名输出的全部私钥且希望它参与余额统计可改用importaddress或importmulti显式监视对应脚本以 hex script 形式但需注意这只会将其视为监视项若你需要签名此类输出signrawtransaction*仍然可用不受影响该变更与引入importpubkey、importaddress的 p2sh 选项、watch-only 支持等同期改动属于同一轮钱包 IsMine 语义重构建议在升级后复核钱包的收款地址清单与余额统计是否符合预期。四、其他值得注意的变更2.1.1 RC1 还包含若干对运行与开发有影响的改动可在 doc/release-notes/release-notes-2.1.1-rc1.md 的完整 Changelog 中查阅以下是几类代表性条目升级与共识Jack Grigg 将 librustzcash 升级至 0.2.0 并迁移 API将 Heartwood 加入升级列表Upgrade list新增NextUpgrade测试用例并把距下次升级高度信息显示到 metrics 控制台。网络与配置connect0现在会禁用自动出站连接Gregory Maxwell新增多 RPC 用户配置选项Gregory Sanders移除了mempooltxinputlimit选项Dagur Valberg Johannsson。钱包与钱包初始化Jonas Schnelli 重构了钱包/初始化交互允许钱包在剪枝pruned模式下运行并禁止在剪枝模式下使用 import 类函数。开发工具Taylor Hornby 为 zcutil 添加了 AFL 模糊测试脚本、可用-replace-main-with-stub的 fuzzing 配置以及 CheckBlock、AddrMan 反序列化、ReadFeeEstimates 等 fuzzing stub。构建依赖Ulrich Kempken 将依赖下载全部切换为安全通道Cory Fields 提升了 OSX 工具链并保证 OSX 构建输出确定性bdb 在 darwin 交叉编译时使用--disable-atomics。五、升级到 2.1.1 RC1 的实践清单脚本适配排查所有同时出现-X/-noX的启动参数按最后指定者生效调整顺序钱包复核检查是否依赖裸多重签名输出计入余额如有则改用importaddress/importmulti显式监视合并流程升级可将原有的实验期z_mergetoaddress调用平滑迁移至稳定 API利用remainingUTXOs/remainingNotes返回值编写合并直到低于阈值的自动化脚本回归验证升级后运行 qa/rpc-tests/mergetoaddress_sapling.py 等测试确认合并链路正常测试需在 regtest 环境运行命令可参考 qa/pull-tester/rpc-tests.py依赖与构建如需交叉编译 darwin 或使用模糊测试注意 2.1.1 起依赖下载已走安全通道OSX 构建已确定性输出。总体而言2.1.1 RC1 是一次稳字当头的版本z_mergetoaddress的转正为钱包整理与自动化合并提供了长期稳定的接口契约选项解析规则的修正消除了一个长期存在的反直觉陷阱而裸多重签名语义的收紧则让钱包的收款判断更加贴近实际使用场景。对于运行 zcashd 节点或维护钱包服务的团队重点关注第二节与第三节的两项行为变更即可平滑升级。【免费下载链接】zcashZcash - Internet Money项目地址: https://gitcode.com/GitHub_Trending/zc/zcash创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考