一、一个哈希两种写法
把一笔已确认交易在区块浏览器上打开,复制它的 txid;再连上自己的节点执行 getrawtransaction 查同一笔,序列化数据里前手交易的引用会给你一段”字母相同、顺序颠倒”的十六进制。这不是谁抄错了——比特币里几乎所有哈希都存在两本账:内存与线上序列化按小端序摆放字节,也就是说数值的低位字节放在前面;而展示给人和 RPC 输出时,惯例把结果当作一个 256 位大整数、按大端序(高位在前)写出来,看起来就像整串倒放。

二、为什么会长成这样
源头要追到两个决定。其一,比特币的序列化规范大量采用小端序,与它诞生于英特尔架构时代有关:金额、高度、时间戳乃至协议魔数都按低位在前编码。其二,哈希函数的输出是一串 32 字节,规范把它整体解释成一个 256 位数字来做难度比较——挖矿要的是”这个数小于目标值”,数字比较天然要求定义谁是高位。共识层把哈希的低位比特对应到字节数组的低位位置,于是”倒着读”成了把内存数组写成人话的固定翻译。两个决定都没有对错,错开的只是各自方便。
三、哪些字段各用哪套
逐项过一遍常用面:交易与区块的内部哈希计算都对序列化字节做两次 SHA-256,计算本身对字节序无所谓,顺序之争发生在”摆进去”和”读出来”两头。RPC 参数里,txid 与区块哈希按大端显示序传入;而 getrawtransaction 的裸数据里前手引用是小端序——这正是很多脚本作者第一次拼原始交易时的头号事故点。高度、金额这类数值字段一律小端;校验和、签名里的 r、s 则各有自己的编码规范,不能想当然地顺手倒序。默克尔树的节点哈希同样是双 SHA-256 的 32 字节原样拼接,不额外倒转。
四、排障时的顺序嗅觉
三类典型场景值得单独点名。第一,用 getblock 拿到的区块头哈希与对端报告”对不上”,先尝试整串倒序再怀疑数据不同源。第二,手写 raw 交易或在脚本里拼 PSBT 字段时,前手 txid 要以小端写入、以大端读入,写一个断言把两次倒序的净效果固定下来,别让”看起来一样”混进长整型转换。第三,比对两份十六进制前先看它出自哪一层:共识层摘要、协议序列化、人类展示是三个不同的仓库,跨仓取货先做序转换。
五、把别扭变成纪律
字节序是比特币工程细节里最”没人喜欢但必须守”的一类:规则本身三句话讲完,破坏力却藏在小端与大端的每次跨界。纪律化做法是——任何数据在工具链里明确标注一次”我是什么序”,跨层时只做一次且可复验的倒序,测试里放一笔已知答案的交易双向核对。养成这个习惯,比在事故现场逐字节瞪十六进制便宜得多。
六、默克尔证明里的顺序细节
SPV 验证与 gettxoutproof 生成的默克尔证明同样被字节序贯穿:证明载荷里列出的哈希节点取自区块默克尔树,是按内部小端口径原样摆放还是按显示序倒放,不同实现历来有分歧,写校验器时要以规范测试向量为锚——先构造一棵已知答案的树,把”我的拼接顺序”与”官方的拼接顺序”在树根上对齐一次,之后所有路径都走这套内部表示,只在最外层展示时统一倒序。顺带复习一个易混点:默克尔树节点对两个子节点做双 SHA-256 前不做任何倒序,“左右顺序”由位置决定而非字节序决定。把这些口径固化成库函数的构造函数,让调用方在类型层面就无法把”显示序”塞进”线序”,是避免整类事故的工程解。字节序这堂课的最大启示其实是:协议里凡是”给人看的”和”给机器算的”共用同一串十六进制时,就一定存在一个没人明说的转换约定——把它显式化,是每个工具作者的义务。
发表评论
还没有评论,来说两句吧。
评论区为展示样式,提交不会被处理。