defmodule Bitcoinex.Opcode do
  @moduledoc """
  	a module for storing the list of opcodes by number and atom
  	and defining the functions associated with each opcode
  """

  def opcode_nums,
    do: %{
      0x00 => :op_0,
      0x4C => :op_pushdata1,
      0x4D => :op_pushdata2,
      0x4E => :op_pushdata4,
      0x4F => :op_1negate,
      0x50 => :op_reserved,
      0x51 => :op_1,
      0x52 => :op_2,
      0x53 => :op_3,
      0x54 => :op_4,
      0x55 => :op_5,
      0x56 => :op_6,
      0x57 => :op_7,
      0x58 => :op_8,
      0x59 => :op_9,
      0x5A => :op_10,
      0x5B => :op_11,
      0x5C => :op_12,
      0x5D => :op_13,
      0x5E => :op_14,
      0x5F => :op_15,
      0x60 => :op_16,
      0x61 => :op_nop,
      0x62 => :op_ver,
      0x63 => :op_if,
      0x64 => :op_notif,
      0x65 => :op_verif,
      0x66 => :op_vernotif,
      0x67 => :op_else,
      0x68 => :op_endif,
      0x69 => :op_verify,
      0x6A => :op_return,
      0x6B => :op_toaltstack,
      0x6C => :op_fromaltstack,
      0x6D => :op_2drop,
      0x6E => :op_2dup,
      0x6F => :op_3dup,
      0x70 => :op_2over,
      0x71 => :op_2rot,
      0x72 => :op_2swap,
      0x73 => :op_ifdup,
      0x74 => :op_depth,
      0x75 => :op_drop,
      0x76 => :op_dup,
      0x77 => :op_nip,
      0x78 => :op_over,
      0x79 => :op_pick,
      0x7A => :op_roll,
      0x7B => :op_rot,
      0x7C => :op_swap,
      0x7D => :op_tuck,
      0x7E => :op_cat,
      0x7F => :op_substr,
      0x80 => :op_left,
      0x81 => :op_right,
      0x82 => :op_size,
      0x83 => :op_invert,
      0x84 => :op_and,
      0x85 => :op_or,
      0x86 => :op_xor,
      0x87 => :op_equal,
      0x88 => :op_equalverify,
      0x89 => :op_reserved1,
      0x8A => :op_reserved2,
      0x8B => :op_1add,
      0x8C => :op_1sub,
      0x8D => :op_2mul,
      0x8E => :op_2div,
      0x8F => :op_negate,
      0x90 => :op_abs,
      0x91 => :op_not,
      0x92 => :op_0notequal,
      0x93 => :op_add,
      0x94 => :op_sub,
      0x95 => :op_mul,
      0x96 => :op_div,
      0x97 => :op_mod,
      0x98 => :op_lshift,
      0x99 => :op_rshift,
      0x9A => :op_booland,
      0x9B => :op_boolor,
      0x9C => :op_numequal,
      0x9D => :op_numequalverify,
      0x9E => :op_numnotequal,
      0x9F => :op_lessthan,
      0xA0 => :op_greaterthan,
      0xA1 => :op_lessthanorequal,
      0xA2 => :op_greaterthanorequal,
      0xA3 => :op_min,
      0xA4 => :op_max,
      0xA5 => :op_within,
      0xA6 => :op_ripemd160,
      0xA7 => :op_sha1,
      0xA8 => :op_sha256,
      0xA9 => :op_hash160,
      0xAA => :op_hash256,
      0xAB => :op_codeseparator,
      0xAC => :op_checksig,
      0xAD => :op_checksigverify,
      0xAE => :op_checkmultisig,
      0xAF => :op_checkmultisigverify,
      0xB0 => :op_nop1,
      0xB1 => :op_checklocktimeverify,
      0xB2 => :op_nop3,
      0xB3 => :op_nop4,
      0xB4 => :op_nop5,
      0xB5 => :op_nop6,
      0xB6 => :op_nop7,
      0xB7 => :op_nop8,
      0xB8 => :op_nop9,
      0xB9 => :op_nop10,
      0xFA => :op_smallinteger,
      0xFB => :op_pubkeys,
      0xFD => :op_pubkeyhash,
      0xFE => :op_pubkey,
      0xFF => :op_invalidopcode
    }

  def opcode_atoms,
    do: %{
      op_0: 0x00,
      op_false: 0x00,
      op_pushdata1: 0x4C,
      op_pushdata2: 0x4D,
      op_pushdata4: 0x4E,
      op_1negate: 0x4F,
      op_reserved: 0x50,
      op_1: 0x51,
      op_true: 0x51,
      op_2: 0x52,
      op_3: 0x53,
      op_4: 0x54,
      op_5: 0x55,
      op_6: 0x56,
      op_7: 0x57,
      op_8: 0x58,
      op_9: 0x59,
      op_10: 0x5A,
      op_11: 0x5B,
      op_12: 0x5C,
      op_13: 0x5D,
      op_14: 0x5E,
      op_15: 0x5F,
      op_16: 0x60,
      op_nop: 0x61,
      op_ver: 0x62,
      op_if: 0x63,
      op_notif: 0x64,
      op_verif: 0x65,
      op_vernotif: 0x66,
      op_else: 0x67,
      op_endif: 0x68,
      op_verify: 0x69,
      op_return: 0x6A,
      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,
      op_depth: 0x74,
      op_drop: 0x75,
      op_dup: 0x76,
      op_nip: 0x77,
      op_over: 0x78,
      op_pick: 0x79,
      op_roll: 0x7A,
      op_rot: 0x7B,
      op_swap: 0x7C,
      op_tuck: 0x7D,
      op_cat: 0x7E,
      op_substr: 0x7F,
      op_left: 0x80,
      op_right: 0x81,
      op_size: 0x82,
      op_invert: 0x83,
      op_and: 0x84,
      op_or: 0x85,
      op_xor: 0x86,
      op_equal: 0x87,
      op_equalverify: 0x88,
      op_reserved1: 0x89,
      op_reserved2: 0x8A,
      op_1add: 0x8B,
      op_1sub: 0x8C,
      op_2mul: 0x8D,
      op_2div: 0x8E,
      op_negate: 0x8F,
      op_abs: 0x90,
      op_not: 0x91,
      op_0notequal: 0x92,
      op_add: 0x93,
      op_sub: 0x94,
      op_mul: 0x95,
      op_div: 0x96,
      op_mod: 0x97,
      op_lshift: 0x98,
      op_rshift: 0x99,
      op_booland: 0x9A,
      op_boolor: 0x9B,
      op_numequal: 0x9C,
      op_numequalverify: 0x9D,
      op_numnotequal: 0x9E,
      op_lessthan: 0x9F,
      op_greaterthan: 0xA0,
      op_lessthanorequal: 0xA1,
      op_greaterthanorequal: 0xA2,
      op_min: 0xA3,
      op_max: 0xA4,
      op_within: 0xA5,
      op_ripemd160: 0xA6,
      op_sha1: 0xA7,
      op_sha256: 0xA8,
      op_hash160: 0xA9,
      op_hash256: 0xAA,
      op_codeseparator: 0xAB,
      op_checksig: 0xAC,
      op_checksigverify: 0xAD,
      op_checkmultisig: 0xAE,
      op_checkmultisigverify: 0xAF,
      op_nop1: 0xB0,
      op_nop2: 0xB1,
      op_checklocktimeverify: 0xB1,
      op_nop3: 0xB2,
      op_nop4: 0xB3,
      op_nop5: 0xB4,
      op_nop6: 0xB5,
      op_nop7: 0xB6,
      op_nop8: 0xB7,
      op_nop9: 0xB8,
      op_nop10: 0xB9,
      op_smallinteger: 0xFA,
      op_pubkeys: 0xFB,
      op_pubkeyhash: 0xFD,
      op_pubkey: 0xFE,
      op_invalidopcode: 0xFF
    }
end
