From f4e5ec138e0903e6fe0ad81f42c6fb897d652628 Mon Sep 17 00:00:00 2001 From: 4tochka Date: Wed, 13 Mar 2019 21:21:53 +0400 Subject: [PATCH] OP_RETURN recognize fix OP_RETURN_NON_STANDARD type --- pybtc/constants.py | 3 ++- pybtc/functions/script.py | 13 ++++++++++--- pybtc/test/script_functions.py | 27 +++++++++++++++++++++++++++ pybtc/transaction.py | 6 +++--- 4 files changed, 42 insertions(+), 7 deletions(-) diff --git a/pybtc/constants.py b/pybtc/constants.py index cfed738..1e0855f 100644 --- a/pybtc/constants.py +++ b/pybtc/constants.py @@ -75,7 +75,8 @@ SCRIPT_TYPES = {"P2PKH": 0, "MULTISIG": 4, "P2WPKH": 5, "P2WSH": 6, - "NON_STANDART": 7 + "NON_STANDARD": 7, + "NULL_DATA_NON_STANDARD": 8 } diff --git a/pybtc/functions/script.py b/pybtc/functions/script.py index 6ef8934..d7af383 100644 --- a/pybtc/functions/script.py +++ b/pybtc/functions/script.py @@ -59,9 +59,16 @@ def parse_script(script, segwit=True): return {"nType": 2, "type": "PUBKEY", "reqSigs": 1, "addressHash": hash160(script[1:-1])} if l == 35 and script[-1] == 172: return {"nType": 2, "type": "PUBKEY", "reqSigs": 1, "addressHash": hash160(script[1:-1])} - if script[0] == 106 and l > 1 and l <= 82: - if script[1] == l - 2: - return {"nType": 3, "type": "NULL_DATA", "reqSigs": 0, "data": script[2:]} + if script[0] == OPCODE["OP_RETURN"]: + if l == 1: + return {"nType": 3, "type": "NULL_DATA", "reqSigs": 0, "data": b""} + elif script[1] < OPCODE["OP_PUSHDATA1"]: + if script[1] == l - 2: + return {"nType": 3, "type": "NULL_DATA", "reqSigs": 0, "data": script[2:]} + elif script[1] == OPCODE["OP_PUSHDATA1"]: + if script[2] == l - 3 and script[2] <= 80: + return {"nType": 3, "type": "NULL_DATA", "reqSigs": 0, "data": script[3:]} + return {"nType": 8, "type": "NULL_DATA_NON_STANDARD", "reqSigs": 0, "script": script} if script[0] >= 81 and script[0] <= 96: if script[-1] == 174: if script[-2] >= 81 and script[-2] <= 96: diff --git a/pybtc/test/script_functions.py b/pybtc/test/script_functions.py index fdab7c4..f9b0a98 100644 --- a/pybtc/test/script_functions.py +++ b/pybtc/test/script_functions.py @@ -26,3 +26,30 @@ class ScriptFunctionsTests(unittest.TestCase): "bc1qwqdg6squsna38e46795at95yu9atm8azzmyvckulcc7kytlcckxswvvzej") + def test_op_return_parse(self): + self.assertEqual(parse_script(OP_RETURN + b"\x00")["type"], "NULL_DATA") + self.assertEqual(parse_script(OP_RETURN + b"\x00")["data"], b"") + self.assertEqual(parse_script(OP_RETURN + b"\x2012345678901234567890123456789012")["type"], "NULL_DATA") + self.assertEqual(parse_script(OP_RETURN + b"\x2012345678901234567890123456789012")["data"], + b"12345678901234567890123456789012") + + self.assertEqual(parse_script(OP_RETURN + b"\x201234567890123456789012345678901211")["type"], + "NULL_DATA_NON_STANDARD") + + self.assertEqual(parse_script(OP_RETURN + OP_PUSHDATA1 + b"\x00")["type"], "NULL_DATA") + self.assertEqual(parse_script(OP_RETURN + OP_PUSHDATA1 + b"\x00")["data"], b"") + self.assertEqual(parse_script(OP_RETURN + OP_PUSHDATA1 + b"\x2012345678901234567890123456789012")["type"], + "NULL_DATA") + self.assertEqual(parse_script(OP_RETURN + OP_PUSHDATA1 + b"\x2012345678901234567890123456789012")["data"], + b"12345678901234567890123456789012") + + self.assertEqual(parse_script(OP_RETURN + OP_PUSHDATA1 + b"\x201234567890123456789012345678901211")["type"], + "NULL_DATA_NON_STANDARD") + self.assertEqual(parse_script(OP_RETURN + OP_PUSHDATA1 + b"\x5012345678901234567890123456789012345678901234567890123456789012345678901234567890")["type"], + "NULL_DATA") + self.assertEqual(parse_script(OP_RETURN + OP_PUSHDATA1 + b"\x5012345678901234567890123456789012345678901234567890123456789012345678901234567890")["data"], + b"12345678901234567890123456789012345678901234567890123456789012345678901234567890") + + self.assertEqual(parse_script( + OP_RETURN + OP_PUSHDATA1 + b"\x51123456789012345678901234567890123456789012345678901234567890123456789012345678901")["type"], + "NULL_DATA_NON_STANDARD") diff --git a/pybtc/transaction.py b/pybtc/transaction.py index ab2ed2b..bb5742a 100644 --- a/pybtc/transaction.py +++ b/pybtc/transaction.py @@ -84,7 +84,7 @@ class Transaction(dict): if self["data"] is None: if s["nType"] == 3: self["data"] = s["data"] - if s["nType"] not in (3, 4, 7): + if s["nType"] not in (3, 4, 7, 8): self["vOut"][k]["addressHash"] = s["addressHash"] self["vOut"][k]["reqSigs"] = s["reqSigs"] @@ -500,7 +500,7 @@ class Transaction(dict): if self["data"] is None: if s["nType"] == 3: self["data"] = s["data"] - if s["nType"] not in (3, 4, 7): + if s["nType"] not in (3, 4, 7, 8): self["vOut"][k]["addressHash"] = s["addressHash"] self["vOut"][k]["reqSigs"] = s["reqSigs"] else: @@ -508,7 +508,7 @@ class Transaction(dict): if self["data"] is None: if s["nType"] == 3: self["data"] = s["data"].hex() - if s["nType"] not in (3, 4, 7): + if s["nType"] not in (3, 4, 7, 8): self["vOut"][k]["addressHash"] = s["addressHash"].hex() self["vOut"][k]["reqSigs"] = s["reqSigs"] self["vOut"][k]["scriptPubKeyOpcodes"] = decode_script(script_pub_key)