mirror of
https://github.com/LBRYFoundation/LBRY-Vault.git
synced 2025-08-23 17:47:31 +00:00
transaction: replace custom enum type for opcodes with stdlib enum
based on Electron-Cash/Electron-Cash@99e60b4941
This commit is contained in:
parent
9dedf51afd
commit
c03c17f1c7
2 changed files with 133 additions and 72 deletions
|
@ -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:
|
||||
|
|
|
@ -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
|
||||
|
@ -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
|
||||
|
||||
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
|
||||
# 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
|
||||
|
||||
def __getattr__(self, attr):
|
||||
if attr not in self.lookup:
|
||||
raise AttributeError
|
||||
return self.lookup[attr]
|
||||
def whatis(self, value):
|
||||
return self.reverseLookup[value]
|
||||
# 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
|
||||
|
||||
# This function comes from bitcointools, bct-LICENSE.txt.
|
||||
def long_hex(bytes):
|
||||
return bytes.encode('hex_codec')
|
||||
# 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
|
||||
|
||||
# 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:]
|
||||
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()
|
||||
|
||||
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):
|
||||
|
@ -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:
|
||||
|
|
Loading…
Add table
Reference in a new issue