forked from LBRYCommunity/lbry-sdk
76 lines
2.9 KiB
Python
76 lines
2.9 KiB
Python
import struct
|
|
from .enumeration import Enumeration
|
|
|
|
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", "OP_NOP2", "OP_NOP3", "OP_NOP4", "OP_NOP5",
|
|
"OP_CLAIM_NAME",
|
|
"OP_SUPPORT_CLAIM", "OP_UPDATE_CLAIM",
|
|
("OP_SINGLEBYTE_END", 0xF0),
|
|
("OP_DOUBLEBYTE_BEGIN", 0xF000),
|
|
"OP_PUBKEY", "OP_PUBKEYHASH",
|
|
("OP_INVALIDOPCODE", 0xFFFF),
|
|
])
|
|
|
|
|
|
def script_GetOp(bytes):
|
|
i = 0
|
|
while i < len(bytes):
|
|
vch = None
|
|
opcode = ord(bytes[i])
|
|
i += 1
|
|
if opcode >= opcodes.OP_SINGLEBYTE_END:
|
|
opcode <<= 8
|
|
opcode |= ord(bytes[i])
|
|
i += 1
|
|
|
|
if opcode <= opcodes.OP_PUSHDATA4:
|
|
nSize = opcode
|
|
if opcode == opcodes.OP_PUSHDATA1:
|
|
nSize = ord(bytes[i])
|
|
i += 1
|
|
elif opcode == opcodes.OP_PUSHDATA2:
|
|
(nSize,) = struct.unpack_from('<H', bytes, i)
|
|
i += 2
|
|
elif opcode == opcodes.OP_PUSHDATA4:
|
|
(nSize,) = struct.unpack_from('<I', bytes, i)
|
|
i += 4
|
|
vch = bytes[i:i + nSize]
|
|
i += nSize
|
|
|
|
yield (opcode, vch, i)
|
|
|
|
|
|
def script_GetOpName(opcode):
|
|
return (opcodes.whatis(opcode)).replace("OP_", "")
|
|
|
|
|
|
def match_decoded(decoded, to_match):
|
|
if len(decoded) != len(to_match):
|
|
return False
|
|
for i, d in enumerate(decoded):
|
|
if to_match[i] == opcodes.OP_PUSHDATA4 and opcodes.OP_PUSHDATA4 >= d[0] > 0:
|
|
# Opcodes below OP_PUSHDATA4 all just push data onto stack, # and are equivalent.
|
|
continue
|
|
if to_match[i] != decoded[i][0]:
|
|
return False
|
|
return True
|