URI: 
       tmove opcodes to bitcoin.py - electrum - Electrum Bitcoin wallet
  HTML git clone https://git.parazyd.org/electrum
   DIR Log
   DIR Files
   DIR Refs
   DIR Submodules
       ---
   DIR commit e7f38467d7a592ab5288e29200cbace65e87834e
   DIR parent c03c17f1c7714a9a1db08ef91bf7bece9ef8dfe7
  HTML Author: SomberNight <somber.night@protonmail.com>
       Date:   Fri, 22 Feb 2019 17:34:43 +0100
       
       move opcodes to bitcoin.py
       
       Diffstat:
         M electrum/bitcoin.py                 |     179 +++++++++++++++++++++++++++----
         M electrum/gui/qt/paytoedit.py        |       4 ++--
         M electrum/plugins/hw_wallet/plugin.… |       4 ++--
         M electrum/tests/test_bitcoin.py      |      30 +++++++++++++++---------------
         M electrum/transaction.py             |     154 ++-----------------------------
       
       5 files changed, 183 insertions(+), 188 deletions(-)
       ---
   DIR diff --git a/electrum/bitcoin.py b/electrum/bitcoin.py
       t@@ -25,6 +25,7 @@
        
        import hashlib
        from typing import List, Tuple, TYPE_CHECKING, Optional, Union
       +from enum import IntEnum
        
        from .util import bfh, bh2u, BitcoinException, assert_bytes, to_bytes, inv_dict
        from . import version
       t@@ -49,6 +50,147 @@ TYPE_PUBKEY  = 1
        TYPE_SCRIPT  = 2
        
        
       +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()
       +
       +
        def rev_hex(s: str) -> str:
            return bh2u(bfh(s)[::-1])
        
       t@@ -112,15 +254,15 @@ def witness_push(item: str) -> str:
            return var_int(len(item) // 2) + item
        
        
       -def op_push(i: int) -> str:
       -    if i<0x4c:  # OP_PUSHDATA1
       +def _op_push(i: int) -> str:
       +    if i < opcodes.OP_PUSHDATA1:
                return int_to_hex(i)
       -    elif i<=0xff:
       -        return '4c' + int_to_hex(i)
       -    elif i<=0xffff:
       -        return '4d' + int_to_hex(i,2)
       +    elif i <= 0xff:
       +        return opcodes.OP_PUSHDATA1.hex() + int_to_hex(i, 1)
       +    elif i <= 0xffff:
       +        return opcodes.OP_PUSHDATA2.hex() + int_to_hex(i, 2)
            else:
       -        return '4e' + int_to_hex(i,4)
       +        return opcodes.OP_PUSHDATA4.hex() + int_to_hex(i, 4)
        
        
        def push_script(data: str) -> str:
       t@@ -131,19 +273,17 @@ def push_script(data: str) -> str:
            ported from https://github.com/btcsuite/btcd/blob/fdc2bc867bda6b351191b5872d2da8270df00d13/txscript/scriptbuilder.go#L128
            """
            data = bfh(data)
       -    from .transaction import opcodes
       -
            data_len = len(data)
        
            # "small integer" opcodes
            if data_len == 0 or data_len == 1 and data[0] == 0:
       -        return bh2u(bytes([opcodes.OP_0]))
       +        return opcodes.OP_0.hex()
            elif data_len == 1 and data[0] <= 16:
                return bh2u(bytes([opcodes.OP_1 - 1 + data[0]]))
            elif data_len == 1 and data[0] == 0x81:
       -        return bh2u(bytes([opcodes.OP_1NEGATE]))
       +        return opcodes.OP_1NEGATE.hex()
        
       -    return op_push(data_len) + bh2u(data)
       +    return _op_push(data_len) + bh2u(data)
        
        
        def add_number_to_script(i: int) -> bytes:
       t@@ -305,19 +445,18 @@ def address_to_script(addr: str, *, net=None) -> str:
            if witprog is not None:
                if not (0 <= witver <= 16):
                    raise BitcoinException(f'impossible witness version: {witver}')
       -        OP_n = witver + 0x50 if witver > 0 else 0
       -        script = bh2u(bytes([OP_n]))
       +        script = bh2u(add_number_to_script(witver))
                script += push_script(bh2u(bytes(witprog)))
                return script
            addrtype, hash_160_ = b58_address_to_hash160(addr)
            if addrtype == net.ADDRTYPE_P2PKH:
       -        script = '76a9'                                      # op_dup, op_hash_160
       +        script = bytes([opcodes.OP_DUP, opcodes.OP_HASH160]).hex()
                script += push_script(bh2u(hash_160_))
       -        script += '88ac'                                     # op_equalverify, op_checksig
       +        script += bytes([opcodes.OP_EQUALVERIFY, opcodes.OP_CHECKSIG]).hex()
            elif addrtype == net.ADDRTYPE_P2SH:
       -        script = 'a9'                                        # op_hash_160
       +        script = opcodes.OP_HASH160.hex()
                script += push_script(bh2u(hash_160_))
       -        script += '87'                                       # op_equal
       +        script += opcodes.OP_EQUAL.hex()
            else:
                raise BitcoinException(f'unknown address type: {addrtype}')
            return script
       t@@ -331,9 +470,7 @@ def script_to_scripthash(script: str) -> str:
            return bh2u(bytes(reversed(h)))
        
        def public_key_to_p2pk_script(pubkey: str) -> str:
       -    script = push_script(pubkey)
       -    script += 'ac'                                           # op_checksig
       -    return script
       +    return push_script(pubkey) + opcodes.OP_CHECKSIG.hex()
        
        __b58chars = b'123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz'
        assert len(__b58chars) == 58
   DIR diff --git a/electrum/gui/qt/paytoedit.py b/electrum/gui/qt/paytoedit.py
       t@@ -30,7 +30,8 @@ from PyQt5.QtGui import QFontMetrics
        
        from electrum import bitcoin
        from electrum.util import bfh, PrintError
       -from electrum.transaction import TxOutput
       +from electrum.transaction import TxOutput, push_script
       +from electrum.bitcoin import opcodes
        
        from .qrtextedit import ScanQRTextEdit
        from .completion_text_edit import CompletionTextEdit
       t@@ -91,7 +92,6 @@ class PayToEdit(CompletionTextEdit, ScanQRTextEdit, PrintError):
                    return bitcoin.TYPE_SCRIPT, script
        
            def parse_script(self, x):
       -        from electrum.transaction import opcodes, push_script
                script = ''
                for word in x.split():
                    if word[0:3] == 'OP_':
   DIR diff --git a/electrum/plugins/hw_wallet/plugin.py b/electrum/plugins/hw_wallet/plugin.py
       t@@ -26,9 +26,9 @@
        
        from electrum.plugin import BasePlugin, hook
        from electrum.i18n import _
       -from electrum.bitcoin import is_address, TYPE_SCRIPT
       +from electrum.bitcoin import is_address, TYPE_SCRIPT, opcodes
        from electrum.util import bfh, versiontuple, UserFacingException
       -from electrum.transaction import opcodes, TxOutput, Transaction
       +from electrum.transaction import TxOutput, Transaction
        
        
        class HW_PluginBase(BasePlugin):
   DIR diff --git a/electrum/tests/test_bitcoin.py b/electrum/tests/test_bitcoin.py
       t@@ -3,18 +3,18 @@ import sys
        
        from electrum.bitcoin import (public_key_to_p2pkh, address_from_private_key,
                                      is_address, is_private_key, is_new_seed, is_old_seed,
       -                              var_int, op_push, address_to_script,
       +                              var_int, _op_push, address_to_script,
                                      deserialize_privkey, serialize_privkey, is_segwit_address,
                                      is_b58_address, address_to_scripthash, is_minikey,
                                      is_compressed_privkey, seed_type, EncodeBase58Check,
       -                              script_num_to_hex, push_script, add_number_to_script, int_to_hex)
       +                              script_num_to_hex, push_script, add_number_to_script, int_to_hex,
       +                              opcodes)
        from electrum.bip32 import (bip32_root, bip32_public_derivation, bip32_private_derivation,
                                    xpub_from_xprv, xpub_type, is_xprv, is_bip32_derivation,
                                    is_xpub, convert_bip32_path_to_list_of_uint32)
        from electrum.crypto import sha256d, SUPPORTED_PW_HASH_VERSIONS
        from electrum import ecc, crypto, constants
        from electrum.ecc import number_to_string, string_to_number
       -from electrum.transaction import opcodes
        from electrum.util import bfh, bh2u, InvalidPassword
        from electrum.storage import WalletStorage
        from electrum.keystore import xtype_from_derivation
       t@@ -291,18 +291,18 @@ class Test_bitcoin(SequentialTestCase):
                self.assertEqual(var_int(0x0123456789abcdef), "ffefcdab8967452301")
        
            def test_op_push(self):
       -        self.assertEqual(op_push(0x00), '00')
       -        self.assertEqual(op_push(0x12), '12')
       -        self.assertEqual(op_push(0x4b), '4b')
       -        self.assertEqual(op_push(0x4c), '4c4c')
       -        self.assertEqual(op_push(0xfe), '4cfe')
       -        self.assertEqual(op_push(0xff), '4cff')
       -        self.assertEqual(op_push(0x100), '4d0001')
       -        self.assertEqual(op_push(0x1234), '4d3412')
       -        self.assertEqual(op_push(0xfffe), '4dfeff')
       -        self.assertEqual(op_push(0xffff), '4dffff')
       -        self.assertEqual(op_push(0x10000), '4e00000100')
       -        self.assertEqual(op_push(0x12345678), '4e78563412')
       +        self.assertEqual(_op_push(0x00), '00')
       +        self.assertEqual(_op_push(0x12), '12')
       +        self.assertEqual(_op_push(0x4b), '4b')
       +        self.assertEqual(_op_push(0x4c), '4c4c')
       +        self.assertEqual(_op_push(0xfe), '4cfe')
       +        self.assertEqual(_op_push(0xff), '4cff')
       +        self.assertEqual(_op_push(0x100), '4d0001')
       +        self.assertEqual(_op_push(0x1234), '4d3412')
       +        self.assertEqual(_op_push(0xfffe), '4dfeff')
       +        self.assertEqual(_op_push(0xffff), '4dffff')
       +        self.assertEqual(_op_push(0x10000), '4e00000100')
       +        self.assertEqual(_op_push(0x12345678), '4e78563412')
        
            def test_script_num_to_hex(self):
                # test vectors from https://github.com/btcsuite/btcd/blob/fdc2bc867bda6b351191b5872d2da8270df00d13/txscript/scriptnum.go#L77
   DIR diff --git a/electrum/transaction.py b/electrum/transaction.py
       t@@ -32,14 +32,14 @@ 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
        from .bitcoin import (TYPE_ADDRESS, TYPE_PUBKEY, TYPE_SCRIPT, hash_160,
                              hash160_to_p2sh, hash160_to_p2pkh, hash_to_segwit_addr,
                              hash_encode, var_int, TOTAL_COIN_SUPPLY_LIMIT_IN_BTC, COIN,
       -                      push_script, int_to_hex, push_script, b58_address_to_hash160)
       +                      push_script, int_to_hex, push_script, b58_address_to_hash160,
       +                      opcodes, add_number_to_script)
        from .crypto import sha256d
        from .keystore import xpubkey_to_address, xpubkey_to_pubkey
        
       t@@ -191,148 +191,6 @@ class BCDataStream(object):
                self.write(s)
        
        
       -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()
       -
       -
       -
        def script_GetOp(_bytes : bytes):
            i = 0
            while i < len(_bytes):
       t@@ -714,10 +572,10 @@ def deserialize(raw: str, force_full_parse=False) -> dict:
        def multisig_script(public_keys: Sequence[str], m: int) -> str:
            n = len(public_keys)
            assert 1 <= m <= n <= 15, f'm {m}, n {n}'
       -    op_m = bh2u(bytes([opcodes.OP_1 - 1 + m]))
       -    op_n = bh2u(bytes([opcodes.OP_1 - 1 + n]))
       +    op_m = bh2u(add_number_to_script(m))
       +    op_n = bh2u(add_number_to_script(n))
            keylist = [push_script(k) for k in public_keys]
       -    return op_m + ''.join(keylist) + op_n + 'ae'
       +    return op_m + ''.join(keylist) + op_n + opcodes.OP_CHECKMULTISIG.hex()
        
        
        
       t@@ -1024,7 +882,7 @@ class Transaction:
                    scriptSig = bitcoin.p2wsh_nested_script(witness_script)
                    return push_script(scriptSig)
                elif _type == 'address':
       -            return 'ff00' + push_script(pubkeys[0])  # fd extended pubkey
       +            return bytes([opcodes.OP_INVALIDOPCODE, opcodes.OP_0]).hex() + push_script(pubkeys[0])
                elif _type == 'unknown':
                    return txin['scriptSig']
                return script