跳到正文

研究指南

加密现货研究

交易身份:区分txid与见证数据承诺

交易标识认证其哈希计算所覆盖的字节。对于SegWit序列化,txid与wtxid覆盖不同字节序列。比较浏览器导出、交易档案或包含证明时,必须保留这种区别:txid相同不证明两个文件的见证数据相同。

它也不证明任一文件能形成有效花费。序列化、标识计算、脚本有效性和已确认经济活动是四项检查。下面特意构造的字节样本只检验前两项,不是实际付款。

比较哈希前,先命名序列化

BIP141的Transaction ID部分分别定义传统序列化得到的txid与含见证序列化得到的wtxid,其Commitment structure部分解释区块通过coinbase交易另行承诺见证。因此,不能把按txid形成的普通交易Merkle路径说成直接覆盖了全部见证字节。

保留原始对象与两个完整标识,说明来源提供的是剥离见证的序列化,还是完整版本。去掉见证的导出可能足以定位输出,却不够检查具体见证。不能从可读函数名或浏览器标签重建缺失字节;哈希也不会替研究者恢复原始材料。

对照两个来源时,先比较对象覆盖,再评价冲突。否则一个保存基础交易、另一个保存完整交易,就会被错误归为链上数据矛盾,而真正区别只是导出范围。

可复算的字节样本

构造一个虚构序列化:版本二、一个引用重复占位哈希的输入、一个输出、锁定时间零。前序输出未被建立,见证故意只有一个虚拟字节项,因此不具备真实授权,不能被当作可广播交易。

以下Python只用标准库。十六进制片段规定实际字节;金额先编码为八字节小端整数,不是把十进制数字当文本拼进哈希。显示标识时,将两次SHA256后的摘要字节反转。

import hashlib

def identifier(raw):
    first = hashlib.sha256(raw).digest()
    return hashlib.sha256(first).digest()[::-1].hex()

version = bytes.fromhex('02000000')
inputs = bytes.fromhex('01' + '11' * 32 + '00000000' + '00' + 'ffffffff')
end = bytes.fromhex('00000000')

def fixture(value, item):
    outputs = bytes.fromhex('01') + value.to_bytes(8, 'little')
    outputs += bytes.fromhex('16' + '0014' + '22' * 20)
    base = version + inputs + outputs + end
    full = version + bytes.fromhex('0001') + inputs + outputs
    full += bytes.fromhex('0101') + bytes([item]) + end
    return len(base), len(full), identifier(base), identifier(full)

for case in [(1000, 1), (1000, 2), (1001, 1)]:
    print(fixture(*case))

三个基础对象都是八十二字节,完整对象都是八十七字节。额外五字节包括marker、flag及三字节虚拟见证编码。明确构造是为了让读者分清“能解析和计算标识”与“签名及花费有效”,不能把这里的样本复制为真实资产操作。

解读三个计算结果

样本输出价值虚拟见证项txid前缀wtxid前缀
A一千聪01b91b72010378bb79fcaf4238
B一千聪02b91b720103783f1d4dfd0055
C一千零一聪01a5e34c11b070676ed39808f6

表格仅为排版缩短标识,真正核验应比较代码输出的完整值。A与B基础字节完全相同,因此txid相同;虚拟见证项不同,使含见证序列化与wtxid改变。C将输出价值改为一千零一聪,该字段存在于两种序列化,所以本样本两个标识都改变。

A到C的金额差是一聪,即零点零零零零零零零一BTC。这个算术差并非真实转账事实,因为样本没有有效前序输出和授权。计算验证的是覆盖关系,不是节点接纳、矿工打包或共识有效性。

如果把完整导出文件本身当成输入再加一次JSON包装,其文件哈希还会改变。那是另一层文件完整性,不能将它自动命名为txid或wtxid。保存编码规则,才能重做相同计算。

任意见证改动并非有效替代

真实见证必须满足前序输出和交易上下文适用的花费规则。翻转签名字节可能让花费无效,同时基础序列化仍不变。因此,“同txid、不同见证”不能升级为“两笔同样有效付款”。

分析真实候选时,需要前序输出脚本与验证上下文,分别检查对象只是被收到、成功解析、被节点接受、被区块包含,还是后来离开选定链。文件比较本身不包含这些状态。

输出改变也可能需要新的授权,并与原输入花费冲突。txid不同不是第二个独立经济事件的保证;合计前应检查共同outpoint和最终确认结果。这也是标识核验与内存池替换研究的衔接处。

边界例:导出剥离见证

假设档案只存基础序列化,另一来源交回完整对象。原始文件哈希不同,但正确计算的txid可能指向同一基础交易。这种差别不自动构成冲突,也不能仅因文件不同就重复统计付款。

不要用剥离字节计算一个所谓wtxid后标“已验证”。未取得所需完整序列化时,应将见证覆盖标为不可用。BIP141说明无见证输入交易存在wtxid等于txid的情形,但必须从实际对象建立该条件,不能拿特例掩盖见证材料缺失。

若后续取得完整对象,可以新增核验并连接原档案,保留早期覆盖说明。无需把早期可用的输出识别结果全部否定,但必须修正此前超出材料范围的见证结论。

样本核验的通过条件

复算时至少检查三条等式:A与B基础字节相等,A与B完整字节不等,A与C输出字段字节不等。再分别检查完整标识的相等关系,而不是只凭表中的短前缀。若字节关系正确但哈希前缀不符,先查摘要反转、十六进制解码和是否误把文本输入哈希。

将见证01改02只发生在故意构造的虚拟项,不能类推真实签名的有效替代。研究复现包应明确写“未验证花费授权”,并保留占位前序哈希的事实。若后续用真实链对象替换样本,需要重新核前序输出、授权与区块关系,而非沿用玩具样本状态。

导出文件如果只保存完整字节,可以从正确解析后的结构产生基础序列化;但不能靠盲目删除某几个偏移字节来处理所有交易,因为输入输出数量和脚本长度可变。解析与序列化版本应可追踪,避免样本恰好通过掩盖真实对象上的边界错误。

核验与发布表

检查保存材料能发现的错误
解析候选字节与解析器版本截断、不支持编码
分离序列化基础与完整字节序列把包装文件或剥离对象算错
重算标识完整txid、wtxid及显示顺序覆盖或端序错误
检查有效性前序输出与规则把虚拟或改坏见证当授权
检查结算区块身份与链状态把候选当已结算付款
统计活动输入关系与输出含义将替代候选当独立收款

完整字节补齐、标识更正或链状态改变后,应重开记录。最终句子说明比较了哪些字节、哪个标识相符,以及实际检查了什么有效性与结算证据。这样可以保留有用档案,而不把哈希计算夸大成经济事实认证。

常见问题

两个不同文件能共享txid吗?

可以,若区别不在txid所用基础序列化内,如本题虚拟见证样本。但两文件仍需各自有效性检查。

改见证是否总能得到另一笔有效交易?

不是。改动可能违反花费规则,标识计算不验证授权。

相关阅读