• 比特币指令集


    比特币指令集

    本文主要译自比特币 wiki

    约定

    • 数字是小端编码,也就是遵循英特尔处理器的规则
    • 整数的编码规则是最高位表示付好,对于一个字节的整数,0x81表示-1,0x80表示负0,0x03 表示3,0x83表示-3
    • 0表示 False, 其他表示 True

    常数指令

    名字 指令 十六进制 输入 输出 描述
    OP_0 0 0X00 nothing nothing 在站上放置一个空数组
    N/A 1-75 0x01-0x4b special data 指令支出后面有多少字节数据需要放置到栈上,比如03 01 02 03,03意味着后面有三个字节的数据01 02 03 需要放置到栈上,01 02 03就是执行后的栈顶数据
    OP_PUSHDATA1 76 0x4c special 数据 输入输出长度均不固定,0x4c 后面的第一个字节表示后面数据的长度比如以下指令 0x4c020102,执行完以后,栈顶为01 02
    OP_PUSHDATA2 77 0x4d special 数据 输入输出长度均不固定,0x4d 后面的两个字节表示后面数据的长度比如以下指令 0x4d00010001....ff,执行完以后,栈顶为0001....feff, 栈顶有256字节的数据,这些数据分别是00...ff
    OP_PUSHDATA4 78 0x4e special 数据 输入输出长度均不固定,0x4e 后面的四个字节表示后面数据的长度比如以下指令 0x4e000000010001....ff,其中4e 后面的00000001表示长度为2^24字节, 目前应该用不到,因为这远超出了一块的大小,是不允许的
    OP_1NEGATIVE 79 0X4F -1 将数值-1放在栈顶,比特币的虚拟机是多少位的?
    OP_1,OP_TRUE 81 0x51 1 将数值1放在栈顶
    OP_2-OP_16 82-96 0X52-0X60 2-16 将数值2-16放置在栈顶

    流程控制

    名字 指令 十六进制 输入 输出 描述
    OP_NOP 97 0x61 就是一般的 nop 指令
    OP_IF 99 0X63 True/false <expression> if [statements] [else [statements1]] endif 移除栈顶,如果为真, statements 将会被执行
    OP_NOTIF 100 0X64 True/false <expression> notif [statements] [else [statements1]] endif 移除栈顶,如果为假, statements 将会被执行
    OP_ELSE 103 0X67 True/false <expression> notif [statements] [else [statements1]] endif 移除栈顶,如果为假, statements1 将会被执行
    OP_ENDIF 104 0X68 True/false <expression> notif [statements] [else [statements1]] endif 主要用来标记if语句的结束
    OP_verify 105 0X69 True/false空 移除栈顶,如果为假,交易直接标记为失败,为真,继续执行指令.
    OP_RETURN 106 0x6a 交易失败 虚拟机执行到此,标记交易失败.因此如果一个交易的输出有 OP_RETURN, 那么意味着这是一个永远有效的 UTXO,谁也无法花费. 可以将此 UTXO value设置为0,用来记录一些特殊数据
    OP_IF OP_ELSE示例

    
    假设初始栈,自顶向下

    graph TD A[栈底部<br/>ff<br/>fe<br/>fd<br/>]

    指令如下:
    OP_1 OP_IF OP_2 OP_3 OP_ELSE OP_4 OP_5 OP_ENDIF
    我们一步一步来看一下栈和指令的变化

    1. OP_1

    栈:

    graph TD A[栈底部<br/>ff<br/>fe<br/>fd<br/>1]

    指令:
    OP_IF OP_2 OP_3 OP_ELSE OP_4 OP_5 OP_ENDIF

    2. OP_IF

    栈:

    graph TD A[栈底部<br/>ff<br/>fe<br/>fd]

    指令:
    OP_2 OP_3 OP_ELSE OP_4 OP_5 OP_ENDIF

    因为条件为真,因此执行 OP_2 OP_3这两条语句,不执行 OP_4 OP_5.

    3. OP_2 OP_3

    栈:

    graph TD A[栈底部<br/>ff<br/>fe<br/>fd<br/>2<br/>3]

    指令:
    OP_ELSE OP_4 OP_5 OP_ENDIF

    4. OP_2 OP_3

    栈:

    graph TD A[栈底部<br/>ff<br/>fe<br/>fd<br/>2<br/>3]

    指令:

    因为执行了 OP_IF else 模块不执行.

    栈相关指令

    名字 指令 十六进制 输入 输出 描述
    OP_TOALTSTACK 107 0x6b x1 (alt)x1 移动主栈栈顶数据到附加栈, 完全不清楚为什么比特币执行会有两个栈,在什么地方用呢
    OP_FROMALTSTACK 108 0x6c (alt)x1 x1 移动附加栈栈顶数据到主栈
    OP_IFDUP 115 0x73 x x/xx 如果 x 非0,栈上会有两份 x, 否则 什么都不做(栈不变化)
    OP_DEPTH 116 0x74 栈高度 将栈上有多少数据信息放到栈顶
    OP_DROP 117 0x75 x 丢弃栈顶数据
    OP_DUP 118 0x76 x x x 复制栈顶数据
    OP_NIP 119 0x77 x1 x2 x2 移除栈顶上面的一项
    OP_OVER 120 0x78 x1 x2 x1 x2 x1 复制栈第二项到栈顶
    OP_PICK 121 0x79 xn...x2 x1 x0 <n> xn ... x2 x1 x0 xn 复制栈第 n 项到栈顶,这个 n 最大可以多大呢?
    OP_ROLL 122 0x7a xn... x2 x1 <n> ... x2 x1 x0 xn 移动栈第 n 项到栈顶
    OP_ROT 123 0x7b x1 x2 x3 x2 x3 x1 旋转栈前三项相当于把第三项移到栈顶
    OP_SWAP 124 0x7c x1 x2 x2 x1 将栈顶两项互相交换
    OP_TUCK 125 0x7d x1 x2 x2 x1 x2 将栈顶复制一份到第二项之上
    OP_2DROP 109 0x6d x1 x2 移除栈顶两项
    OP_2DUP 110 0x6e x1 x2 x1 x2 x1 x2 复制栈顶两项
    OP_3DUP 111 0x6f x1 x2 x3 x1 x2 x3 x1 x2 x3 复制栈顶三项
    OP_2OVER 112 0x70 x1 x2 x3 x4 x1 x2 x3 x4 x1 x2 复制栈第三第四项到栈顶
    OP_2ROT 113 0x71 x1 x2 x3 x4 x5 x6 x3 x4 x5 x6 x1 x2 移动栈第第五第六项到栈顶
    OP_2SWAP 114 0x72 x1 x2 x3 x4 x3 x4 x1 x2 交换栈顶一对数据

    关于栈描述,栈是按照从左至右表示栈底到栈顶. 以OP_2ROT 为例,
    输入:
    x1 x2 x3 x4 x5 x6
    栈顶是 x6,第二项是 x5,以此类推,第六项是 x1
    执行完输出为:
    x3 x4 x5 x6 x1 x2
    栈顶是 x2,第二项是x1,以此类推,第六项是x3

    字符串相关指令

    名字 指令 描述
    OP_CAT 126 已禁用,碰到此指令,交易直接失败
    OP_SUBSTR 127 已禁用,碰到此指令,交易直接失败
    OP_LEFT 128 已禁用,碰到此指令,交易直接失败
    OP_RIGHT 129 已禁用,碰到此指令,交易直接失败
    OP_SIZE 130 将栈上字符串的长度放到栈顶(不会弹出字符串)

    位运算

    名字 指令 十六进制 输入 输出 描述
    OP_INVERT 131 0x83 已禁用,碰到此指令,交易直接失败
    OP_AND 132 0x84 已禁用,碰到此指令,交易直接失败
    OP_OR 133 0x85 已禁用,碰到此指令,交易直接失败
    OP_XOR 134 0x86 已禁用,碰到此指令,交易直接失败
    OP_EQUAL 135 0x87 x1 x2 TRUE/false 弹出栈顶两个数据,如果相等,放置1到栈顶,否则放置0到栈顶
    OP_EQUALVERIFY 136 0x88 x1 x2 弹出栈顶两个数据,如果不等,交易直接失败,否则什么都不做.

    算术运算

    比特币不再支持乘除运算,碰到这样的指令,必须失败.这些指令就不列出了.
    这些指令包括乘法指令(OP_MUL,OP_2MUL),除法指令(OP_DIV,OP_2DIV,OP_MOD),移位指令( OP_LSHIFT,OP_RSHIFT)

    名字 指令 十六进制 输入 输出 描述
    OP_1ADD 139 0x8b x x+1 栈顶数据加1
    OP_1SUB 140 0x8c x x-1 栈顶数据减1
    OP_NEGATE 143 0x8f x -x 符号取反
    OP_ABS 144 0x90 x abs(x) 求栈顶的绝对值,弹出 x, 压入 x 的绝对值
    OP_NOT 145 0x91 x not(x) x 转换位逻辑真假,然后取反,比如3,相当于真, not 以后为0
    OP_0NOTEQUAL 146 0x92 in out 返回0,如果输入为0,否则1. 这条指令看不懂什么意思,怎么用
    OP_ADD 147 0x93 a b a+b 求和
    OP_SUB 148 0x94 a b a-b 求差
    OP_BOOLAND 154 0x9a a b a && b 如果 a b 都不是""(空字符串),输出为1,否则为0
    OP_BOOLOR 155 0x9b a b a or b 如果 a 或者 b 不是"",输出为1,否则为0
    OP_NUMEQUAL 156 0x9c a b a==b 弹出a,b 如果相等,放置1到栈顶,否则放置0
    OP_NUMEQUALVERIFY 157 0x9d a b nothing/fail 如果 a,b 不等,交易失败,否则什么都不做
    OP_NUMNOTEQUAL 158 0x9e a b a!=b 如果 a,b 不等,栈顶放1,否则放0
    OP_LESSTHAN 159 0x9f a b a<b a 是否小于 b
    OP_GREATERTHAN 160 0xa0 a b a>b a 是否大于 b
    OP_LESSTHANOREQUAL 161 0xa1 a b a<=b a 是否小于等于 b
    OP_GREATERTHANOREQUAL 162 0xa2 a b a>=b a 是否大于等于 b
    OP_MIN 163 0xa3 a b a<b?a:b 弹出 a,b ,然后在栈顶放较小的
    OP_MAX 164 0xa4 a b a>b?a:b 弹出 a,b,然后放较大的
    OP_WITHIN 165 0xa5 x a b true/false 弹出 x,a,b,如果 x 介于 a,b 之间,放1,否则放0

    密码学指令

    名字 指令 十六进制 输入 输出 描述
    OP_RIPEMD160 166 0xa6 in hash hash=RIPEMD160(in), 问题是如何知道 in 的长度是多少呢?怎么界定?
    OP_SHA1 167 0xa7 in hash 求sha1.
    OP_SHA256 168 0xa8 in hash 求sha256
    OP_HASH160 169 0xa9 in hash ripemd160(sha256(in))
    OP_HASH256 170 0xaa in hash sha256(sha256(in))
    OP_CODESEPARATOR 171 0xab Nothing Nothing 代码数据分隔符.
    OP_CHECKSIG 172 0xac sig pubkey True / false 弹出 signature,pubkey, 验证两者是否匹配. 至于签名内容包含什么,可以参考我另一篇博客比特币 解锁脚本signature script 包含了那些东西
    OP_CHECKSIGVERIFY 173 0xad sig pubkey Nothing / fail 和前一条指令功能相同,如果验证为假,那么交易直接失败
    OP_CHECKMULTISIG 174 0xae x sig1 sig2 ... pub1 pub2 True / False 多重签名验证 , 弹出的数据根据 n/m 来确定.
    OP_CHECKMULTISIGVERIFY 175 0xaf x sig1 sig2 ... pub1 pub2 ... Nothing / fail 先做OP_CHECKMULTISIG, 然后执行OP_VERIFY

    LockTime

    名字 指令 十六进制 输入 输出 描述
    OP_CHECKLOCKTIMEVERIFY (previously OP_NOP2) 177 0xb1 x x / fail 基本功能就是为了阻止 TxOut 只能在某个绝对块数之后被花出,比如30000 OP_CHECKLOCKTIMEVERIFY DROP ...表示30000块之后后续脚本才有可能成功,否则必定失败. 详细功能参考 BIP 0065.
    OP_CHECKSEQUENCEVERIFY (previously OP_NOP3) 178 0xb2 x x / fail 使用 TxIn中的 nSequence 中的作为相对块数,表示只能在花费的那个UTXO 被挖矿nSequence块以后才能花费那个 UTXO.详细参考 BIP 0112.

    关于OP_CHECKLOCKTIMEVERIFY的一个示例

        IF
            <now + 3 months> CHECKLOCKTIMEVERIFY DROP
            <Lenny's pubkey> CHECKSIGVERIFY
            1
        ELSE
            2
        ENDIF
        <Alice's pubkey> <Bob's pubkey> 2 CHECKMULTISIG
    

    上面的脚本中< now+3 months> 就是一个从现在起,推算出来的一个绝对块数,比如现在是5000000块,那么三个月以后就是5012960块

    那么解锁脚本是什么呢,有两种情况
    一种是三个月以后,使用Alice或者 Bob 的签名,加上 Lenny 的签名
    一种是随时用Alice和 Bob 的签名

    第一种情况,解锁脚本是
    0 <Alice/Bob's signature> <Lenny's signature> 1
    

    解锁脚本从左到右一次压栈,

    1. 1表示走上面的分支
    2. 验证是否是三个月以后了
    3. 第一个 CHECKSIGVERIFY验证Lenny的签名是否正确
    4. 第二个CHECKMULTISIG输入是 0 <Alice/Bob's signature> 1 <Alice's pubkey> <Bob's pubkey> 2 CHECKMULTISIG ,因此随便 Alice/Bob 的一个有效签名都可以花费该 UTXO
    第二种情况解锁脚本
    0 <Alice's signature> <Bob's signature> 0
    
    1. 0表示走下面的分支
    2. 也就是一个2-2的多重签名验证,因此需要 Alice/Bob 都签名才可以.
  • 相关阅读:
    red hat linux下安装mysql
    oracle数据库sys与system默认密码
    eclipse 创建maven web项目
    mysql-5.7.17-winx64的安装配置
    有趣的浏览器地址栏JavaScript代码
    jsp自定义标签Tag
    exp:CollectionSecurity must be empty, but is not; jsp自定义标签异常
    java中&与&&的区别
    解决springmvc在multipart/form-data方式提交请求在过滤器Filter中获取不到参数的问题
    java itextpdf使用HTML模板生成pdf文件,并设置table
  • 原文地址:https://www.cnblogs.com/baizx/p/9476013.html
Copyright © 2020-2023  润新知