URI: 
       ttransaction: replace custom enum type for opcodes with stdlib enum - electrum - Electrum Bitcoin wallet
  HTML git clone https://git.parazyd.org/electrum
   DIR Log
   DIR Files
   DIR Refs
   DIR Submodules
       ---
   DIR commit c03c17f1c7714a9a1db08ef91bf7bece9ef8dfe7
   DIR parent 9dedf51afdeb96590c49ff2d438ae7deec2f3448
  HTML Author: SomberNight <somber.night@protonmail.com>
       Date:   Fri, 22 Feb 2019 16:52:08 +0100
       
       ttransaction: replace custom enum type for opcodes with stdlib enum
       
       based on Electron-Cash/Electron-Cash@99e60b49413e103dd8e9b7cfaf22e69626db6594
       
       Diffstat:
         M electrum/gui/qt/paytoedit.py        |       3 +--
         M electrum/transaction.py             |     218 ++++++++++++++++++++-----------
       
       2 files changed, 141 insertions(+), 80 deletions(-)
       ---
   DIR diff --git a/electrum/gui/qt/paytoedit.py b/electrum/gui/qt/paytoedit.py
       t@@ -95,8 +95,7 @@ class PayToEdit(CompletionTextEdit, ScanQRTextEdit, PrintError):
                script = ''
                for word in x.split():
                    if word[0:3] == 'OP_':
       -                assert word in opcodes.lookup
       -                opcode_int = opcodes.lookup[word]
       +                opcode_int = opcodes[word]
                        assert opcode_int < 256  # opcode is single-byte
                        script += bitcoin.int_to_hex(opcode_int)
                    else:
   DIR diff --git a/electrum/transaction.py b/electrum/transaction.py
       t@@ -32,6 +32,7 @@ import traceback
        import sys
        from typing import (Sequence, Union, NamedTuple, Tuple, Optional, Iterable,
                            Callable, List, Dict)
       +from enum import IntEnum
        
        from . import ecc, bitcoin, constants, segwit_addr
        from .util import print_error, profiler, to_bytes, bh2u, bfh
       t@@ -190,81 +191,146 @@ class BCDataStream(object):
                self.write(s)
        
        
       -# enum-like type
       -# From the Python Cookbook, downloaded from http://code.activestate.com/recipes/67107/
       -class EnumException(Exception):
       -    pass
       -
       +class opcodes(IntEnum):
       +    # push value
       +    OP_0 = 0x00
       +    OP_FALSE = OP_0
       +    OP_PUSHDATA1 = 0x4c
       +    OP_PUSHDATA2 = 0x4d
       +    OP_PUSHDATA4 = 0x4e
       +    OP_1NEGATE = 0x4f
       +    OP_RESERVED = 0x50
       +    OP_1 = 0x51
       +    OP_TRUE = OP_1
       +    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
       +
       +    # control
       +    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
       +
       +    # stack ops
       +    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
       +
       +    # splice ops
       +    OP_CAT = 0x7e
       +    OP_SUBSTR = 0x7f
       +    OP_LEFT = 0x80
       +    OP_RIGHT = 0x81
       +    OP_SIZE = 0x82
       +
       +    # bit logic
       +    OP_INVERT = 0x83
       +    OP_AND = 0x84
       +    OP_OR = 0x85
       +    OP_XOR = 0x86
       +    OP_EQUAL = 0x87
       +    OP_EQUALVERIFY = 0x88
       +    OP_RESERVED1 = 0x89
       +    OP_RESERVED2 = 0x8a
       +
       +    # numeric
       +    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
       +
       +    # crypto
       +    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
       +
       +    # expansion
       +    OP_NOP1 = 0xb0
       +    OP_CHECKLOCKTIMEVERIFY = 0xb1
       +    OP_NOP2 = OP_CHECKLOCKTIMEVERIFY
       +    OP_CHECKSEQUENCEVERIFY = 0xb2
       +    OP_NOP3 = OP_CHECKSEQUENCEVERIFY
       +    OP_NOP4 = 0xb3
       +    OP_NOP5 = 0xb4
       +    OP_NOP6 = 0xb5
       +    OP_NOP7 = 0xb6
       +    OP_NOP8 = 0xb7
       +    OP_NOP9 = 0xb8
       +    OP_NOP10 = 0xb9
       +
       +    OP_INVALIDOPCODE = 0xff
       +
       +    def hex(self) -> str:
       +        return bytes([self]).hex()
        
       -class Enumeration:
       -    def __init__(self, name, enumList):
       -        self.__doc__ = name
       -        lookup = { }
       -        reverseLookup = { }
       -        i = 0
       -        uniqueNames = [ ]
       -        uniqueValues = [ ]
       -        for x in enumList:
       -            if isinstance(x, tuple):
       -                x, i = x
       -            if not isinstance(x, str):
       -                raise EnumException("enum name is not a string: " + x)
       -            if not isinstance(i, int):
       -                raise EnumException("enum value is not an integer: " + i)
       -            if x in uniqueNames:
       -                raise EnumException("enum name is not unique: " + x)
       -            if i in uniqueValues:
       -                raise EnumException("enum value is not unique for " + x)
       -            uniqueNames.append(x)
       -            uniqueValues.append(i)
       -            lookup[x] = i
       -            reverseLookup[i] = x
       -            i = i + 1
       -        self.lookup = lookup
       -        self.reverseLookup = reverseLookup
       -
       -    def __getattr__(self, attr):
       -        if attr not in self.lookup:
       -            raise AttributeError
       -        return self.lookup[attr]
       -    def whatis(self, value):
       -        return self.reverseLookup[value]
       -
       -
       -# This function comes from bitcointools, bct-LICENSE.txt.
       -def long_hex(bytes):
       -    return bytes.encode('hex_codec')
       -
       -# This function comes from bitcointools, bct-LICENSE.txt.
       -def short_hex(bytes):
       -    t = bytes.encode('hex_codec')
       -    if len(t) < 11:
       -        return t
       -    return t[0:4]+"..."+t[-4:]
       -
       -
       -
       -opcodes = Enumeration("Opcodes", [
       -    ("OP_0", 0), ("OP_PUSHDATA1",76), "OP_PUSHDATA2", "OP_PUSHDATA4", "OP_1NEGATE", "OP_RESERVED",
       -    "OP_1", "OP_2", "OP_3", "OP_4", "OP_5", "OP_6", "OP_7",
       -    "OP_8", "OP_9", "OP_10", "OP_11", "OP_12", "OP_13", "OP_14", "OP_15", "OP_16",
       -    "OP_NOP", "OP_VER", "OP_IF", "OP_NOTIF", "OP_VERIF", "OP_VERNOTIF", "OP_ELSE", "OP_ENDIF", "OP_VERIFY",
       -    "OP_RETURN", "OP_TOALTSTACK", "OP_FROMALTSTACK", "OP_2DROP", "OP_2DUP", "OP_3DUP", "OP_2OVER", "OP_2ROT", "OP_2SWAP",
       -    "OP_IFDUP", "OP_DEPTH", "OP_DROP", "OP_DUP", "OP_NIP", "OP_OVER", "OP_PICK", "OP_ROLL", "OP_ROT",
       -    "OP_SWAP", "OP_TUCK", "OP_CAT", "OP_SUBSTR", "OP_LEFT", "OP_RIGHT", "OP_SIZE", "OP_INVERT", "OP_AND",
       -    "OP_OR", "OP_XOR", "OP_EQUAL", "OP_EQUALVERIFY", "OP_RESERVED1", "OP_RESERVED2", "OP_1ADD", "OP_1SUB", "OP_2MUL",
       -    "OP_2DIV", "OP_NEGATE", "OP_ABS", "OP_NOT", "OP_0NOTEQUAL", "OP_ADD", "OP_SUB", "OP_MUL", "OP_DIV",
       -    "OP_MOD", "OP_LSHIFT", "OP_RSHIFT", "OP_BOOLAND", "OP_BOOLOR",
       -    "OP_NUMEQUAL", "OP_NUMEQUALVERIFY", "OP_NUMNOTEQUAL", "OP_LESSTHAN",
       -    "OP_GREATERTHAN", "OP_LESSTHANOREQUAL", "OP_GREATERTHANOREQUAL", "OP_MIN", "OP_MAX",
       -    "OP_WITHIN", "OP_RIPEMD160", "OP_SHA1", "OP_SHA256", "OP_HASH160",
       -    "OP_HASH256", "OP_CODESEPARATOR", "OP_CHECKSIG", "OP_CHECKSIGVERIFY", "OP_CHECKMULTISIG",
       -    "OP_CHECKMULTISIGVERIFY",
       -    ("OP_NOP1", 0xB0),
       -    ("OP_CHECKLOCKTIMEVERIFY", 0xB1), ("OP_CHECKSEQUENCEVERIFY", 0xB2),
       -    "OP_NOP4", "OP_NOP5", "OP_NOP6", "OP_NOP7", "OP_NOP8", "OP_NOP9", "OP_NOP10",
       -    ("OP_INVALIDOPCODE", 0xFF),
       -])
        
        
        def script_GetOp(_bytes : bytes):
       t@@ -294,10 +360,6 @@ def script_GetOp(_bytes : bytes):
                yield opcode, vch, i
        
        
       -def script_GetOpName(opcode):
       -    return (opcodes.whatis(opcode)).replace("OP_", "")
       -
       -
        class OPPushDataGeneric:
            def __init__(self, pushlen: Callable=None):
                if pushlen is not None: