Bloodline's Blog Notes and thoughts from Bloodline

附录2 交易脚本语言操作符,常量和符号

以下的表和描述参见https://en.bitcoin.it/wiki/Script

表1.脚本压入堆栈

符号 值 (十六进制) 描述
OP_0 or OP_FALSE 0x00 一个字节空串被压入堆栈中
1-75 0x01-0x4b 把接下来的N 个字节压入堆栈中,N 的取值在1 到75 之间
OP_PUSHDATA1 0x4c 下一个脚本字节包括N,会将接下来的N 个字节压入堆栈
OP_PUSHDATA2 0x4d 下两个脚本字节包括N,会将接下来的N 个字节压入堆栈
OP_PUSHDATA4 0x4e 下四个脚本字节包括N,会将接下来的N 个字节压入堆栈
OP_1NEGATE 0x4f 将脚本-1 压入堆栈
OP_RESERVED 0x50 终止- 交易无效(除非在未执行的OP_IF语句中)
OP_1 or OP_TRUE 0x51 将脚本1 压入堆栈
OP_2 to OP_16 0x52 to 0x60 将脚本N 压入堆栈,例如OP_2 压入脚本“2”

表2.有条件的流控制的操作符

符号 值 (十六进制) 描述
OP_NOP 0x61 无操作
OP_VER 0x62 终止- 交易无效(除非在未执行的OP_IF 语句中)
OP_IF 0x63 如果栈项元素值为0,语句将被执行
OP_NOTIF 0x64 如果栈项元素值不为0,语句将被执行
OP_VERIF 0x65 终止- 交易无效
OP_VERNOTIF 0x66 终止- 交易无效
OP_ELSE 0x67 如果前述的OP_IF 或OP_NOTIF 或OP_ELSE 未被执行,这些语句就会被执行
OP_ENDIF 0x68 终止OP_IF, OP_NOTIF, OP_ELSE 区块
OP_VERIFY 0x69 如果栈项元素值非真,则标记交易无效
OP_RETURN 0x6a 标记交易无效

表3.时间锁操作符

符号 值 (十六进制) 描述
OP_CHECKLOCKTIMEVERIFY (previously OP_NOP2) 0xb1 如果栈顶元素比交易锁定时间字段大,则将交易标记为无效。否则脚本评测将像OP_NOP操作一样继续执行。交易在一下4种之一的情况下是无效的:1.堆栈是空的;2.栈顶元素是负数;3.当交易锁定时间字段值少于500000000时,栈顶元素大于等于500000000,反之亦然;4.输入序列字段等于0xffffffff。具体内容详见BIP-65。
OP_CHECKSEQUENCEVERIFY (previously OP_NOP3) 0xb2 如果输入值(BIP 0068强制规定的顺序)的相对锁定时间不等于或多于栈顶元素值时,将交易标记为无效。具体内容详见BIP-112。

表4.堆栈操作符

符号 值 (十六进制) 描述
OP_TOALTSTACK 0x6b 从主堆栈中取出元素,推入辅堆栈。
OP_FROMALTSTACK 0x6c 从辅堆栈中取出元素,推入主堆栈
OP_2DROP 0x6d 移除栈顶两个元素
OP_2DUP 0x6e 复制栈顶两个元素
OP_3DUP 0x6f 复制栈顶三个元素
OP_2OVER 0x70 把栈底的第三、第四个元素拷贝到栈顶
OP_2ROT 0x71 移动第五、第六元素到栈顶
OP_2SWAP 0x72 将栈顶的两个元素进行交换
OP_IFDUP 0x73 如果栈项元素值不为0,复制该元素值
OP_DEPTH 0x74 Count the items on the stack and push the resulting count
OP_DROP 0x75 删除栈顶元素
OP_DUP 0x76 复制栈顶元素
OP_NIP 0x77 删除栈顶的下一个元素
OP_OVER 0x78 复制栈顶的下一个元素到栈顶
OP_PICK 0x79 把堆栈的第n 个元素拷贝到栈顶
OP_ROLL 0x7a 把堆栈的第n 个元素移动到栈顶
OP_ROT 0x7b 翻转栈顶的三个元素
OP_SWAP 0x7c 栈顶的三个元素交换
OP_TUCK 0x7d 拷贝栈顶元素并插入到栈顶第二个元素之后

表5.字符串接操作

符号 值 (十六进制) 描述
OP_CAT 0x7e 连接两个字符串,已禁用
OP_SUBSTR 0x7f 返回字符串的一部分,已禁用
OP_LEFT 0x80 在一个字符串中保留左边指定长度的子串,已禁用
OP_RIGHT 0x81 在一个字符串中保留右边指定长度的子串,已禁用
OP_SIZE 0x82 把栈顶元素的字符串长度压入堆栈

表6.二进制算术和条件

符号 值 (十六进制) 描述
OP_INVERT 0x83 所有输入的位取反,已禁用
OP_AND 0x84 对输入的所有位进行布尔与运算,已禁用
OP_OR 0x85 对输入的每一位进行布尔或运算,已禁用
OP_XOR 0x86 对输入的每一位进行布尔异或运算,已禁用
OP_EQUAL 0x87 如果输入的两个数相等,返回1,否则返回0
OP_EQUALVERIFY 0x88 与OP_EQUAL 一样,如结果为0,之后运行OP_VERIFY
OP_RESERVED1 0x89 终止- 无效交易(除非在未执行的OP_IF 语句中)
OP_RESERVED2 0x8a 终止-无效交易(除非在未执行的OP_IF 语句中)

表7.数值操作

符号 值 (十六进制) 描述
OP_1ADD 0x8b 栈顶值加1
OP_1SUB 0x8c 栈顶值减1
OP_2MUL 0x8d 无效(栈顶值乘2)
OP_2DIV 0x8e 无效(栈顶值除2)
OP_NEGATE 0x8f 栈顶值符号取反
OP_ABS 0x90 栈顶值符号取正
OP_NOT 0x91 如果栈顶值为0 或1,则输出1或0;否则输出0
OP_0NOTEQUAL 0x92 输入值为0 输出0;否则输出1
OP_ADD 0x93 弹出栈顶的两个元素,压入二者相加结果
OP_SUB 0x94 弹出栈顶的两个元素,压入二者相减(第二项减去第一项)结果
OP_MUL 0x95 禁用(栈顶两项的积)
OP_DIV 0x96 禁用(输出用第二项除以第一项的倍数)
OP_MOD 0x97 禁用(输出用第二项除以第一项得到的余数)
OP_LSHIFT 0x98 禁用(左移第二项,移动位数为第一项的二进制位数)
OP_RSHIFT 0x99 禁用(右移第二项,移动位数为第一项的二进制位数)
OP_BOOLAND 0x9a 布尔与运算,两项都不为0,输出1,否则输出0
OP_BOOLOR 0x9b 布尔或运算,两项有一个不为0,输出1,否则输出0
OP_NUMEQUAL 0x9c 两项相等则输出1,否则输出为0
OP_NUMEQUALVERIFY 0x9d 与NUMEQUAL 相同,如结果为0运行OP_VERIFY
OP_NUMNOTEQUAL 0x9e 如果栈顶两项不是相等数的话,则输出1
OP_LESSTHAN 0x9f 如果第二项小于栈顶项,则输出1
OP_GREATERTHAN 0xa0 如果第二项大于栈顶项,则输出1
OP_LESSTHANOREQUAL 0xa1 如果第二项小于或等于第一项,则输出1
OP_GREATERTHANOREQUAL 0xa2 如果第二项大于或等于第一项,则输出1
OP_MIN 0xa3 输出栈顶两项中较小的一项
OP_MAX 0xa4 输出栈顶两项中较大的一项
OP_WITHIN 0xa5 如果第三项的数值介于前两项之间,则输出1

表8.加密和散列操作

符号 值 (十六进制) 描述
OP_RIPEMD160 0xa6 返回栈顶项的RIPEMD160 哈希值
OP_SHA1 0xa7 返回栈顶项SHA1 哈希值
OP_SHA256 0xa8 返回栈顶项SHA256 哈希值
OP_HASH160 0xa9 栈顶项进行两次HASH,先用SHA-256,再用RIPEMD-160
OP_HASH256 0xaa 栈顶项用SHA-256 算法HASH 两次
OP_CODESEPARATOR 0xab 标记已进行签名验证的数据
OP_CHECKSIG 0xac 交易所用的签名必须是哈希值和公钥的有效签名,如果为真,则返回1
OP_CHECKSIGVERIFY 0xad 与CHECKSIG 一样,但之后运行OP_VERIFY
OP_CHECKMULTISIG 0xae 对于每对签名和公钥运行CHECKSIG。所有的签名要与公钥匹配。因为存在BUG,一个未使用的外部值会从堆栈中删除。
OP_CHECKMULTISIGVERIFY 0xaf 与CHECKMULTISIG 一样,但之后运行OP_VERIFY

表9.非操作符

符号 值 (十六进制) 描述
OP_NOP1-OP_NOP10 0xb0-0xb9 无操作忽略

表10.仅供内部使用的保留关键字

符号 值 (十六进制) 描述
OP_SMALLDATA 0xf9 代表小数据域
OP_SMALLINTEGER 0xfa 代表小整数数据域
OP_PUBKEYS 0xfb 代表公钥域
OP_PUBKEYHASH 0xfd 代表公钥哈希域
OP_PUBKEY 0xfe 代表公钥域
OP_INVALIDOPCODE 0xff 代表当前未指定的操作码