区块链-多重签名中CHECKMULTISIG执行中的bug
2019-05-21 19:14
746 查看
目录:https://blog.csdn.net/qq_40452317/article/details/89646633
来看看多重签名(https://blog.csdn.net/qq_40452317/article/details/90412143)一个例子,比特币的正确的验证脚本如下:
[code]0 <Signature B> <Signature C> 2 <Public Key A> <Public Key B> <Public Key C> 3 CHECKMULTISIG
对比多重签名中的验证脚本会发现,这个正确的验证脚本前面多了个0,这个0是什么回事?
这是因为在CHECKMULTISIG的执行中有一个bug,来看看这个bug是怎么产生的。
[code]<Signature B> <Signature C> 2 <Public Key A> <Public Key B> <Public Key C> 3 CHECKMULTISIG
首先根据“错误”的脚本,CHECKMULTISIG弹出最上面的项目,这是N(在这个例子中N是“3”)。
然后它弹出N个项目,这是可以签名的公钥。在这个例子中,公钥 A,B 和C。
然后, 它弹出一个项目,即M,仲裁(需要多少个签名)。这里M=2。此时, CHECKMULTISIG应弹出最终的 M 个项目,这些是签名,并查看它们是否有效。
然而,不幸的是,实施中的错误导致CHECKMULTISIG再弹出一个项目(总共M+1个)。检查签名时,不考虑额外的项目,因此它对CHECKMULTISIG本身没有直接影响。但是,必须存在额外的值,因为如果不存在,则当CHECKMULTISIG尝试 弹出空堆栈时,会导致堆栈错误和脚本失败(将交易标记为无效)。因为额外的项目被忽略,它可以是任何东西,但通常使用0。
0取出后它被立刻丢去,并不用于之后的运算。这个数具体是什么值无关紧要,可堆栈上不能缺失它,不然无法正常执行CHECKMULTISIG。为了保证共识机制的向后兼容,每个解锁脚本就多压入一个零,而CHECKMULTISIG实现代码里的错误只能年复一年地遗留下来。
来看正确的脚本执行:
[code]0 <Signature B> <Signature C> 2 <Public Key A> <Public Key B> <Public Key C> 3 CHECKMULTISIG
解锁脚本是:
[code]0 <Signature B> <Signature C>
[code] // 首先运行解锁脚本 0: [] // 初始状态:空堆栈 1: [0] // 0 被压入栈顶 2: [0, 签名B] // PUSHDATA 入栈第一个签名 3: [0, 签名B, 签名C] // PUSHDATA 入栈第二个签名 4: [0, 签名B, 签名C, 脚本] // PUSHDATA 入栈完整脚本 // 复制堆栈后运行上锁脚本 5: [0, 签名B, 签名C, 脚本哈希] // HASH160 取出栈顶脚本,压入它的哈希 6: [0, 签名B, 签名C, 脚本哈希, 目标脚本哈希] // PUSHDATA 入栈目标脚本哈希 7: [0, 签名B, 签名C, TRUE] // EQUAL 取出栈顶两个哈希,判断是否相等,压入检测结果 // 取出栈顶结果,如果非真,则验证失败,否则运行原始脚本 8: [0, 签名B, 签名C] // 准备运行原始脚本 9: [0, 签名B, 签名C, 2] // 2 被压入栈顶 10: [0, 签名B, 签名C, 2, 公钥A] // PUSHDATA 入栈第一个公钥 11: [0, 签名B, 签名C, 2, 公钥A, 公钥B] // PUSHDATA 入栈第二个公钥 12: [0, 签名B, 签名C, 2, 公钥A, 公钥B, 公钥C] // PUSHDATA 入栈第三个公钥 13: [0, 签名B, 签名C, 2, 公钥A, 公钥B, 公钥C, 3] // 3 被压入栈顶 14: [0, 签名B, 签名C, 2, 公钥A, 公钥B, 公钥C] // CHECKMULTISIG 先取出公钥数N(3) 15: [0, 签名B, 签名C, 2] // 接着取出N(3)个公钥 16: [0, 签名B, 签名C] // 再取出签名数M(2) 17: [TRUE] // 接着取出M(2)个签名和数字0,根据交易验证签名,压入检查结果 // 栈顶为真则验证成功
相关文章推荐
- TinyOS bug程序的执行01(T-Check中的bug)
- 执行脚本时报-bash: ./checktom.sh: /bin/sh^M: bad interpreter: No such file or directory错
- Bug 14275161 - ORA-600 [rwoirw: check ret val] on CTAS with predicate move around
- 关于SQLServer2005的学习笔记——约束、Check、触发器的执行顺序
- 通过View.post()获取View的宽高引发的两个问题:1post的Runnable何时被执行,2为何View需要layout两次;以及发现Android的一个小bug
- Careless BugCheck
- 11. SQL -- 约束、Check、触发器的执行顺序
- RadioGroup调用check(id)方法时,onCheckedChanged方法被执行多次调用解决办法
- lepus监控redis执行python check_redis.py报错
- 错误的理解引起的bug async await 执行顺序
- eclipse中执行程序时报错'A JNI error has occurred,please check your installation and try again'
- bug笔记之——自执行函数与分号
- Android笔记:调用finish()后不能立即执行onDestroy()的BUG
- NMAP执行脚本smb-check-vulns.nse出错
- zepto.js tap 会执行两次的bug以及 Uncaught TypeError
- 区块链创业者试水MiaoA ATTS,执行保证计划,推动价值增长
- nagios 执行check_disk时报错“NRPE: Command 'check_disk' not defined
- 解决od复制到可执行文件中没有所有修改的bug
- SqlServer bug:sp_replqueuemonitor 在SqlServer 2008(RTM) 执行无结果
- embed tomcat bug:org.apache.catalina.connector.CoyoteAdapter checkRecycled