transaction.py: fix script_GetOp for malformed scripts
related fyookball/electrum#829
This commit is contained in:
@@ -59,6 +59,10 @@ class NotRecognizedRedeemScript(Exception):
|
||||
pass
|
||||
|
||||
|
||||
class MalformedBitcoinScript(Exception):
|
||||
pass
|
||||
|
||||
|
||||
TxOutput = NamedTuple("TxOutput", [('type', int), ('address', str), ('value', Union[int, str])])
|
||||
# ^ value is str when the output is set to max: '!'
|
||||
|
||||
@@ -263,13 +267,16 @@ def script_GetOp(_bytes : bytes):
|
||||
if opcode <= opcodes.OP_PUSHDATA4:
|
||||
nSize = opcode
|
||||
if opcode == opcodes.OP_PUSHDATA1:
|
||||
nSize = _bytes[i]
|
||||
try: nSize = _bytes[i]
|
||||
except IndexError: raise MalformedBitcoinScript()
|
||||
i += 1
|
||||
elif opcode == opcodes.OP_PUSHDATA2:
|
||||
(nSize,) = struct.unpack_from('<H', _bytes, i)
|
||||
try: (nSize,) = struct.unpack_from('<H', _bytes, i)
|
||||
except struct.error: raise MalformedBitcoinScript()
|
||||
i += 2
|
||||
elif opcode == opcodes.OP_PUSHDATA4:
|
||||
(nSize,) = struct.unpack_from('<I', _bytes, i)
|
||||
try: (nSize,) = struct.unpack_from('<I', _bytes, i)
|
||||
except struct.error: raise MalformedBitcoinScript()
|
||||
i += 4
|
||||
vch = _bytes[i:i + nSize]
|
||||
i += nSize
|
||||
@@ -281,21 +288,11 @@ def script_GetOpName(opcode):
|
||||
return (opcodes.whatis(opcode)).replace("OP_", "")
|
||||
|
||||
|
||||
def decode_script(bytes):
|
||||
result = ''
|
||||
for (opcode, vch, i) in script_GetOp(bytes):
|
||||
if len(result) > 0: result += " "
|
||||
if opcode <= opcodes.OP_PUSHDATA4:
|
||||
result += "%d:"%(opcode,)
|
||||
result += short_hex(vch)
|
||||
else:
|
||||
result += script_GetOpName(opcode)
|
||||
return result
|
||||
|
||||
|
||||
def match_decoded(decoded, to_match):
|
||||
if decoded is None:
|
||||
return False
|
||||
if len(decoded) != len(to_match):
|
||||
return False;
|
||||
return False
|
||||
for i in range(len(decoded)):
|
||||
if to_match[i] == opcodes.OP_PUSHDATA4 and decoded[i][0] <= opcodes.OP_PUSHDATA4 and decoded[i][0]>0:
|
||||
continue # Opcodes below OP_PUSHDATA4 all just push data onto stack, and are equivalent.
|
||||
@@ -413,7 +410,10 @@ def parse_scriptSig(d, _bytes):
|
||||
|
||||
|
||||
def parse_redeemScript_multisig(redeem_script: bytes):
|
||||
dec2 = [ x for x in script_GetOp(redeem_script) ]
|
||||
try:
|
||||
dec2 = [ x for x in script_GetOp(redeem_script) ]
|
||||
except MalformedBitcoinScript:
|
||||
raise NotRecognizedRedeemScript()
|
||||
try:
|
||||
m = dec2[0][0] - opcodes.OP_1 + 1
|
||||
n = dec2[-2][0] - opcodes.OP_1 + 1
|
||||
@@ -434,7 +434,10 @@ def parse_redeemScript_multisig(redeem_script: bytes):
|
||||
|
||||
|
||||
def get_address_from_output_script(_bytes, *, net=None):
|
||||
decoded = [x for x in script_GetOp(_bytes)]
|
||||
try:
|
||||
decoded = [x for x in script_GetOp(_bytes)]
|
||||
except MalformedBitcoinScript:
|
||||
decoded = None
|
||||
|
||||
# The Genesis Block, self-payments, and pay-by-IP-address payments look like:
|
||||
# 65 BYTES:... CHECKSIG
|
||||
|
||||
Reference in New Issue
Block a user