BTC 节点执行验证的关键点梳理
一、节点执行校验过程——关键点分析
1. 校验解锁数据和脚本合法性
节点首先要确认输入端(scriptSig)与输出端(scriptPubKey)数据结构正确无误,如签名数量、公钥格式、脚本本身的操作长度等,防止直接剧本攻击或格式错误。
2. 校验P2SH哈希是否匹配
对于P2SH输入(多签常用),节点必须把你在解锁时提供的赎回脚本哈希后,与原来这笔UTXO的地址锁定值对比,看是不是你声称的那个条件,否则直接判为无效。
3. 执行赎回脚本并校验签名
节点严格依次执行你提供的赎回脚本,检查里面指定的M-of-N名公钥是否能被你的签名数和签名内容匹配正确解锁。
如果是多签,还涉及“签名与公钥”的一一检验,避免乱序或错误次数。
4. 防止重放与二次花费
节点还必须确保输入所引用的UTXO没被花过,即校验花费的UTXO是否还是“未花费状态”,双花不成立。
5. 校验签名消息内容
签名不是针对随机数据签,而是对“本次新交易关键信息哈希”进行签名,确保提交签名不能用于别处,提高交易不可抵赖性。
6. 最终脚本是否返回True
整个解锁+锁定脚本按比特币Script机理跑完后,只有栈顶为真(非零),节点才认定“这笔UTXO花费成功”,否则就是无效。
二、举例流程:2-3多签校验全过程
三人多签(类似上面例子)——Alice/Carol打算花,流程如下:
1. 解锁脚本(scriptSig)如下
<OP_0> <Alice签名> <Carol签名> <赎回脚本>
其中赎回脚本形如:
2 <Alice公钥> <Bob公钥> <Carol公钥> 3 OP_CHECKMULTISIG
2. 节点校验全流程
(1) 首先格式检查
各个元素字节长度、签名是否合规格式、公钥有效、公钥能否解压等;
赎回脚本整体不超大小上限、不含未认可操作码等。
(2) 校验P2SH哈希
对你 scriptSig 里的
<赎回脚本>
做HASH160,结果应等于你当前 UTXO scriptPubKey 的 20字节哈希。如果不一致,立刻终止。
(3) 按脚本堆栈合并执行
先“推入签名”,再推入原始多签脚本,执行多签判定。
(4) OP_CHECKMULTISIG操作解析
检查有2个签名,3个公钥;
依次验证两个签名是否对这3个公钥中两个能成功验签,且两者不能用同一个公钥或伪数据混骗,按“最左优先”方式配对从公钥列表找能通过的即可。
(5) 校验签名消息内容
每个签名本质是过
(sighash)
,节点会重组当前交易,构造sighash内容,然后用对应公钥验签。
(6) UTXO是否真的未花
查看 UTXO 集合,这一笔是否还未被其他交易引用过,不能被重复花费。
(7) 脚本栈顶为True判定
如果上述全部通过,则脚本执行返回True(1),此UTXO被花成功,否则交易被丢弃。
三、实际案例中的重要点举例
场景1:签名伪造检测
如果有人提供了无效的签名或顺序错误,比如拿Bob公钥签名配Carol的签名,节点会校验每一对签名与公钥是否匹配,发现无效立即停止检查报错。
场景2:赎回脚本伪造检测
攻击者伪造一个与原哈希不符的赎回脚本,节点Hash比较直接淘汰。
场景3:脚本引擎执行完栈顶非真
如签名少于要求数量,或者签名内容格式被篡改等,脚本最后栈顶不是“真”值,直接判为无效。
四、经典流程图
提供签名/公钥等数据
↓
格式校验(公钥/签名/脚本)
↓
赎回脚本哈希匹配P2SH锁定
↓
逐一验签,达到M-of-N规则
↓
sighash数据一致性串通校验
↓
脚本执行最终True判为合法