2014-07-18 13:56:17 +00:00
|
|
|
// Rust Bitcoin Library
|
|
|
|
// Written in 2014 by
|
|
|
|
// Andrew Poelstra <apoelstra@wpsoftware.net>
|
|
|
|
//
|
|
|
|
// To the extent possible under law, the author(s) have dedicated all
|
|
|
|
// copyright and related and neighboring rights to this software to
|
|
|
|
// the public domain worldwide. This software is distributed without
|
|
|
|
// any warranty.
|
|
|
|
//
|
|
|
|
// You should have received a copy of the CC0 Public Domain Dedication
|
|
|
|
// along with this software.
|
|
|
|
// If not, see <http://creativecommons.org/publicdomain/zero/1.0/>.
|
|
|
|
//
|
|
|
|
|
|
|
|
//! # Opcodes
|
|
|
|
//!
|
|
|
|
//! Bitcoin's script uses a stack-based assembly language. This module defines
|
2014-08-06 02:08:06 +00:00
|
|
|
//! all of the opcodes
|
2014-07-18 13:56:17 +00:00
|
|
|
//!
|
|
|
|
|
2014-08-06 02:08:06 +00:00
|
|
|
#![allow(non_camel_case_types)]
|
|
|
|
|
2015-04-06 00:10:37 +00:00
|
|
|
use serde;
|
2014-08-06 02:08:06 +00:00
|
|
|
|
2015-04-05 03:13:19 +00:00
|
|
|
// Heavy stick to translate between opcode types
|
|
|
|
use std::mem::transmute;
|
2014-08-06 02:08:06 +00:00
|
|
|
|
2015-04-05 03:13:19 +00:00
|
|
|
use network::serialize::{SimpleDecoder, SimpleEncoder};
|
|
|
|
use network::encodable::{ConsensusDecodable, ConsensusEncodable};
|
2014-08-06 02:08:06 +00:00
|
|
|
|
2015-04-05 03:13:19 +00:00
|
|
|
// Note: I am deliberately not implementing PartialOrd or Ord on the
|
|
|
|
// opcode enum. If you want to check ranges of opcodes, etc.,
|
|
|
|
// write an #[inline] helper function which casts to u8s.
|
2014-08-06 02:08:06 +00:00
|
|
|
|
2015-04-05 03:13:19 +00:00
|
|
|
/// A script Opcode
|
2015-04-10 23:15:57 +00:00
|
|
|
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
|
2015-04-05 03:13:19 +00:00
|
|
|
#[repr(u8)]
|
|
|
|
pub enum All {
|
2014-08-06 02:08:06 +00:00
|
|
|
/// Push an empty array onto the stack
|
|
|
|
OP_PUSHBYTES_0 = 0x0,
|
|
|
|
/// Push the next byte as an array onto the stack
|
|
|
|
OP_PUSHBYTES_1 = 0x01,
|
|
|
|
/// Push the next 2 bytes as an array onto the stack
|
|
|
|
OP_PUSHBYTES_2 = 0x02,
|
|
|
|
/// Push the next 2 bytes as an array onto the stack
|
|
|
|
OP_PUSHBYTES_3 = 0x03,
|
|
|
|
/// Push the next 4 bytes as an array onto the stack
|
|
|
|
OP_PUSHBYTES_4 = 0x04,
|
|
|
|
/// Push the next 5 bytes as an array onto the stack
|
|
|
|
OP_PUSHBYTES_5 = 0x05,
|
|
|
|
/// Push the next 6 bytes as an array onto the stack
|
|
|
|
OP_PUSHBYTES_6 = 0x06,
|
|
|
|
/// Push the next 7 bytes as an array onto the stack
|
|
|
|
OP_PUSHBYTES_7 = 0x07,
|
|
|
|
/// Push the next 8 bytes as an array onto the stack
|
|
|
|
OP_PUSHBYTES_8 = 0x08,
|
|
|
|
/// Push the next 9 bytes as an array onto the stack
|
|
|
|
OP_PUSHBYTES_9 = 0x09,
|
|
|
|
/// Push the next 10 bytes as an array onto the stack
|
|
|
|
OP_PUSHBYTES_10 = 0x0a,
|
|
|
|
/// Push the next 11 bytes as an array onto the stack
|
|
|
|
OP_PUSHBYTES_11 = 0x0b,
|
|
|
|
/// Push the next 12 bytes as an array onto the stack
|
|
|
|
OP_PUSHBYTES_12 = 0x0c,
|
|
|
|
/// Push the next 13 bytes as an array onto the stack
|
|
|
|
OP_PUSHBYTES_13 = 0x0d,
|
|
|
|
/// Push the next 14 bytes as an array onto the stack
|
|
|
|
OP_PUSHBYTES_14 = 0x0e,
|
|
|
|
/// Push the next 15 bytes as an array onto the stack
|
|
|
|
OP_PUSHBYTES_15 = 0x0f,
|
|
|
|
/// Push the next 16 bytes as an array onto the stack
|
|
|
|
OP_PUSHBYTES_16 = 0x10,
|
|
|
|
/// Push the next 17 bytes as an array onto the stack
|
|
|
|
OP_PUSHBYTES_17 = 0x11,
|
|
|
|
/// Push the next 18 bytes as an array onto the stack
|
|
|
|
OP_PUSHBYTES_18 = 0x12,
|
|
|
|
/// Push the next 19 bytes as an array onto the stack
|
|
|
|
OP_PUSHBYTES_19 = 0x13,
|
|
|
|
/// Push the next 20 bytes as an array onto the stack
|
|
|
|
OP_PUSHBYTES_20 = 0x14,
|
|
|
|
/// Push the next 21 bytes as an array onto the stack
|
|
|
|
OP_PUSHBYTES_21 = 0x15,
|
|
|
|
/// Push the next 22 bytes as an array onto the stack
|
|
|
|
OP_PUSHBYTES_22 = 0x16,
|
|
|
|
/// Push the next 23 bytes as an array onto the stack
|
|
|
|
OP_PUSHBYTES_23 = 0x17,
|
|
|
|
/// Push the next 24 bytes as an array onto the stack
|
|
|
|
OP_PUSHBYTES_24 = 0x18,
|
|
|
|
/// Push the next 25 bytes as an array onto the stack
|
|
|
|
OP_PUSHBYTES_25 = 0x19,
|
|
|
|
/// Push the next 26 bytes as an array onto the stack
|
|
|
|
OP_PUSHBYTES_26 = 0x1a,
|
|
|
|
/// Push the next 27 bytes as an array onto the stack
|
|
|
|
OP_PUSHBYTES_27 = 0x1b,
|
|
|
|
/// Push the next 28 bytes as an array onto the stack
|
|
|
|
OP_PUSHBYTES_28 = 0x1c,
|
|
|
|
/// Push the next 29 bytes as an array onto the stack
|
|
|
|
OP_PUSHBYTES_29 = 0x1d,
|
|
|
|
/// Push the next 30 bytes as an array onto the stack
|
|
|
|
OP_PUSHBYTES_30 = 0x1e,
|
|
|
|
/// Push the next 31 bytes as an array onto the stack
|
|
|
|
OP_PUSHBYTES_31 = 0x1f,
|
|
|
|
/// Push the next 32 bytes as an array onto the stack
|
|
|
|
OP_PUSHBYTES_32 = 0x20,
|
|
|
|
/// Push the next 33 bytes as an array onto the stack
|
|
|
|
OP_PUSHBYTES_33 = 0x21,
|
|
|
|
/// Push the next 34 bytes as an array onto the stack
|
|
|
|
OP_PUSHBYTES_34 = 0x22,
|
|
|
|
/// Push the next 35 bytes as an array onto the stack
|
|
|
|
OP_PUSHBYTES_35 = 0x23,
|
|
|
|
/// Push the next 36 bytes as an array onto the stack
|
|
|
|
OP_PUSHBYTES_36 = 0x24,
|
|
|
|
/// Push the next 37 bytes as an array onto the stack
|
|
|
|
OP_PUSHBYTES_37 = 0x25,
|
|
|
|
/// Push the next 38 bytes as an array onto the stack
|
|
|
|
OP_PUSHBYTES_38 = 0x26,
|
|
|
|
/// Push the next 39 bytes as an array onto the stack
|
|
|
|
OP_PUSHBYTES_39 = 0x27,
|
|
|
|
/// Push the next 40 bytes as an array onto the stack
|
|
|
|
OP_PUSHBYTES_40 = 0x28,
|
|
|
|
/// Push the next 41 bytes as an array onto the stack
|
|
|
|
OP_PUSHBYTES_41 = 0x29,
|
|
|
|
/// Push the next 42 bytes as an array onto the stack
|
|
|
|
OP_PUSHBYTES_42 = 0x2a,
|
|
|
|
/// Push the next 43 bytes as an array onto the stack
|
|
|
|
OP_PUSHBYTES_43 = 0x2b,
|
|
|
|
/// Push the next 44 bytes as an array onto the stack
|
|
|
|
OP_PUSHBYTES_44 = 0x2c,
|
|
|
|
/// Push the next 45 bytes as an array onto the stack
|
|
|
|
OP_PUSHBYTES_45 = 0x2d,
|
|
|
|
/// Push the next 46 bytes as an array onto the stack
|
|
|
|
OP_PUSHBYTES_46 = 0x2e,
|
|
|
|
/// Push the next 47 bytes as an array onto the stack
|
|
|
|
OP_PUSHBYTES_47 = 0x2f,
|
|
|
|
/// Push the next 48 bytes as an array onto the stack
|
|
|
|
OP_PUSHBYTES_48 = 0x30,
|
|
|
|
/// Push the next 49 bytes as an array onto the stack
|
|
|
|
OP_PUSHBYTES_49 = 0x31,
|
|
|
|
/// Push the next 50 bytes as an array onto the stack
|
|
|
|
OP_PUSHBYTES_50 = 0x32,
|
|
|
|
/// Push the next 51 bytes as an array onto the stack
|
|
|
|
OP_PUSHBYTES_51 = 0x33,
|
|
|
|
/// Push the next 52 bytes as an array onto the stack
|
|
|
|
OP_PUSHBYTES_52 = 0x34,
|
|
|
|
/// Push the next 53 bytes as an array onto the stack
|
|
|
|
OP_PUSHBYTES_53 = 0x35,
|
|
|
|
/// Push the next 54 bytes as an array onto the stack
|
|
|
|
OP_PUSHBYTES_54 = 0x36,
|
|
|
|
/// Push the next 55 bytes as an array onto the stack
|
|
|
|
OP_PUSHBYTES_55 = 0x37,
|
|
|
|
/// Push the next 56 bytes as an array onto the stack
|
|
|
|
OP_PUSHBYTES_56 = 0x38,
|
|
|
|
/// Push the next 57 bytes as an array onto the stack
|
|
|
|
OP_PUSHBYTES_57 = 0x39,
|
|
|
|
/// Push the next 58 bytes as an array onto the stack
|
|
|
|
OP_PUSHBYTES_58 = 0x3a,
|
|
|
|
/// Push the next 59 bytes as an array onto the stack
|
|
|
|
OP_PUSHBYTES_59 = 0x3b,
|
|
|
|
/// Push the next 60 bytes as an array onto the stack
|
|
|
|
OP_PUSHBYTES_60 = 0x3c,
|
|
|
|
/// Push the next 61 bytes as an array onto the stack
|
|
|
|
OP_PUSHBYTES_61 = 0x3d,
|
|
|
|
/// Push the next 62 bytes as an array onto the stack
|
|
|
|
OP_PUSHBYTES_62 = 0x3e,
|
|
|
|
/// Push the next 63 bytes as an array onto the stack
|
|
|
|
OP_PUSHBYTES_63 = 0x3f,
|
|
|
|
/// Push the next 64 bytes as an array onto the stack
|
|
|
|
OP_PUSHBYTES_64 = 0x40,
|
|
|
|
/// Push the next 65 bytes as an array onto the stack
|
|
|
|
OP_PUSHBYTES_65 = 0x41,
|
|
|
|
/// Push the next 66 bytes as an array onto the stack
|
|
|
|
OP_PUSHBYTES_66 = 0x42,
|
|
|
|
/// Push the next 67 bytes as an array onto the stack
|
|
|
|
OP_PUSHBYTES_67 = 0x43,
|
|
|
|
/// Push the next 68 bytes as an array onto the stack
|
|
|
|
OP_PUSHBYTES_68 = 0x44,
|
|
|
|
/// Push the next 69 bytes as an array onto the stack
|
|
|
|
OP_PUSHBYTES_69 = 0x45,
|
|
|
|
/// Push the next 70 bytes as an array onto the stack
|
|
|
|
OP_PUSHBYTES_70 = 0x46,
|
|
|
|
/// Push the next 71 bytes as an array onto the stack
|
|
|
|
OP_PUSHBYTES_71 = 0x47,
|
|
|
|
/// Push the next 72 bytes as an array onto the stack
|
|
|
|
OP_PUSHBYTES_72 = 0x48,
|
|
|
|
/// Push the next 73 bytes as an array onto the stack
|
|
|
|
OP_PUSHBYTES_73 = 0x49,
|
|
|
|
/// Push the next 74 bytes as an array onto the stack
|
|
|
|
OP_PUSHBYTES_74 = 0x4a,
|
|
|
|
/// Push the next 75 bytes as an array onto the stack
|
|
|
|
OP_PUSHBYTES_75 = 0x4b,
|
|
|
|
/// Read the next byte as N; push the next N bytes as an array onto the stack
|
|
|
|
OP_PUSHDATA1 = 0x4c,
|
|
|
|
/// Read the next 2 bytes as N; push the next N bytes as an array onto the stack
|
|
|
|
OP_PUSHDATA2 = 0x4d,
|
|
|
|
/// Read the next 4 bytes as N; push the next N bytes as an array onto the stack
|
|
|
|
OP_PUSHDATA4 = 0x4e,
|
|
|
|
/// Push the array [0x80] onto the stack
|
|
|
|
OP_PUSHNUM_NEG1 = 0x4f,
|
|
|
|
/// Synonym for OP_RETURN
|
|
|
|
OP_RESERVED = 0x50,
|
|
|
|
/// Push the array [0x01] onto the stack
|
|
|
|
OP_PUSHNUM_1 = 0x51,
|
2014-08-13 05:50:40 +00:00
|
|
|
/// Push the array [0x02] onto the stack
|
2014-08-06 02:08:06 +00:00
|
|
|
OP_PUSHNUM_2 = 0x52,
|
2014-08-13 05:50:40 +00:00
|
|
|
/// Push the array [0x03] onto the stack
|
2014-08-06 02:08:06 +00:00
|
|
|
OP_PUSHNUM_3 = 0x53,
|
2014-08-13 05:50:40 +00:00
|
|
|
/// Push the array [0x04] onto the stack
|
2014-08-06 02:08:06 +00:00
|
|
|
OP_PUSHNUM_4 = 0x54,
|
2014-08-13 05:50:40 +00:00
|
|
|
/// Push the array [0x05] onto the stack
|
2014-08-06 02:08:06 +00:00
|
|
|
OP_PUSHNUM_5 = 0x55,
|
2014-08-13 05:50:40 +00:00
|
|
|
/// Push the array [0x06] onto the stack
|
2014-08-06 02:08:06 +00:00
|
|
|
OP_PUSHNUM_6 = 0x56,
|
2014-08-13 05:50:40 +00:00
|
|
|
/// Push the array [0x07] onto the stack
|
2014-08-06 02:08:06 +00:00
|
|
|
OP_PUSHNUM_7 = 0x57,
|
2014-08-13 05:50:40 +00:00
|
|
|
/// Push the array [0x08] onto the stack
|
2014-08-06 02:08:06 +00:00
|
|
|
OP_PUSHNUM_8 = 0x58,
|
2014-08-13 05:50:40 +00:00
|
|
|
/// Push the array [0x09] onto the stack
|
2014-08-06 02:08:06 +00:00
|
|
|
OP_PUSHNUM_9 = 0x59,
|
2014-08-13 05:50:40 +00:00
|
|
|
/// Push the array [0x0a] onto the stack
|
2014-08-06 02:08:06 +00:00
|
|
|
OP_PUSHNUM_10 = 0x5a,
|
2014-08-13 05:50:40 +00:00
|
|
|
/// Push the array [0x0b] onto the stack
|
2014-08-06 02:08:06 +00:00
|
|
|
OP_PUSHNUM_11 = 0x5b,
|
2014-08-13 05:50:40 +00:00
|
|
|
/// Push the array [0x0c] onto the stack
|
2014-08-06 02:08:06 +00:00
|
|
|
OP_PUSHNUM_12 = 0x5c,
|
2014-08-13 05:50:40 +00:00
|
|
|
/// Push the array [0x0d] onto the stack
|
2014-08-06 02:08:06 +00:00
|
|
|
OP_PUSHNUM_13 = 0x5d,
|
2014-08-13 05:50:40 +00:00
|
|
|
/// Push the array [0x0e] onto the stack
|
2014-08-06 02:08:06 +00:00
|
|
|
OP_PUSHNUM_14 = 0x5e,
|
2014-08-13 05:50:40 +00:00
|
|
|
/// Push the array [0x0f] onto the stack
|
2014-08-06 02:08:06 +00:00
|
|
|
OP_PUSHNUM_15 = 0x5f,
|
2014-08-13 05:50:40 +00:00
|
|
|
/// Push the array [0x10] onto the stack
|
2014-08-06 02:08:06 +00:00
|
|
|
OP_PUSHNUM_16 = 0x60,
|
|
|
|
/// Does nothing
|
|
|
|
OP_NOP = 0x61,
|
|
|
|
/// Synonym for OP_RETURN
|
|
|
|
OP_VER = 0x62,
|
|
|
|
/// Pop and execute the next statements if a nonzero element was popped
|
|
|
|
OP_IF = 0x63,
|
|
|
|
/// Pop and execute the next statements if a zero element was popped
|
|
|
|
OP_NOTIF = 0x64,
|
|
|
|
/// Fail the script unconditionally, does not even need to be executed
|
|
|
|
OP_VERIF = 0x65,
|
|
|
|
/// Fail the script unconditionally, does not even need to be executed
|
|
|
|
OP_VERNOTIF = 0x66,
|
|
|
|
/// Execute statements if those after the previous OP_IF were not, and vice-versa.
|
|
|
|
/// If there is no previous OP_IF, this acts as a RETURN.
|
|
|
|
OP_ELSE = 0x67,
|
|
|
|
/// Pop and execute the next statements if a zero element was popped
|
|
|
|
OP_ENDIF = 0x68,
|
|
|
|
/// If the top value is zero or the stack is empty, fail; otherwise, pop the stack
|
|
|
|
OP_VERIFY = 0x69,
|
|
|
|
/// Fail the script immediately. (Must be executed.)
|
|
|
|
OP_RETURN = 0x6a,
|
|
|
|
/// Pop one element from the main stack onto the alt stack
|
|
|
|
OP_TOALTSTACK = 0x6b,
|
|
|
|
/// Pop one element from the alt stack onto the main stack
|
|
|
|
OP_FROMALTSTACK = 0x6c,
|
|
|
|
/// Drops the top two stack items
|
|
|
|
OP_2DROP = 0x6d,
|
|
|
|
/// Duplicates the top two stack items as AB -> ABAB
|
|
|
|
OP_2DUP = 0x6e,
|
|
|
|
/// Duplicates the two three stack items as ABC -> ABCABC
|
|
|
|
OP_3DUP = 0x6f,
|
|
|
|
/// Copies the two stack items of items two spaces back to
|
|
|
|
/// the front, as xxAB -> ABxxAB
|
|
|
|
OP_2OVER = 0x70,
|
|
|
|
/// Moves the two stack items four spaces back to the front,
|
|
|
|
/// as xxxxAB -> ABxxxx
|
|
|
|
OP_2ROT = 0x71,
|
|
|
|
/// Swaps the top two pairs, as ABCD -> CDAB
|
|
|
|
OP_2SWAP = 0x72,
|
|
|
|
/// Duplicate the top stack element unless it is zero
|
|
|
|
OP_IFDUP = 0x73,
|
|
|
|
/// Push the current number of stack items onto te stack
|
|
|
|
OP_DEPTH = 0x74,
|
|
|
|
/// Drops the top stack item
|
|
|
|
OP_DROP = 0x75,
|
|
|
|
/// Duplicates the top stack item
|
|
|
|
OP_DUP = 0x76,
|
|
|
|
/// Drops the second-to-top stack item
|
|
|
|
OP_NIP = 0x77,
|
|
|
|
/// Copies the second-to-top stack item, as xA -> AxA
|
|
|
|
OP_OVER = 0x78,
|
|
|
|
/// Pop the top stack element as N. Copy the Nth stack element to the top
|
|
|
|
OP_PICK = 0x79,
|
|
|
|
/// Pop the top stack element as N. Move the Nth stack element to the top
|
|
|
|
OP_ROLL = 0x7a,
|
|
|
|
/// Rotate the top three stack items, as [top next1 next2] -> [next2 top next1]
|
|
|
|
OP_ROT = 0x7b,
|
|
|
|
/// Swap the top two stack items
|
|
|
|
OP_SWAP = 0x7c,
|
|
|
|
/// Copy the top stack item to before the second item, as [top next] -> [top next top]
|
|
|
|
OP_TUCK = 0x7d,
|
|
|
|
/// Fail the script unconditionally, does not even need to be executed
|
|
|
|
OP_CAT = 0x7e,
|
|
|
|
/// Fail the script unconditionally, does not even need to be executed
|
|
|
|
OP_SUBSTR = 0x7f,
|
|
|
|
/// Fail the script unconditionally, does not even need to be executed
|
|
|
|
OP_LEFT = 0x80,
|
|
|
|
/// Fail the script unconditionally, does not even need to be executed
|
|
|
|
OP_RIGHT = 0x81,
|
|
|
|
/// Pushes the length of the top stack item onto the stack
|
|
|
|
OP_SIZE = 0x82,
|
|
|
|
/// Fail the script unconditionally, does not even need to be executed
|
|
|
|
OP_INVERT = 0x83,
|
|
|
|
/// Fail the script unconditionally, does not even need to be executed
|
|
|
|
OP_AND = 0x84,
|
|
|
|
/// Fail the script unconditionally, does not even need to be executed
|
|
|
|
OP_OR = 0x85,
|
|
|
|
/// Fail the script unconditionally, does not even need to be executed
|
|
|
|
OP_XOR = 0x86,
|
|
|
|
/// Pushes 1 if the inputs are exactly equal, 0 otherwise
|
|
|
|
OP_EQUAL = 0x87,
|
|
|
|
/// Returns success if the inputs are exactly equal, failure otherwise
|
|
|
|
OP_EQUALVERIFY = 0x88,
|
|
|
|
/// Synonym for OP_RETURN
|
|
|
|
OP_RESERVED1 = 0x89,
|
|
|
|
/// Synonym for OP_RETURN
|
|
|
|
OP_RESERVED2 = 0x8a,
|
|
|
|
/// Increment the top stack element in place
|
|
|
|
OP_1ADD = 0x8b,
|
|
|
|
/// Decrement the top stack element in place
|
|
|
|
OP_1SUB = 0x8c,
|
|
|
|
/// Fail the script unconditionally, does not even need to be executed
|
|
|
|
OP_2MUL = 0x8d,
|
|
|
|
/// Fail the script unconditionally, does not even need to be executed
|
|
|
|
OP_2DIV = 0x8e,
|
|
|
|
/// Multiply the top stack item by -1 in place
|
|
|
|
OP_NEGATE = 0x8f,
|
|
|
|
/// Absolute value the top stack item in place
|
|
|
|
OP_ABS = 0x90,
|
|
|
|
/// Map 0 to 1 and everything else to 0, in place
|
|
|
|
OP_NOT = 0x91,
|
|
|
|
/// Map 0 to 0 and everything else to 1, in place
|
|
|
|
OP_0NOTEQUAL = 0x92,
|
|
|
|
/// Pop two stack items and push their sum
|
|
|
|
OP_ADD = 0x93,
|
|
|
|
/// Pop two stack items and push the second minus the top
|
|
|
|
OP_SUB = 0x94,
|
|
|
|
/// Fail the script unconditionally, does not even need to be executed
|
|
|
|
OP_MUL = 0x95,
|
|
|
|
/// Fail the script unconditionally, does not even need to be executed
|
|
|
|
OP_DIV = 0x96,
|
|
|
|
/// Fail the script unconditionally, does not even need to be executed
|
|
|
|
OP_MOD = 0x97,
|
|
|
|
/// Fail the script unconditionally, does not even need to be executed
|
|
|
|
OP_LSHIFT = 0x98,
|
|
|
|
/// Fail the script unconditionally, does not even need to be executed
|
|
|
|
OP_RSHIFT = 0x99,
|
|
|
|
/// Pop the top two stack items and push 1 if both are nonzero, else push 0
|
|
|
|
OP_BOOLAND = 0x9a,
|
|
|
|
/// Pop the top two stack items and push 1 if either is nonzero, else push 0
|
|
|
|
OP_BOOLOR = 0x9b,
|
|
|
|
/// Pop the top two stack items and push 1 if both are numerically equal, else push 0
|
|
|
|
OP_NUMEQUAL = 0x9c,
|
|
|
|
/// Pop the top two stack items and return success if both are numerically equal, else return failure
|
|
|
|
OP_NUMEQUALVERIFY = 0x9d,
|
|
|
|
/// Pop the top two stack items and push 0 if both are numerically equal, else push 1
|
|
|
|
OP_NUMNOTEQUAL = 0x9e,
|
|
|
|
/// Pop the top two items; push 1 if the second is less than the top, 0 otherwise
|
|
|
|
OP_LESSTHAN = 0x9f,
|
|
|
|
/// Pop the top two items; push 1 if the second is greater than the top, 0 otherwise
|
|
|
|
OP_GREATERTHAN = 0xa0,
|
|
|
|
/// Pop the top two items; push 1 if the second is <= the top, 0 otherwise
|
|
|
|
OP_LESSTHANOREQUAL = 0xa1,
|
|
|
|
/// Pop the top two items; push 1 if the second is >= the top, 0 otherwise
|
|
|
|
OP_GREATERTHANOREQUAL = 0xa2,
|
|
|
|
/// Pop the top two items; push the smaller
|
|
|
|
OP_MIN = 0xa3,
|
|
|
|
/// Pop the top two items; push the larger
|
|
|
|
OP_MAX = 0xa4,
|
|
|
|
/// Pop the top three items; if the top is >= the second and < the third, push 1, otherwise push 0
|
|
|
|
OP_WITHIN = 0xa5,
|
|
|
|
/// Pop the top stack item and push its RIPEMD160 hash
|
|
|
|
OP_RIPEMD160 = 0xa6,
|
|
|
|
/// Pop the top stack item and push its SHA1 hash
|
|
|
|
OP_SHA1 = 0xa7,
|
|
|
|
/// Pop the top stack item and push its SHA256 hash
|
|
|
|
OP_SHA256 = 0xa8,
|
|
|
|
/// Pop the top stack item and push its RIPEMD(SHA256) hash
|
|
|
|
OP_HASH160 = 0xa9,
|
|
|
|
/// Pop the top stack item and push its SHA256(SHA256) hash
|
|
|
|
OP_HASH256 = 0xaa,
|
|
|
|
/// Ignore this and everything preceding when deciding what to sign when signature-checking
|
|
|
|
OP_CODESEPARATOR = 0xab,
|
|
|
|
/// https://en.bitcoin.it/wiki/OP_CHECKSIG pushing 1/0 for success/failure
|
|
|
|
OP_CHECKSIG = 0xac,
|
|
|
|
/// https://en.bitcoin.it/wiki/OP_CHECKSIG returning success/failure
|
|
|
|
OP_CHECKSIGVERIFY = 0xad,
|
|
|
|
/// Pop N, N pubkeys, M, M signatures, a dummy (due to bug in reference code), and verify that all M signatures are valid.
|
|
|
|
/// Push 1 for "all valid", 0 otherwise
|
|
|
|
OP_CHECKMULTISIG = 0xae,
|
|
|
|
/// Like the above but return success/failure
|
|
|
|
OP_CHECKMULTISIGVERIFY = 0xaf,
|
|
|
|
/// Does nothing
|
|
|
|
OP_NOP1 = 0xb0,
|
|
|
|
/// Does nothing
|
|
|
|
OP_NOP2 = 0xb1,
|
|
|
|
/// Does nothing
|
|
|
|
OP_NOP3 = 0xb2,
|
|
|
|
/// Does nothing
|
|
|
|
OP_NOP4 = 0xb3,
|
|
|
|
/// Does nothing
|
|
|
|
OP_NOP5 = 0xb4,
|
|
|
|
/// Does nothing
|
|
|
|
OP_NOP6 = 0xb5,
|
|
|
|
/// Does nothing
|
|
|
|
OP_NOP7 = 0xb6,
|
|
|
|
/// Does nothing
|
|
|
|
OP_NOP8 = 0xb7,
|
|
|
|
/// Does nothing
|
|
|
|
OP_NOP9 = 0xb8,
|
|
|
|
/// Does nothing
|
|
|
|
OP_NOP10 = 0xb9,
|
|
|
|
// Every other opcode acts as OP_RETURN
|
|
|
|
/// Synonym for OP_RETURN
|
|
|
|
OP_RETURN_186 = 0xba,
|
|
|
|
/// Synonym for OP_RETURN
|
|
|
|
OP_RETURN_187 = 0xbb,
|
|
|
|
/// Synonym for OP_RETURN
|
|
|
|
OP_RETURN_188 = 0xbc,
|
|
|
|
/// Synonym for OP_RETURN
|
|
|
|
OP_RETURN_189 = 0xbd,
|
|
|
|
/// Synonym for OP_RETURN
|
|
|
|
OP_RETURN_190 = 0xbe,
|
|
|
|
/// Synonym for OP_RETURN
|
|
|
|
OP_RETURN_191 = 0xbf,
|
|
|
|
/// Synonym for OP_RETURN
|
|
|
|
OP_RETURN_192 = 0xc0,
|
|
|
|
/// Synonym for OP_RETURN
|
|
|
|
OP_RETURN_193 = 0xc1,
|
|
|
|
/// Synonym for OP_RETURN
|
|
|
|
OP_RETURN_194 = 0xc2,
|
|
|
|
/// Synonym for OP_RETURN
|
|
|
|
OP_RETURN_195 = 0xc3,
|
|
|
|
/// Synonym for OP_RETURN
|
|
|
|
OP_RETURN_196 = 0xc4,
|
|
|
|
/// Synonym for OP_RETURN
|
|
|
|
OP_RETURN_197 = 0xc5,
|
|
|
|
/// Synonym for OP_RETURN
|
|
|
|
OP_RETURN_198 = 0xc6,
|
|
|
|
/// Synonym for OP_RETURN
|
|
|
|
OP_RETURN_199 = 0xc7,
|
|
|
|
/// Synonym for OP_RETURN
|
|
|
|
OP_RETURN_200 = 0xc8,
|
|
|
|
/// Synonym for OP_RETURN
|
|
|
|
OP_RETURN_201 = 0xc9,
|
|
|
|
/// Synonym for OP_RETURN
|
|
|
|
OP_RETURN_202 = 0xca,
|
|
|
|
/// Synonym for OP_RETURN
|
|
|
|
OP_RETURN_203 = 0xcb,
|
|
|
|
/// Synonym for OP_RETURN
|
|
|
|
OP_RETURN_204 = 0xcc,
|
|
|
|
/// Synonym for OP_RETURN
|
|
|
|
OP_RETURN_205 = 0xcd,
|
|
|
|
/// Synonym for OP_RETURN
|
|
|
|
OP_RETURN_206 = 0xce,
|
|
|
|
/// Synonym for OP_RETURN
|
|
|
|
OP_RETURN_207 = 0xcf,
|
|
|
|
/// Synonym for OP_RETURN
|
|
|
|
OP_RETURN_208 = 0xd0,
|
|
|
|
/// Synonym for OP_RETURN
|
|
|
|
OP_RETURN_209 = 0xd1,
|
|
|
|
/// Synonym for OP_RETURN
|
|
|
|
OP_RETURN_210 = 0xd2,
|
|
|
|
/// Synonym for OP_RETURN
|
|
|
|
OP_RETURN_211 = 0xd3,
|
|
|
|
/// Synonym for OP_RETURN
|
|
|
|
OP_RETURN_212 = 0xd4,
|
|
|
|
/// Synonym for OP_RETURN
|
|
|
|
OP_RETURN_213 = 0xd5,
|
|
|
|
/// Synonym for OP_RETURN
|
|
|
|
OP_RETURN_214 = 0xd6,
|
|
|
|
/// Synonym for OP_RETURN
|
|
|
|
OP_RETURN_215 = 0xd7,
|
|
|
|
/// Synonym for OP_RETURN
|
|
|
|
OP_RETURN_216 = 0xd8,
|
|
|
|
/// Synonym for OP_RETURN
|
|
|
|
OP_RETURN_217 = 0xd9,
|
|
|
|
/// Synonym for OP_RETURN
|
|
|
|
OP_RETURN_218 = 0xda,
|
|
|
|
/// Synonym for OP_RETURN
|
|
|
|
OP_RETURN_219 = 0xdb,
|
|
|
|
/// Synonym for OP_RETURN
|
|
|
|
OP_RETURN_220 = 0xdc,
|
|
|
|
/// Synonym for OP_RETURN
|
|
|
|
OP_RETURN_221 = 0xdd,
|
|
|
|
/// Synonym for OP_RETURN
|
|
|
|
OP_RETURN_222 = 0xde,
|
|
|
|
/// Synonym for OP_RETURN
|
|
|
|
OP_RETURN_223 = 0xdf,
|
|
|
|
/// Synonym for OP_RETURN
|
|
|
|
OP_RETURN_224 = 0xe0,
|
|
|
|
/// Synonym for OP_RETURN
|
|
|
|
OP_RETURN_225 = 0xe1,
|
|
|
|
/// Synonym for OP_RETURN
|
|
|
|
OP_RETURN_226 = 0xe2,
|
|
|
|
/// Synonym for OP_RETURN
|
|
|
|
OP_RETURN_227 = 0xe3,
|
|
|
|
/// Synonym for OP_RETURN
|
|
|
|
OP_RETURN_228 = 0xe4,
|
|
|
|
/// Synonym for OP_RETURN
|
|
|
|
OP_RETURN_229 = 0xe5,
|
|
|
|
/// Synonym for OP_RETURN
|
|
|
|
OP_RETURN_230 = 0xe6,
|
|
|
|
/// Synonym for OP_RETURN
|
|
|
|
OP_RETURN_231 = 0xe7,
|
|
|
|
/// Synonym for OP_RETURN
|
|
|
|
OP_RETURN_232 = 0xe8,
|
|
|
|
/// Synonym for OP_RETURN
|
|
|
|
OP_RETURN_233 = 0xe9,
|
|
|
|
/// Synonym for OP_RETURN
|
|
|
|
OP_RETURN_234 = 0xea,
|
|
|
|
/// Synonym for OP_RETURN
|
|
|
|
OP_RETURN_235 = 0xeb,
|
|
|
|
/// Synonym for OP_RETURN
|
|
|
|
OP_RETURN_236 = 0xec,
|
|
|
|
/// Synonym for OP_RETURN
|
|
|
|
OP_RETURN_237 = 0xed,
|
|
|
|
/// Synonym for OP_RETURN
|
|
|
|
OP_RETURN_238 = 0xee,
|
|
|
|
/// Synonym for OP_RETURN
|
|
|
|
OP_RETURN_239 = 0xef,
|
|
|
|
/// Synonym for OP_RETURN
|
|
|
|
OP_RETURN_240 = 0xf0,
|
|
|
|
/// Synonym for OP_RETURN
|
|
|
|
OP_RETURN_241 = 0xf1,
|
|
|
|
/// Synonym for OP_RETURN
|
|
|
|
OP_RETURN_242 = 0xf2,
|
|
|
|
/// Synonym for OP_RETURN
|
|
|
|
OP_RETURN_243 = 0xf3,
|
|
|
|
/// Synonym for OP_RETURN
|
|
|
|
OP_RETURN_244 = 0xf4,
|
|
|
|
/// Synonym for OP_RETURN
|
|
|
|
OP_RETURN_245 = 0xf5,
|
|
|
|
/// Synonym for OP_RETURN
|
|
|
|
OP_RETURN_246 = 0xf6,
|
|
|
|
/// Synonym for OP_RETURN
|
|
|
|
OP_RETURN_247 = 0xf7,
|
|
|
|
/// Synonym for OP_RETURN
|
|
|
|
OP_RETURN_248 = 0xf8,
|
|
|
|
/// Synonym for OP_RETURN
|
|
|
|
OP_RETURN_249 = 0xf9,
|
|
|
|
/// Synonym for OP_RETURN
|
|
|
|
OP_RETURN_250 = 0xfa,
|
|
|
|
/// Synonym for OP_RETURN
|
|
|
|
OP_RETURN_251 = 0xfb,
|
|
|
|
/// Synonym for OP_RETURN
|
|
|
|
OP_RETURN_252 = 0xfc,
|
|
|
|
/// Synonym for OP_RETURN
|
|
|
|
OP_RETURN_253 = 0xfd,
|
|
|
|
/// Synonym for OP_RETURN
|
|
|
|
OP_RETURN_254 = 0xfe,
|
|
|
|
/// Synonym for OP_RETURN
|
|
|
|
OP_RETURN_255 = 0xff,
|
2015-04-05 03:13:19 +00:00
|
|
|
}
|
2014-08-06 02:08:06 +00:00
|
|
|
|
2015-04-05 03:13:19 +00:00
|
|
|
impl All {
|
2014-08-06 02:08:06 +00:00
|
|
|
/// Classifies an Opcode into a broad class
|
|
|
|
#[inline]
|
2015-04-05 17:58:49 +00:00
|
|
|
pub fn classify(&self) -> Class {
|
2014-08-06 02:08:06 +00:00
|
|
|
// 17 opcodes
|
2015-04-05 03:13:19 +00:00
|
|
|
if *self == All::OP_VERIF || *self == All::OP_VERNOTIF ||
|
|
|
|
*self == All::OP_CAT || *self == All::OP_SUBSTR ||
|
|
|
|
*self == All::OP_LEFT || *self == All::OP_RIGHT ||
|
|
|
|
*self == All::OP_INVERT || *self == All::OP_AND ||
|
|
|
|
*self == All::OP_OR || *self == All::OP_XOR ||
|
|
|
|
*self == All::OP_2MUL || *self == All::OP_2DIV ||
|
|
|
|
*self == All::OP_MUL || *self == All::OP_DIV || *self == All::OP_MOD ||
|
|
|
|
*self == All::OP_LSHIFT || *self == All::OP_RSHIFT {
|
2015-04-05 17:58:49 +00:00
|
|
|
Class::IllegalOp
|
2014-08-06 02:08:06 +00:00
|
|
|
// 11 opcodes
|
2015-04-05 03:13:19 +00:00
|
|
|
} else if *self == All::OP_NOP ||
|
|
|
|
(All::OP_NOP1 as u8 <= *self as u8 &&
|
|
|
|
*self as u8 <= All::OP_NOP10 as u8) {
|
2015-04-05 17:58:49 +00:00
|
|
|
Class::NoOp
|
2014-08-06 02:08:06 +00:00
|
|
|
// 75 opcodes
|
2015-04-05 03:13:19 +00:00
|
|
|
} else if *self == All::OP_RESERVED || *self == All::OP_VER || *self == All::OP_RETURN ||
|
|
|
|
*self == All::OP_RESERVED1 || *self == All::OP_RESERVED2 ||
|
|
|
|
*self as u8 >= All::OP_RETURN_186 as u8 {
|
2015-04-05 17:58:49 +00:00
|
|
|
Class::ReturnOp
|
2014-08-06 02:08:06 +00:00
|
|
|
// 1 opcode
|
2015-04-05 03:13:19 +00:00
|
|
|
} else if *self == All::OP_PUSHNUM_NEG1 {
|
2015-04-05 17:58:49 +00:00
|
|
|
Class::PushNum(-1)
|
2014-08-06 02:08:06 +00:00
|
|
|
// 16 opcodes
|
2015-04-05 03:13:19 +00:00
|
|
|
} else if All::OP_PUSHNUM_1 as u8 <= *self as u8 &&
|
|
|
|
*self as u8 <= All::OP_PUSHNUM_16 as u8 {
|
2015-04-07 22:51:57 +00:00
|
|
|
Class::PushNum(1 + *self as i32 - All::OP_PUSHNUM_1 as i32)
|
2014-08-06 02:08:06 +00:00
|
|
|
// 76 opcodes
|
2015-04-05 03:13:19 +00:00
|
|
|
} else if *self as u8 <= All::OP_PUSHBYTES_75 as u8 {
|
2015-04-07 22:51:57 +00:00
|
|
|
Class::PushBytes(*self as u32)
|
2014-08-06 02:08:06 +00:00
|
|
|
// 60 opcodes
|
|
|
|
} else {
|
2015-04-05 17:58:49 +00:00
|
|
|
Class::Ordinary(unsafe { transmute(*self) })
|
2014-08-06 02:08:06 +00:00
|
|
|
}
|
|
|
|
}
|
2015-04-05 03:13:19 +00:00
|
|
|
}
|
2014-08-06 02:08:06 +00:00
|
|
|
|
2015-10-14 13:56:48 +00:00
|
|
|
impl From<u8> for All {
|
|
|
|
#[inline]
|
|
|
|
fn from(b: u8) -> All {
|
|
|
|
unsafe { transmute(b) }
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2015-04-07 01:51:11 +00:00
|
|
|
display_from_debug!(All);
|
|
|
|
|
2015-04-06 00:10:37 +00:00
|
|
|
impl<D: SimpleDecoder> ConsensusDecodable<D> for All {
|
2014-08-06 02:08:06 +00:00
|
|
|
#[inline]
|
2015-04-06 00:10:37 +00:00
|
|
|
fn consensus_decode(d: &mut D) -> Result<All, D::Error> {
|
2015-10-14 13:56:48 +00:00
|
|
|
Ok(All::from(try!(d.read_u8())))
|
2014-08-06 02:08:06 +00:00
|
|
|
}
|
2015-04-05 03:13:19 +00:00
|
|
|
}
|
2014-08-06 02:08:06 +00:00
|
|
|
|
2015-04-06 00:10:37 +00:00
|
|
|
impl<S: SimpleEncoder> ConsensusEncodable<S> for All {
|
2014-08-06 02:08:06 +00:00
|
|
|
#[inline]
|
2015-04-06 00:10:37 +00:00
|
|
|
fn consensus_encode(&self, s: &mut S) -> Result<(), S::Error> {
|
2014-08-06 02:08:06 +00:00
|
|
|
s.emit_u8(*self as u8)
|
|
|
|
}
|
2015-04-05 03:13:19 +00:00
|
|
|
}
|
2014-08-06 02:08:06 +00:00
|
|
|
|
2015-04-06 00:10:37 +00:00
|
|
|
impl serde::Serialize for All {
|
|
|
|
fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error>
|
|
|
|
where S: serde::Serializer,
|
|
|
|
{
|
|
|
|
serializer.visit_str(&self.to_string())
|
|
|
|
}
|
2014-08-06 02:08:06 +00:00
|
|
|
}
|
|
|
|
|
2015-04-05 03:13:19 +00:00
|
|
|
/// Empty stack is also FALSE
|
2015-04-05 19:43:44 +00:00
|
|
|
pub static OP_FALSE: All = All::OP_PUSHBYTES_0;
|
2015-04-05 03:13:19 +00:00
|
|
|
/// Number 1 is also TRUE
|
2015-04-05 19:43:44 +00:00
|
|
|
pub static OP_TRUE: All = All::OP_PUSHNUM_1;
|
2015-04-05 03:13:19 +00:00
|
|
|
|
2014-08-06 02:08:06 +00:00
|
|
|
/// Broad categories of opcodes with similar behavior
|
2015-04-10 23:15:57 +00:00
|
|
|
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
|
2015-04-05 17:58:49 +00:00
|
|
|
pub enum Class {
|
2014-08-06 02:08:06 +00:00
|
|
|
/// Pushes the given number onto the stack
|
2015-04-07 22:51:57 +00:00
|
|
|
PushNum(i32),
|
2014-08-06 02:08:06 +00:00
|
|
|
/// Pushes the given number of bytes onto the stack
|
2015-04-07 22:51:57 +00:00
|
|
|
PushBytes(u32),
|
2014-08-06 02:08:06 +00:00
|
|
|
/// Fails the script if executed
|
|
|
|
ReturnOp,
|
|
|
|
/// Fails the script even if not executed
|
|
|
|
IllegalOp,
|
|
|
|
/// Does nothing
|
|
|
|
NoOp,
|
|
|
|
/// Any opcode not covered above
|
2015-04-05 03:13:19 +00:00
|
|
|
Ordinary(Ordinary)
|
2014-08-06 02:08:06 +00:00
|
|
|
}
|
|
|
|
|
2015-04-07 01:51:11 +00:00
|
|
|
display_from_debug!(Class);
|
|
|
|
|
2015-04-06 00:10:37 +00:00
|
|
|
impl serde::Serialize for Class {
|
|
|
|
fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error>
|
|
|
|
where S: serde::Serializer,
|
|
|
|
{
|
|
|
|
serializer.visit_str(&self.to_string())
|
2014-08-17 02:04:57 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-01-18 18:16:01 +00:00
|
|
|
macro_rules! ordinary_opcode {
|
2014-08-06 02:08:06 +00:00
|
|
|
($($op:ident),*) => (
|
|
|
|
#[repr(u8)]
|
2014-08-10 19:58:15 +00:00
|
|
|
#[doc(hidden)]
|
2015-04-10 23:15:57 +00:00
|
|
|
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
|
2015-04-05 03:13:19 +00:00
|
|
|
pub enum Ordinary {
|
|
|
|
$( $op = All::$op as u8 ),*
|
2014-08-06 02:08:06 +00:00
|
|
|
}
|
|
|
|
);
|
2015-01-18 18:16:01 +00:00
|
|
|
}
|
2014-08-06 02:08:06 +00:00
|
|
|
|
|
|
|
/// "Ordinary" opcodes -- should be 60 of these
|
2015-01-18 18:16:01 +00:00
|
|
|
ordinary_opcode! {
|
2014-08-06 02:08:06 +00:00
|
|
|
// pushdata
|
|
|
|
OP_PUSHDATA1, OP_PUSHDATA2, OP_PUSHDATA4,
|
|
|
|
// control flow
|
|
|
|
OP_IF, OP_NOTIF, OP_ELSE, OP_ENDIF, OP_VERIFY,
|
|
|
|
// stack
|
|
|
|
OP_TOALTSTACK, OP_FROMALTSTACK,
|
|
|
|
OP_2DROP, OP_2DUP, OP_3DUP, OP_2OVER, OP_2ROT, OP_2SWAP,
|
|
|
|
OP_DROP, OP_DUP, OP_NIP, OP_OVER, OP_PICK, OP_ROLL, OP_ROT, OP_SWAP, OP_TUCK,
|
|
|
|
OP_IFDUP, OP_DEPTH, OP_SIZE,
|
|
|
|
// equality
|
|
|
|
OP_EQUAL, OP_EQUALVERIFY,
|
|
|
|
// arithmetic
|
|
|
|
OP_1ADD, OP_1SUB, OP_NEGATE, OP_ABS, OP_NOT, OP_0NOTEQUAL,
|
|
|
|
OP_ADD, OP_SUB, OP_BOOLAND, OP_BOOLOR,
|
|
|
|
OP_NUMEQUAL, OP_NUMEQUALVERIFY, OP_NUMNOTEQUAL, OP_LESSTHAN,
|
|
|
|
OP_GREATERTHAN, OP_LESSTHANOREQUAL, OP_GREATERTHANOREQUAL,
|
|
|
|
OP_MIN, OP_MAX, OP_WITHIN,
|
|
|
|
// crypto
|
|
|
|
OP_RIPEMD160, OP_SHA1, OP_SHA256, OP_HASH160, OP_HASH256,
|
2014-08-11 04:37:12 +00:00
|
|
|
OP_CODESEPARATOR, OP_CHECKSIG, OP_CHECKSIGVERIFY,
|
|
|
|
OP_CHECKMULTISIG, OP_CHECKMULTISIGVERIFY
|
2015-01-18 18:16:01 +00:00
|
|
|
}
|
2014-07-18 13:56:17 +00:00
|
|
|
|
|
|
|
|