09 - Bitwise transformations and Arithmetic
Last updated
Last updated
Bitcoin Script has a full array of bitwise/binary transformation and arithmetic opcodes.
Bitwise transformation opcodes are used to perform bitwise transformations on data items on the stack.
OP_INVERT
in
out
Flips all of the bits in the input.
OP_AND
x1 x2
out
Boolean and between each bit in the inputs.
OP_OR
x1 x2
out
Boolean or between each bit in the inputs.
OP_XOR
x1 x2
out
Boolean exclusive or between each bit in the inputs.
To check Bitwise outcomes, the scripting language provides an equality checker. For these checks to return true, the values on the stack must be equal at a bitwise level - i.e. they must be the same value and the same size.
OP_EQUAL
x1 x2
True / false
Returns 1 if the inputs are exactly equal, 0 otherwise.
OP_EQUALVERIFY
x1 x2
Nothing / fail
Same as OP_EQUAL, but runs OP_VERIFY afterward.
<0x80> OP_AND <0x80> OP_EQUALVERIFY
This example checks that the first bit of the top stack item is 1 (0x80 = 0b10000000
). If this condition is not met, the script will fail. The other bits are not evaluated. The top stack item must be 1 byte long or the script will fail.
<0x7f> OP_OR <0x7f> OP_EQUALVERIFY
This example checks that the first bit of the top stack item is 0 (0x7F = 0b01111111
). If this condition is not met, the script will fail. The other bits are not evaluated. The top stack item must be 1 byte long or the script will fail.
OP_XOR <0x7F> OP_OR <0xFF> OP_EQUALVERIFY
This example first applies an XOR function to two single byte values at the top of the stack. It then uses 0x7f OP_OR
to check that only one of them had the first bit set, and excludes the remaining bits from the test. If this condition is not met, the script will fail. The stack items must be 1 byte long or the script will fail.
These operations perform arithmetic and other mathematical transformations on data items on the stack.
OP_NEGATE
in
out
The sign of the input is flipped.
OP_ABS
in
out
The input is made positive.
OP_ADD
a b
out
a is added to b.
OP_1ADD
in
out
1 is added to the input.
OP_SUB
a b
out
b is subtracted from a.
OP_1SUB
in
out
1 is subtracted from the input.
OP_NOT
in
out
If the input is 0 or 1, it is flipped. Otherwise the output will be 0.
OP_MUL
a b
out
a is multiplied by b.
OP_DIV
a b
out
a is divided by b.
OP_MOD
a b
out
Returns the remainder after dividing a by b.
OP_DUP OP_DUP OP_MUL OP_MUL OP_ABS
In this example, the number at the top of the stack is duplicated twice and then the three values are multiplied together to calculate the cube of the original value. The absolute value of the outcome is the final result.
OP_DUP OP_MUL <314> OP_MUL <100> OP_DIV <1,000,000>* OP_LESSTHANOREQUAL
OP_FALSE OP_RETURN
OP_ENDIF
In this example, a trusted IoT measurement device records and reports the radius of a circle. The script uses this value to calculate the circle's area using the equation Pi x r^2. If the circle is less than 1m^2 the script fails. Note that there are no floating point calculations in Bitcoin, so 314 is used to approximate Pi (3.14) and the resulting output divided by 100 to get a figure in m^2.
* For readability, <314>, <100> and <1,000,000> are shown as decimal numbers. To implement this example in script, the little endian integers 0x3A01, 0x64 and 0x40420F should be used respectively.
OP_DUP OP_SHA256 <1,000,000>* OP_MOD OP_NOTIF
<1>
OP_ELSE
<2>
OP_ENDIF
<pubkey1> <pubkey2> <2> OP_CHECKMULTISIG
* For readability <1,000,000> is shown as a decimal number. To implement this example in script, the little endian integer 0x40420F should be used.
In this example, the signing parties play a game where the first to find a signature that with a SHA256 hash that is divisible by 1 million can spend the output. To begin the game, the coin is spent into a non-final script using both keys which pays out equally. If one user finds a valid solution before the time expires, they can finalise the payment channel and spend the full amount to their own wallet.
Valid solutions to the script are as follows:
<x> <signature 1>
(where signature 1 is divisible by 1,000,000)
<x> <signature 2>
(where signature 2 is divisible by 1,000,000)
<x> <signature 1> <signature 2>
Boolean shifts are used to shift the bits within a data item on the stack. There is no limit to the size of data item that these opcodes can be applied to.
OP_LSHIFT
a b
out
Logical left shift b bits. Sign data is discarded
OP_RSHIFT
a b
out
Logical right shift b bits. Sign data is discarded
These opcodes check inputs against Boolean and/or conditions. In all cases, any non-zero value is considered a true/1, while a zero value of any length bytevector is considered a false/0.
OP_BOOLAND
a b
out
If both a and b are not 0, the output is 1. Otherwise 0.
OP_BOOLOR
a b
out
If a or b is not 0, the output is 1. Otherwise 0.
These opcodes allow the script to check stack values against pre-set/expected results to create complex functionality.
OP_NUMEQUAL
a b
out
Returns 1 if the numbers are equal, 0 otherwise.
OP_NUMEQUALVERIFY
a b
Nothing / fail
Same as OP_NUMEQUAL, but runs OP_VERIFY afterward.
OP_NUMNOTEQUAL
a b
out
Returns 1 if the numbers are not equal, 0 otherwise.
OP_LESSTHAN
a b
out
Returns 1 if a is less than b, 0 otherwise.
OP_GREATERTHAN
a b
out
Returns 1 if a is greater than b, 0 otherwise.
OP_LESSTHANOREQUAL
a b
out
Returns 1 if a is less than or equal to b, 0 otherwise.
OP_GREATERTHANOREQUAL
a b
out
Returns 1 if a is greater than or equal to b, 0 otherwise.
These opcodes allow the script to select a maximum or minimum value from a group, or to discover whether a value is within a range.
OP_MIN
a b
out
Returns the smaller of a and b.
OP_MAX
a b
out
Returns the larger of a and b.
OP_WITHIN
x min max
out
Returns 1 if x is within the specified range (left-inclusive), 0 otherwise.