layout: specification
title: Restore disabled script opcodes, May 2018
category: spec
date: 2018-04-05
activation: 1526400000
version: 0.4
updated: 2018-05-23
In 2010 and 2011 the discovery of serious bugs prompted the deactivation of many opcodes in the Bitcoin script language.
It is our intention to restore the functionality that some of these opcodes provided in Bitcoin Cash.
Rather than simply re-enable the opcodes, the functionality that they provide has been re-examined and in some cases the opcodes have been re-designed or new opcodes have been added to address specific issues.
This document contains the specifications for the opcodes that are to be added in the May 2018 protocol upgrade.
We anticipate that additional opcodes will be proposed for the November 2018, or later, protocol upgrades.
The opcodes that are to be added are:
Word | OpCode | Hex | Input | Output | Description |
---|---|---|---|---|---|
OP_CAT | 126 | 0x7e | x1 x2 | out | Concatenates two byte sequences |
OP_SPLIT | 127 | 0x7f | x n | x1 x2 | Split byte sequence x at position n |
OP_AND | 132 | 0x84 | x1 x2 | out | Boolean AND between each bit of the inputs |
OP_OR | 133 | 0x85 | x1 x2 | out | Boolean OR between each bit of the inputs |
OP_XOR | 134 | 0x86 | x1 x2 | out | Boolean EXCLUSIVE OR between each bit of the inputs |
OP_DIV | 150 | 0x96 | a b | out | a is divided by b |
OP_MOD | 151 | 0x97 | a b | out | return the remainder after a is divided by b |
OP_NUM2BIN | 128 | 0x80 | a b | out | convert numeric value a into byte sequence of length b |
OP_BIN2NUM | 129 | 0x81 | x | out | convert byte sequence x into a numeric value |
Splice operations: OP_CAT
, OP_SPLIT
**
Bitwise logic: OP_AND
, OP_OR
, OP_XOR
Arithmetic: OP_DIV
, OP_MOD
New operations:
x OP_BIN2NUM -> n
, convert a byte sequence x
into a numeric valuen m OP_NUM2BIN -> out
, convert a numeric value n
into a byte sequence of length m
Further discussion of the purpose of these new operations can be found below under bitwise operations.
** A new operation, OP_SPLIT
, has been designed as a replacement for OP_SUBSTR
, OP_LEFT
and OP_RIGHT
.
The original operations can be implemented with varying combinations of OP_SPLIT
, OP_SWAP
and OP_DROP
.
It should be noted that in script operation data values on the stack are interpreted as either byte sequences or numeric values.
All data on the stack is interpreted as a byte sequence unless specifically stated as being interpreted as a numeric value.
For accuracy in this specification, a byte sequences is presented as {0x01, 0x02, 0x03}.
This sequence is three bytes long, it begins with a byte of value 1 and ends with a byte of value 3.
The numeric value type has specific limitations:
The new opcode x OP_BIN2NUM -> out
can be used convert a byte sequence into a numeric value where required.
The new opcode x n OP_NUM2BIN
can be used to convert a numeric value into a zero padded byte sequence of length n
whilst preserving the sign bit.
x1 x2 OP_CAT
--> x2
is the top stack item and x1
is the next from the top.OP_0
is used as a convenient representation of an empty byte sequence.Global conditions apply to all operations.
These conditions must be checked by the implementation when it is possible that they will occur:
0 <= len(e) <= MAX_SCRIPT_ELEMENT_SIZE
These unit tests should be included for every operation:
MAX_SCRIPT_ELEMENT_SIZE
will failIn all cases where not explicitly stated otherwise the operand stack elements are consumed by the operation and replaced with the output.
Opcode (decimal): 126
Opcode (hex): 0x7e
Concatenates two operands.
x1 x2 OP_CAT -> out
Examples:
{Ox11} {0x22, 0x33} OP_CAT -> 0x112233
The operator must fail if len(out) > MAX_SCRIPT_ELEMENT_SIZE
.
The operation cannot output elements that violate the constraint on the element size.
Note that the concatenation of a zero length operand is valid.
Impact of successful execution:
The limit on the length of the output prevents the memory exhaustion attack and results in the operation having less impact on stack size than existing OP_DUP operators.
Unit tests:
maxlen_x y OP_CAT -> failure
.OP_1
), onto a maximum sized array causes failurelarge_x large_y OP_CAT -> failure
.MAX_SCRIPT_ELEMENT_SIZE
, causes failureOP_0 OP_0 OP_CAT -> OP_0
.x OP_0 OP_CAT -> x
.len(x) = MAX_SCRIPT_ELEMENT_SIZE
OP_0 x OP_CAT -> x
.len(x) = MAX_SCRIPT_ELEMENT_SIZE
x y OP_CAT -> concat(x,y)
.OP_SPLIT
replaces OP_SUBSTR
and uses it’s opcode.
Opcode (decimal): 127
Opcode (hex): 0x7f
Split the operand at the given position.
This operation is the exact inverse of OP_CAT
x n OP_SPLIT -> x1 x2
where n is interpreted as a numeric value
Examples:
{0x00, 0x11, 0x22} 0 OP_SPLIT -> OP_0 {0x00, 0x11, 0x22}
{0x00, 0x11, 0x22} 1 OP_SPLIT -> {0x00} {0x11, 0x22}
{0x00, 0x11, 0x22} 2 OP_SPLIT -> {0x00, 0x11} {0x22}
{0x00, 0x11, 0x22} 3 OP_SPLIT -> {0x00, 0x11, 0x22} OP_0
Notes:
OP_SUBSTR
, OP_LEFT
and OP_RIGHT
.OP_SPLIT
, OP_SWAP
and OP_DROP
.x
is split at position n
, where n
is the number of bytes from the beginningx1
will be the first n
bytes of x
and x2
will be the remaining bytesn == 0
, then x1
is the empty array and x2 == x
n == len(x)
then x1 == x
and x2
is the empty array.n > len(x)
, then the operator must fail.x n OP_SPLIT OP_CAT -> x
, for all x
and for all 0 <= n <= len(x)
The operator must fail if:
!isnum(n)
.n
is not a numeric value.n < 0
.n
is negative.n > len(x)
.n
is too high.Impact of successful execution:
len(n)
)Unit tests:
OP_0 0 OP_SPLIT -> OP_0 OP_0
.x 0 OP_SPLIT -> OP_0 x
x len(x) OP_SPLIT -> x OP_0
x (len(x) + 1) OP_SPLIT -> FAIL
The bitwise logic operators expect ‘byte sequence’ operands.
The operands must be the same length.
OP_CAT
can be used to pad a shorter byte sequence to an appropriate length.OP_CAT
) can be produced using OP_0 n OP_NUM2BIN
x n OP_NUM2BIN
can be used to pad a numeric value to length n
whilst preserving the sign bit.Opcode (decimal): 132
Opcode (hex): 0x84
Boolean and between each bit in the operands.
x1 x2 OP_AND -> out
Notes:
len(x1) == 0
and len(x2) == 0
the output will be an empty array.The operator must fail if:
len(x1) != len(x2)
.Impact of successful execution:
len(x1)
Unit tests:
x1 x2 OP_AND -> failure
, where len(x1) != len(x2)
.x1 x2 OP_AND -> x1 & x2
.Opcode (decimal): 133
Opcode (hex): 0x85
Boolean or between each bit in the operands.
x1 x2 OP_OR -> out
The operator must fail if:
len(x1) != len(x2)
.Impact of successful execution:
len(x1)
Unit tests:
x1 x2 OP_OR -> failure
, where len(x1) != len(x2)
. The two operands must be the same size.x1 x2 OP_OR -> x1 | x2
. Check valid results.Opcode (decimal): 134
Opcode (hex): 0x86
Boolean xor between each bit in the operands.
x1 x2 OP_XOR -> out
The operator must fail if:
len(x1) != len(x2)
.Impact of successful execution:
len(x1)
Unit tests:
x1 x2 OP_XOR -> failure
, where len(x1) != len(x2)
.x1 x2 OP_XOR -> x1 xor x2
.Operands for all arithmetic operations are assumed to be numeric values and must be in canonical form
See data types for more information.
Note that when considering integer division and modulo operations with negative operands, the rules applied in the C language and most languages (with Python being a notable exception) differ from the strict mathematical definition.
Script follows the C language set of rules.
Namely:
(a/b)*b + a%b == a
is satisfied by the resultsa%b == a - (a/b)*b
a
is negative for the modulo operator the result will be negative or zero.Opcode (decimal): 150
Opcode (hex): 0x96
Return the integer quotient of a
and b
.
If the result would be a non-integer it is rounded towards zero.
a b OP_DIV -> out
where a and b are interpreted as numeric values
The operator must fail if:
!isnum(a) || !isnum(b)
.b == 0
.b
is equal to any type of zero.Impact of successful execution:
Unit tests:
a b OP_DIV -> failure
where !isnum(a)
or !isnum(b)
.a 0 OP_DIV -> failure
.OP_0
27 7 OP_DIV -> 3
, 27 -7 OP_DIV -> -3
, -27 7 OP_DIV -> -3
, -27 -7 OP_DIV -> 3
.0..4
Opcode (decimal): 151
Opcode (hex): 0x97
Returns the remainder after dividing a by b.
The output will be represented using the least number of bytes required.
a b OP_MOD -> out
where a and b are interpreted as numeric values
The operator must fail if:
!isnum(a) || !isnum(b)
.b == 0
.b
is equal to any type of zero.Impact of successful execution:
Unit tests:
a b OP_MOD -> failure
where !isnum(a)
or !isnum(b)
.a 0 OP_MOD -> failure
.OP_0
27 7 OP_MOD -> 6
, 27 -7 OP_MOD -> 6
, -27 7 OP_MOD -> -6
, -27 -7 OP_MOD -> -6
.0..4
and returning result zeroOP_NUM2BIN
replaces OP_LEFT
and uses it’s opcode
Opcode (decimal): 128
Opcode (hex): 0x80
Convert the numeric value into a byte sequence of a certain size, taking account of the sign bit.
The byte sequence produced uses the little-endian encoding.
a b OP_NUM2BIN -> x
where a
and b
are interpreted as numeric values.
a
is the value to be converted to a byte sequence,
it can be up to MAX_SCRIPT_ELEMENT_SIZE
long and does not need to be minimally encoded.
b
is the desired size of the result, it must be minimally encoded and <= 4 bytes long.
It must be possible for the
value a
to be encoded in a byte sequence of length b
without loss of data.
See also OP_BIN2NUM
.
Examples:
2 4 OP_NUM2BIN -> {0x02, 0x00, 0x00, 0x00}
-5 4 OP_NUM2BIN -> {0x05, 0x00, 0x00, 0x80}
The operator must fail if:
b
is not a minimally encoded numeric value.b < len(minimal_encoding(a))
.a
must be able to fit into b
bytes.b > MAX_SCRIPT_ELEMENT_SIZE
.Impact of successful execution:
b - len(a) - len(b)
, maximum increase is when b = MAX_SCRIPT_ELEMENT_SIZE
Unit tests:
a b OP_NUM2BIN -> failure
where !isnum(b)
.b
must be a minimally encoded numeric value.256 1 OP_NUM2BIN -> failure
.1 (MAX_SCRIPT_ELEMENT_SIZE+1) OP_NUM2BIN -> failure
.OP_BIN2NUM
replaces OP_RIGHT
and uses it’s opcode
Opcode (decimal): 129
Opcode (hex): 0x81
Convert the byte sequence into a numeric value, including minimal encoding.
The byte sequence must encode the value in little-endian encoding.
a OP_BIN2NUM -> x
See also OP_NUM2BIN
.
Notes:
a
is any form of zero, including negative zero, then OP_0
must be the resultExamples:
{0x02, 0x00, 0x00, 0x00, 0x00} OP_BIN2NUM -> 2
.0x0200000000
in little-endian encoding has value 2.{0x05, 0x00, 0x80} OP_BIN2NUM -> -5
- 0x050080
in little-endian encoding has value -5.The operator must fail if:
1.the numeric value is out of the range of acceptable numeric values (currently size is limited to 4 bytes)
Impact of successful execution:
Unit tests:
a OP_BIN2NUM -> failure
, when a
is a byte sequence whose numeric value is too large to fit into the numeric value type, for both positive and negative values.{0x00} OP_BIN2NUM -> OP_0
.{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} OP_BIN2NUM -> 1
.{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80} OP_BIN2NUM -> -1
.{0x80} OP_BIN2NUM -> OP_0
.{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80} OP_BIN2NUM -> OP_0
.OP_AND, OP_OR, OP_XOR: https://reviews.bitcoinabc.org/D1211
OP_DIV and OP_MOD: https://reviews.bitcoinabc.org/D1212
OP_SPLIT: https://reviews.bitcoinabc.org/D1228
OP_BIN2NUM: https://reviews.bitcoinabc.org/D1220
OP_NUM2BIN: https://reviews.bitcoinabc.org/D1222