在钱包图形界面里导入一个体积过大的 PSBT 文件,会弹出一句提示:文件必须小于 100 MiB。这句提示背后有一个常量,而常量与文案的单位口径其实不完全一致。这个细节对多签协作的人有实际影响。
限制只加在一条路径上
比特币核心 v31.0 源码里,这个上限常量定义在 PSBT 的头文件中,取值是一亿字节,源码自己的注释把它写作 100 MB。同一个头文件上方的注释解释了为什么要设这个数:BIP 174 规定了这个格式的读写规则,但没有规定文件最大能有多大,程序自己必须有个上限,否则拿到一个不断增长的流就只能一直读下去,最终把内存耗尽。
需要强调的是这条闸门的覆盖面。全仓库里真正执行尺寸判断的调用点,出现在图形界面的导入路径上:用户通过文件对话框挑一个 PSBT 文件,程序在读取之前先看文件尺寸,等于或超过上限就给出那句提示并中止。命令行下把 PSBT 当参数传进去、或者通过 RPC 传一段 base64 文本,走的是另外的入口,不经过这个判断。所以”节点导入 PSBT 有 100 MB 上限”这句话是不准确的,它约束的是图形界面挑文件这条路。
一亿字节和 100 MiB 差多少
这是最容易看漏的一处。常量是一亿字节,按十进制算正好是 100 MB;而界面提示写的是 100 MiB,也就是 104857600 字节。两者相差约 4.86%。
对绝大多数文件这个差别毫无意义,没人会为了百分之五去纠结。但它决定了一个边界行为的解释权:程序真正的准入线是那串十进制的一亿字节,提示文字只是给人看的近似说法。如果你的协作流程里有一个自动检查环节按 104857600 判断”这文件能不能导入”,那么在 100000000 到 104857600 之间的文件会被你的脚本放过、被钱包拒绝。写脚本时按常量口径判断,别照抄提示文案。
读进来之后还有一道格式兼容
尺寸闸门放行之后,图形界面的导入代码还做了一件很多人不知道的事:它先把整个文件读进内存,然后尝试把内容当作 base64 文本解码一次。如果解得动,就用解码结果替换原始字节。
这段逻辑的注释说明它针对的是”有些 PSBT 文件里存的是 base64 字符串而不是二进制内容”这一现实。PSBT 有两种常见的外在表现形式——二进制流与 base64 编码的文本,BIP 174 对两者都给了规则,实际协作中不同工具产出的形态不一样。图形界面在这条路径上两种都吃:文件是二进制就直接用,是 base64 文本就先解码。
顺带一提,同一条导入链路的剪贴板分支有对应的错误提示:从剪贴板取内容时如果 base64 解不开,会明确告知无法从剪贴板解码。也就是说,“文件导入”与”剪贴板导入”是两个分支,前者有尺寸闸门和形态兼容,后者只处理 base64 文本这一种形态。
为什么 PSBT 会大到接近上限
PSBT 的体积不由交易本身决定,而由它携带的元数据决定。一份 PSBT 要为每个输入、每个输出附带尽可能完整的信息:前一笔交易的全文、可用的脚本与赎回数据、各方的公钥与派生路径、已收集的签名,以及版本号与分隔符结构。
多签协作场景最容易把它撑大。参与方越多,每方附带的公钥列表、派生路径与签名字节就越多;如果每方都往里面塞完整的前一交易副本,输入数量一多,体积会迅速上一个数量级。跨机构协作还常见一种情况:各方反复在同一份文件上叠加自己的信息而没有清理,或者把整段历史交易都嵌了进去,这比交易本身大小重要得多。
版本号也占位置。PSBT 有一个显式的版本字段,v31.0 的头文件里把当前程序支持的最高版本定义为 0,意味着它还读不懂更高版本号的 PSBT。这不是尺寸问题,但同样会导致”文件能读进来却报格式错”的结果,排查时值得一并看。
实操建议
真遇到那句提示时,先判断是文件真的异常还是流程有问题。异常的情形通常是上游工具产出错了——比如把一个二进制文件误存成文本、或者把不该嵌进去的整块数据塞进了某个输入字段,这类问题重做一次导出就能发现。流程上的问题则更常见:把一份巨型 PSBT 拆成两笔交易分别协作,往往比想办法绕过尺寸闸门省事得多,因为过大的 PSBT 即便能导入,签名校验与后续广播的成本也不会变小。
不要尝试用改配置的方式绕过它,这个上限在源码里是常量,没有对应的启动参数。如果确实有一笔交易的 PSBT 逼近这个量级,正确的方向是重新审视交易结构,而不是继续往上抬闸门。
风险提示:本文依据比特币核心 v31.0 源码撰写,常量取值与导入路径实现可能随版本调整;涉及资产操作请以实际软件提示为准,本文不构成任何投资建议。
发表评论
还没有评论,来说两句吧。
评论区为展示样式,提交不会被处理。