示例#1
0
    async def load_utxo_from_daemon(self):
        #
        #  load missed utxo from bitcoind daemon
        #
        if not self.missed_failed: return
        missed = chunks_by_count(self.missed_failed, 50)
        for m in missed:
            result = await self.rpc.batch([["getrawtransaction", rh2s(i[:32]), 1] for i in m])
            hash_list = set()
            for r in result:
                if r["result"]["blockhash"] not in self.restore_blocks_cache:
                    hash_list.add(r["result"]["blockhash"])

            result2 = await self.rpc.batch([["getblock", r] for r in hash_list])
            for r in result2:
               self.restore_blocks_cache[r["result"]["hash"]] = r["result"]

            for key, r in zip(m, result):
                out_index = bytes_to_int(key[32:])
                tx=r["result"]
                amount = int(tx["vout"][out_index]["value"] * 100000000)
                script = parse_script(tx["vout"][out_index]["scriptPubKey"]["hex"])
                try:
                    address = b"".join((bytes([script["nType"]]), script["addressHash"]))
                except:
                    address = b"".join((bytes([script["nType"]]), script["script"]))
                block = self.restore_blocks_cache[tx["blockhash"]]

                tx_index = block["tx"].index(tx["txid"])
                block_height = block["height"]
                pointer = (block_height << 39) + (tx_index << 20) + (1 << 19) + out_index
                self.loaded[key] = (pointer, amount, address)
        self.missed_failed = list()
        while len(self.restore_blocks_cache) > 1000:
            self.restore_blocks_cache.pop()
示例#2
0
 def __sign_p2sh_p2wsh(self, n, private_key, public_key,
                       redeem_script, sighash_type, amount):
     rst = parse_script(redeem_script)
     if rst["type"] == "MULTISIG":
         return self.__sign_p2sh_p2wsh_multisig(n, private_key, public_key,
                                                redeem_script, sighash_type, amount)
     else:
         raise RuntimeError("not implemented")
示例#3
0
    def add_output(self, amount, address=None, script_pub_key=None):
        if address is None and script_pub_key is None:
            raise Exception("unable to add output, address or script required")
        if type(amount) != int:
            raise TypeError("unable to add output, amount type error")
        if amount < 0 or amount > MAX_AMOUNT:
            raise Exception("unable to add output, amount value error")
        if script_pub_key:
            if isinstance(script_pub_key, str):
                script_pub_key = bytes_from_hex(script_pub_key)
            if not isinstance(script_pub_key, bytes):
                raise TypeError("unable to add output, script_pub_key type error")
        else:
            if type(address) == Address:
                address = address.address
            script_pub_key = address_to_script(address)

        k = len(self["vOut"])
        self["vOut"][k] = dict()
        self["vOut"][k]["value"] = amount
        segwit = True if "segwit" in self else False
        s = parse_script(script_pub_key, segwit)
        self["vOut"][k]["nType"] = s["nType"]
        self["vOut"][k]["type"] = s["type"]

        if self["format"] == "raw":
            self["vOut"][k]["scriptPubKey"] = script_pub_key
            if self["data"] is None:
                if s["nType"] == 3:
                    self["data"] = s["data"]
            if s["nType"] not in (3, 4, 7, 8):
                self["vOut"][k]["addressHash"] = s["addressHash"]
                self["vOut"][k]["reqSigs"] = s["reqSigs"]
        else:
            self["vOut"][k]["scriptPubKey"] = script_pub_key.hex()
            if self["data"] is None:
                if s["nType"] == 3:
                    self["data"] = s["data"].hex()
            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)
            self["vOut"][k]["scriptPubKeyAsm"] = decode_script(script_pub_key, 1)
            sh = True if self["vOut"][k]["nType"] in (1, 5) else False
            witness_version = None if self["vOut"][k]["nType"] < 5 else 0
            if "addressHash" in self["vOut"][k]:
                self["vOut"][k]["address"] = hash_to_address(self["vOut"][k]["addressHash"],
                                                             self["testnet"],
                                                             sh,
                                                             witness_version)
        if self.auto_commit:
            self.commit()
        return self
示例#4
0
def parse_script(script, segwit=True):
    """
    Parse script and return script type, script address and required signatures count.

    :param script: script in bytes string or HEX encoded string format.
    :param segwit:  (optional) If set to True recognize P2WPKH and P2WSH sripts, by default set to True.

    :return: dictionary:

            - nType - numeric script type
            - type  - script type
            - addressHash - address hash in case address recognized
            - script - script if no address recognized
            - reqSigs - required signatures count
    """
    return __parent__.parse_script(script, segwit=segwit)
示例#5
0
    def __sign_p2sh(self, n, private_key, public_key, redeem_script, sighash_type, amount, p2sh_p2wsh):
        if not redeem_script:
            if "redeemScript" in self["vIn"][n]:
                redeem_script = self["vIn"][n]["redeemScript"]
            else:
                raise RuntimeError("no redeem script")
        if isinstance(redeem_script, str):
            redeem_script = bytes.fromhex(redeem_script)
        rst = parse_script(redeem_script)

        if p2sh_p2wsh:
            return self.__sign_p2sh_p2wsh(n, private_key,
                                          public_key, redeem_script, sighash_type, amount)
        if rst["type"] == "MULTISIG":
            return self.__sign_p2sh_multisig(n, private_key, public_key, redeem_script, sighash_type)
        elif rst["type"] == "P2WPKH":
            return self.__sign_p2sh_p2wpkh(n, private_key, public_key, redeem_script, sighash_type, amount)
        else:
            return self.__sign_p2sh_custom(n, private_key, public_key, redeem_script, sighash_type, amount)
示例#6
0
 def __sign_p2wsh(self, n, private_key, public_key, script_pub_key, redeem_script, sighash_type, amount):
     self["segwit"] = True
     if not redeem_script:
         if "redeemScript" in self["vIn"][n]:
             redeem_script = self["vIn"][n]["redeemScript"]
         else:
             raise RuntimeError("no redeem script")
     if isinstance(redeem_script, str):
         redeem_script = bytes.fromhex(redeem_script)
     rst = parse_script(redeem_script)
     if amount is None:
         try:
             amount = self["vIn"][n]["value"]
         except:
             raise RuntimeError("no input amount")
     if rst["type"] == "MULTISIG":
         return self.__sign_p2wsh_multisig(n, private_key, public_key,
                                           script_pub_key, redeem_script, sighash_type, amount)
     else:
         return self.__sign_p2wsh_custom(n, private_key, public_key,
                                         script_pub_key, redeem_script, sighash_type, amount)
示例#7
0
    def sign_input(self, n, private_key=None, script_pub_key=None,
                   redeem_script=None,
                   sighash_type=SIGHASH_ALL,
                   address=None, amount=None, witness_version=0,
                   p2sh_p2wsh=False):
        # private key
        if not private_key:
            try:
                private_key = self["vIn"][n]["private_key"].key
            except:
                raise RuntimeError("no private key")
        if isinstance(private_key, list):
            public_key = [PublicKey(p).key for p in private_key]
            private_key = [p.key if isinstance(p, PrivateKey) else PrivateKey(p).key for p in private_key]
        else:
            if not isinstance(private_key, PrivateKey):
                private_key = PrivateKey(private_key)
            public_key = [PublicKey(private_key).key]
            private_key = [private_key.key]

        if address is not None:
            if isinstance(address, str):
                net = True if address_net_type(address) == 'mainnet' else False
                if not net != self["testnet"]:
                    raise TypeError("address invalid")
                script_pub_key = address_to_script(address)
            elif type(address) in (Address, ScriptAddress):
                script_pub_key = address_to_script(address.address)
        # script pub key
        if script_pub_key is None:

            if "scriptPubKey" in self["vIn"][n]:
                script_pub_key = self["vIn"][n]["scriptPubKey"]
                st = parse_script(script_pub_key)
            elif redeem_script or "redeemScript" in self["vIn"][n]:
                if witness_version is None or p2sh_p2wsh:
                    st = {"type": "P2SH"}
                elif witness_version == 0:
                    st = {"type": "P2WSH"}
                else:
                    raise RuntimeError("not implemented")
            else:
                raise RuntimeError("no scriptPubKey key")
        else:
            st = parse_script(script_pub_key)
        if isinstance(script_pub_key, str):
            script_pub_key = bytes.fromhex(script_pub_key)

        # sign input
        if st["type"] == "PUBKEY":
            script_sig = self.__sign_pubkey__(n, private_key, script_pub_key, sighash_type)
        elif st["type"] == "P2PKH":
            script_sig = self.__sign_p2pkh__(n, private_key, public_key, script_pub_key, sighash_type)
        elif st["type"] == "P2SH":
            script_sig = self.__sign_p2sh(n, private_key, public_key, redeem_script, sighash_type, amount, p2sh_p2wsh)
        elif st["type"] == "P2WPKH":
            script_sig = self.__sign_p2wpkh(n, private_key, public_key, script_pub_key, sighash_type, amount)
        elif st["type"] == "P2WSH":
            script_sig = self.__sign_p2wsh(n, private_key, public_key, script_pub_key,
                                           redeem_script, sighash_type, amount)
        elif st["type"] == "MULTISIG":
            script_sig = self.__sign_bare_multisig__(n, private_key, public_key, script_pub_key, sighash_type)
        else:
            raise RuntimeError("not implemented")

        if self["format"] == "raw":
            self["vIn"][n]["scriptSig"] = script_sig
        else:
            self["vIn"][n]["scriptSig"] = script_sig.hex()
            self["vIn"][n]["scriptSigOpcodes"] = decode_script(script_sig)
            self["vIn"][n]["scriptSigAsm"] = decode_script(script_sig, 1)
        if self.auto_commit:
            self.commit()
        return self
示例#8
0
    def __init__(self, raw_tx=None, format="decoded", version=1, lock_time=0, testnet=False, auto_commit=True):
        if format not in ("decoded", "raw"):
            raise ValueError("format error, raw or decoded allowed")
        self.auto_commit = auto_commit
        self["format"] = format
        self["testnet"] = testnet
        self["segwit"] = False
        self["txId"] = None
        self["hash"] = None
        self["version"] = version
        self["size"] = 0
        self["vSize"] = 0
        self["bSize"] = 0
        self["lockTime"] = lock_time
        self["vIn"] = dict()
        self["vOut"] = dict()
        self["rawTx"] = None
        self["blockHash"] = None
        self["confirmations"] = None
        self["time"] = None
        self["blockTime"] = None
        self["blockIndex"] = None
        self["coinbase"] = False
        self["fee"] = None
        self["data"] = None
        self["amount"] = None
        if raw_tx is None:
            return

        self["amount"] = 0
        sw = sw_len = 0
        stream = self.get_stream(raw_tx)
        start = stream.tell()
        read = stream.read
        tell = stream.tell
        seek = stream.seek
        # start deserialization
        self["version"] = unpack('<L', read(4))[0]
        n = read_var_int(stream)

        if n == b'\x00':
            # segwit format
            sw = 1
            self["flag"] = read(1)
            n = read_var_int(stream)

        # inputs
        ic = var_int_to_int(n)
        for k in range(ic):
            self["vIn"][k] = dict()
            self["vIn"][k]["txId"] = read(32)
            self["vIn"][k]["vOut"] = unpack('<L', read(4))[0]
            self["vIn"][k]["scriptSig"] = read(var_int_to_int(read_var_int(stream)))
            self["vIn"][k]["sequence"] = unpack('<L', read(4))[0]

        # outputs
        for k in range(var_int_to_int(read_var_int(stream))):
            self["vOut"][k] = dict()
            self["vOut"][k]["value"] = unpack('<Q', read(8))[0]
            self["amount"] += self["vOut"][k]["value"]
            self["vOut"][k]["scriptPubKey"] = read(var_int_to_int(read_var_int(stream)))
            s = parse_script(self["vOut"][k]["scriptPubKey"])
            self["vOut"][k]["nType"] = s["nType"]
            self["vOut"][k]["type"] = s["type"]
            if self["data"] is None:
                if s["nType"] == 3:
                    self["data"] = s["data"]
            if s["nType"] not in (3, 4, 7, 8):
                self["vOut"][k]["addressHash"] = s["addressHash"]
                self["vOut"][k]["reqSigs"] = s["reqSigs"]

        # witness
        if sw:
            sw = tell() - start
            for k in range(ic):
                self["vIn"][k]["txInWitness"] = [read(var_int_to_int(read_var_int(stream))) \
                                                 for c in range(var_int_to_int(read_var_int(stream)))]
            sw_len = (stream.tell() - start) - sw + 2

        self["lockTime"] = unpack('<L', read(4))[0]

        end = tell()
        seek(start)
        b = read(end - start)
        self["rawTx"] = b
        self["size"] = end - start
        self["bSize"] = end - start - sw_len
        self["weight"] = self["bSize"] * 3 + self["size"]
        self["vSize"] = ceil(self["weight"] / 4)
        if ic == 1 and \
                        self["vIn"][0]["txId"] == b'\x00' * 32 and \
                        self["vIn"][0]["vOut"] == 0xffffffff:
            self["coinbase"] = True
        else:
            self["coinbase"] = False
        if sw:
            self["segwit"] = True
            self["hash"] = double_sha256(b)
            self["txId"] = double_sha256(b"%s%s%s" % (b[:4], b[6:sw],b[-4:]))
        else:
            self["segwit"] = False
            self["txId"] = double_sha256(b)
            self["hash"] = self["txId"]
        if self["format"] == "decoded":
            self.decode()
示例#9
0
def test_parse_script():
    assert parse_script(b"")["type"] == "NON_STANDARD"
    assert parse_script(b"".join([OP_RETURN, b"\x00"]))["type"] == "NULL_DATA"
    assert parse_script(b"".join([OP_RETURN, b""]))["type"] == "NULL_DATA"
    assert parse_script(b"".join([
        OP_RETURN,
        b2h("20313233343536373839303132333435363738393"
            "0313233343536373839303132")
    ]))["type"] == "NULL_DATA"
    assert parse_script(b"".join([OP_RETURN,
                                  b2h("20313233343536373839303132333435363"
                                      "7383930313233343536373839303132")]))["data"].hex() == \
           "3132333435363738393031323334353637383930313233343536373839303132"
    assert parse_script(b"".join([
        OP_RETURN,
        b2h("203132333435363738393031323334353637383930"
            "3132333435363738393031323131")
    ]))["type"] == "NULL_DATA_NON_STANDARD"
    assert parse_script(b"".join([OP_RETURN, OP_PUSHDATA1,
                                  b"\x00"]))["type"] == "NULL_DATA"
    assert parse_script(b"".join([OP_RETURN, OP_PUSHDATA1,
                                  b"\x00"]))["data"] == b""
    assert parse_script(b"".join([OP_RETURN, OP_PUSHDATA1,
                                  b2h("2031323334353637383930313233343536373839303"
                                      "13233343536373839303132")]))["data"].hex() == "3132333435363738393031323334353" \
                                                                                     "637383930313233343536373839303132"
    assert parse_script(b"".join([
        OP_RETURN, OP_PUSHDATA1,
        b2h("20313233343536373839303132333435363738393031323334353637"
            "3839303132")
    ]))["type"] == "NULL_DATA"
    assert parse_script(b"".join([
        OP_RETURN, OP_PUSHDATA1,
        b2h("20313233343536373839303132333435363738393031323334353637"
            "38393031323131")
    ]))["type"] == "NULL_DATA_NON_STANDARD"
    assert parse_script(b"".join(
        [OP_RETURN, OP_PUSHDATA1,
         b"\x1412345678901234567890"]))["type"] == "NULL_DATA"
    assert parse_script(b"".join(
        [OP_RETURN, OP_PUSHDATA1,
         b"\x14123456789012345678901"]))["type"] == "NULL_DATA_NON_STANDARD"
    assert parse_script(b"".join([OP_RETURN, OP_PUSHDATA1
                                  ]))["type"] == "NULL_DATA_NON_STANDARD"

    assert parse_script(b"".join([
        OP_RETURN, OP_PUSHDATA2,
        b2h("20313233343536373839303132333435363738393031323334353637"
            "38393031323131")
    ]))["type"] == "NULL_DATA_NON_STANDARD"
    assert parse_script(b"".join([
        OP_RETURN, OP_PUSHDATA1,
        b2h("20313233343536373839303132333435363738393031323334353637"
            "383930313231313131")
    ]))["type"] == "NULL_DATA_NON_STANDARD"
    assert parse_script(b"".join([
        OP_RETURN, OP_PUSHDATA1,
        b2h("50313233343536373839303132333435363738393031323334353637383930313"
            "23334353637383930313233343536373839303132333435363738393031323334"
            "35363738393031323334353637383930")
    ]))["type"] == "NULL_DATA"
    assert parse_script(b"".join([OP_RETURN, OP_PUSHDATA1,
                                  b2h("50313233343536373839303132333435363738393031323334353637383930313"
                                      "23334353637383930313233343536373839303132333435363738393031323334"
                                      "353637383930313233343536"
                                      "37383930")]))["data"].hex() == "3132333435363738393031323334353637" \
                                                                      "3839303132333435363738393031323334" \
                                                                      "3536373839303132333435363738393031" \
                                                                      "3233343536373839303132333435363738" \
                                                                      "393031323334353637383930"
    assert parse_script(b"".join([
        OP_RETURN, OP_PUSHDATA1,
        b2h("5131323334353637383930313233343536373839303132333435363738393031323"
            "3343536373839303132333435363738393031323334353637383930313233343536"
            "373839303132333435363738"
            "393031")
    ]))["type"] == "NULL_DATA_NON_STANDARD"
    assert parse_script(b2h(
        "a914546fbecb877edbe5777bc0ce4c8be6989d8edd9387"))["type"] == "P2SH"
    assert parse_script(
        b2h("a914546fbecb877edbe5777bc0ce4c8be6989d8edd9387"))["nType"] == 1
    assert parse_script(
        b2h("a914546fbecb877edbe5777bc0c"
            "e4c8be6989d8edd9387"))["addressHash"].hex(
            ) == "546fbecb877edbe5777bc0ce4c8be6989d8edd93"
    assert parse_script(b2h(
        "a914546fbecb877edbe5777bc0ce4c8be6989d8edd9387"))["reqSigs"] == None

    assert parse_script(
        b2h("76a9143053ef41e2106fb5fea261c8ee3fd44f007b5ee688ac")
    )["type"] == "P2PKH"
    assert parse_script(
        b2h("76a9143053ef41e2106fb5fea261c8ee3fd44f007b5ee688ac")
    )["nType"] == 0
    assert parse_script(
        b2h("76a9143053ef41e2106fb5fea261c8ee3fd44f007b5ee688ac")
    )["reqSigs"] == 1
    assert parse_script(b2h("76a9143053ef41e2106fb5fea261"
                            "c8ee3fd44f007b5ee688ac"))["addressHash"].hex() == \
           "3053ef41e2106fb5fea261c8ee3fd44f007b5ee6"

    p = "410496b538e853519c726a2c91e61ec11600ae1390813a627c66fb8be7947be63c52da7589379515d4e0a604" \
        "f8141781e62294721166bf621e73a82cbf2342c858eeac"
    assert parse_script(p)["type"] == "PUBKEY"
    assert parse_script(p)["nType"] == 2
    assert parse_script(p)["reqSigs"] == 1
    assert parse_script(
        p)["addressHash"].hex() == "119b098e2e980a229e139a9ed01a469e518e6f26"

    p = b"".join([
        b"\x33",
        b2h("03295ba1e53005b622b5c959a66185fe9ad4564597c99d43d99e7824add7d755de"
            ), OP_CHECKSIG
    ])

    assert parse_script(p)["type"] == "PUBKEY"
    assert parse_script(p)["nType"] == 2
    assert parse_script(p)["reqSigs"] == 1

    p = "00142ac50173769ba101bb2a2e7b32f158eb8c77d8a4"
    assert parse_script(p)["type"] == "P2WPKH"
    assert parse_script(p)["nType"] == 5
    assert parse_script(p)["reqSigs"] == 1
    assert parse_script(
        p)["addressHash"].hex() == "2ac50173769ba101bb2a2e7b32f158eb8c77d8a4"

    p = "00142ac50173769ba101bb2a2e7b32f158eb8c77d8a4"
    assert parse_script(p, False)["type"] == "NON_STANDARD"
    assert parse_script(p, False)["nType"] == 7
    assert parse_script(p, False)["reqSigs"] == 0

    p = "0020701a8d401c84fb13e6baf169d59684e17abd9fa216c8cc5b9fc63d622ff8c58d"
    assert parse_script(b2h(p))["type"] == "P2WSH"
    assert parse_script(b2h(p))["nType"] == 6
    assert parse_script(b2h(p))["reqSigs"] is None
    assert parse_script(b2h(p))["addressHash"].hex() == "701a8d401c84fb13e6baf169d59684e17ab" \
                                                        "d9fa216c8cc5b9fc63d622ff8c58d"

    s = "512102953397b893148acec2a9da8341159e9e7fb3d32987c3563e8bdf22116213623"
    s += "441048da561da64584fb1457e906bc2840a1f963b401b632ab98761d12d74dd795bbf"
    s += "410c7b6d6fd39acf9d870cb9726578eaf8ba430bb296eac24957f3fb3395b8b042060"
    s += "466616fb675310aeb024f957b4387298dc28305bc7276bf1f7f662a6764bcdffb6a97"
    s += "40de596f89ad8000f8fa6741d65ff1338f53eb39e98179dd18c6e6be8e3953ae"
    assert parse_script(b2h(s))["type"] == "MULTISIG"
    assert parse_script(b2h(s))["nType"] == 4
    assert parse_script(b2h(s))["reqSigs"] == 1

    s = "5f210378d430274f8c5ec1321338151e9f27f4c676a008bdf8638d07c0b6be9ab35c"
    s += "71210378d430274f8c5ec1321338151e9f27f4c676a008bdf8638d07c0b6be9ab35c"
    s += "71210378d430274f8c5ec1321338151e9f27f4c676a008bdf8638d07c0b6be9ab35c"
    s += "71210378d430274f8c5ec1321338151e9f27f4c676a008bdf8638d07c0b6be9ab35c"
    s += "71210378d430274f8c5ec1321338151e9f27f4c676a008bdf8638d07c0b6be9ab35c"
    s += "71210378d430274f8c5ec1321338151e9f27f4c676a008bdf8638d07c0b6be9ab35c"
    s += "71210378d430274f8c5ec1321338151e9f27f4c676a008bdf8638d07c0b6be9ab35c"
    s += "71210378d430274f8c5ec1321338151e9f27f4c676a008bdf8638d07c0b6be9ab35c"
    s += "71210378d430274f8c5ec1321338151e9f27f4c676a008bdf8638d07c0b6be9ab35c"
    s += "71210378d430274f8c5ec1321338151e9f27f4c676a008bdf8638d07c0b6be9ab35c"
    s += "71210378d430274f8c5ec1321338151e9f27f4c676a008bdf8638d07c0b6be9ab35c"
    s += "71210378d430274f8c5ec1321338151e9f27f4c676a008bdf8638d07c0b6be9ab35c"
    s += "71210378d430274f8c5ec1321338151e9f27f4c676a008bdf8638d07c0b6be9ab35c"
    s += "71210378d430274f8c5ec1321338151e9f27f4c676a008bdf8638d07c0b6be9ab35c"
    s += "71210378d430274f8c5ec1321338151e9f27f4c676a008bdf8638d07c0b6be9ab35c"
    s += "715fae"
    assert parse_script(b2h(s))["type"] == "MULTISIG"
    assert parse_script(b2h(s))["nType"] == 4
    assert parse_script(b2h(s))["reqSigs"] == 15

    s = "0114410478d430274f8c5ec1321338151e9f27f4c676a008bdf8638d07c0b6be9ab35"
    s += "c71a1518063243acd4dfe96b66e3f2ec8013c8e072cd09b3834a19f81f659cc345541"
    s += "0478d430274f8c5ec1321338151e9f27f4c676a008bdf8638d07c0b6be9ab35c71a15"
    s += "18063243acd4dfe96b66e3f2ec8013c8e072cd09b3834a19f81f659cc3455410478d4"
    s += "30274f8c5ec1321338151e9f27f4c676a008bdf8638d07c0b6be9ab35c71a15180632"
    s += "43acd4dfe96b66e3f2ec8013c8e072cd09b3834a19f81f659cc3455410478d430274f"
    s += "8c5ec1321338151e9f27f4c676a008bdf8638d07c0b6be9ab35c71a1518063243acd4"
    s += "dfe96b66e3f2ec8013c8e072cd09b3834a19f81f659cc3455410478d430274f8c5ec1"
    s += "321338151e9f27f4c676a008bdf8638d07c0b6be9ab35c71a1518063243acd4dfe96b"
    s += "66e3f2ec8013c8e072cd09b3834a19f81f659cc3455410478d430274f8c5ec1321338"
    s += "151e9f27f4c676a008bdf8638d07c0b6be9ab35c71a1518063243acd4dfe96b66e3f2"
    s += "ec8013c8e072cd09b3834a19f81f659cc3455410478d430274f8c5ec1321338151e9f"
    s += "27f4c676a008bdf8638d07c0b6be9ab35c71a1518063243acd4dfe96b66e3f2ec8013"
    s += "c8e072cd09b3834a19f81f659cc3455410478d430274f8c5ec1321338151e9f27f4c6"
    s += "76a008bdf8638d07c0b6be9ab35c71a1518063243acd4dfe96b66e3f2ec8013c8e072"
    s += "cd09b3834a19f81f659cc3455410478d430274f8c5ec1321338151e9f27f4c676a008"
    s += "bdf8638d07c0b6be9ab35c71a1518063243acd4dfe96b66e3f2ec8013c8e072cd09b3"
    s += "834a19f81f659cc3455410478d430274f8c5ec1321338151e9f27f4c676a008bdf863"
    s += "8d07c0b6be9ab35c71a1518063243acd4dfe96b66e3f2ec8013c8e072cd09b3834a19"
    s += "f81f659cc3455410478d430274f8c5ec1321338151e9f27f4c676a008bdf8638d07c0"
    s += "b6be9ab35c71a1518063243acd4dfe96b66e3f2ec8013c8e072cd09b3834a19f81f65"
    s += "9cc3455410478d430274f8c5ec1321338151e9f27f4c676a008bdf8638d07c0b6be9a"
    s += "b35c71a1518063243acd4dfe96b66e3f2ec8013c8e072cd09b3834a19f81f659cc345"
    s += "5410478d430274f8c5ec1321338151e9f27f4c676a008bdf8638d07c0b6be9ab35c71"
    s += "a1518063243acd4dfe96b66e3f2ec8013c8e072cd09b3834a19f81f659cc345541047"
    s += "8d430274f8c5ec1321338151e9f27f4c676a008bdf8638d07c0b6be9ab35c71a15180"
    s += "63243acd4dfe96b66e3f2ec8013c8e072cd09b3834a19f81f659cc3455410478d4302"
    s += "74f8c5ec1321338151e9f27f4c676a008bdf8638d07c0b6be9ab35c71a1518063243a"
    s += "cd4dfe96b66e3f2ec8013c8e072cd09b3834a19f81f659cc3455410478d430274f8c5"
    s += "ec1321338151e9f27f4c676a008bdf8638d07c0b6be9ab35c71a1518063243acd4dfe"
    s += "96b66e3f2ec8013c8e072cd09b3834a19f81f659cc3455410478d430274f8c5ec1321"
    s += "338151e9f27f4c676a008bdf8638d07c0b6be9ab35c71a1518063243acd4dfe96b66e"
    s += "3f2ec8013c8e072cd09b3834a19f81f659cc3455410478d430274f8c5ec1321338151"
    s += "e9f27f4c676a008bdf8638d07c0b6be9ab35c71a1518063243acd4dfe96b66e3f2ec8"
    s += "013c8e072cd09b3834a19f81f659cc3455410478d430274f8c5ec1321338151e9f27f"
    s += "4c676a008bdf8638d07c0b6be9ab35c71a1518063243acd4dfe96b66e3f2ec8013c8e"
    s += "072cd09b3834a19f81f659cc3455410478d430274f8c5ec1321338151e9f27f4c676a"
    s += "008bdf8638d07c0b6be9ab35c71a1518063243acd4dfe96b66e3f2ec8013c8e072cd0"
    s += "9b3834a19f81f659cc34550114ae"

    assert parse_script(b2h(s))["type"] == "NON_STANDARD"
    assert parse_script(b2h(s))["nType"] == 7
    assert parse_script(b2h(s))["reqSigs"] == 20

    s = "512102953397b893148acec2a9da8341159e9e7fb3d32987c3563e8bdf22116213623"
    s += "441048da561da64584fb1457e906bc2840a1f963b401b632ab98761d12d74dd795bbf"
    s += "410c7b6d6fd39acf9d870cb9726578eaf8ba430bb296eac24957f3fb3395b8b042060"
    s += "466616fb675310aeb024f957b4387298dc28305bc7276bf1f7f662a6764bcdffb6a97"
    s += "40de596f89ad8000f8fa6741d65ff1338f53eb39e98179dd18c6e6be8e3953"
    assert parse_script(b2h(s))["type"] == "NON_STANDARD"

    s = "512102953397b893148acec2a9da8341159e9e7fb3d32987c3563e8bdf22116213623"
    s += "441048da561da64584fb1457e906bc2840a1f963b401b632ab98761d12d74dd795bbf"
    s += "410c7b6d6fd39acf9d870cb9726578eaf8ba430bb296eac24957f3fb3395b8b042060"
    s += "466616fb675310aeb024f957b4387298dc28305bc7276bf1f7f662a6764bcdffb6a97"
    s += "40de596f89ad8000f8fa6741d65ff1338f53eb39e98179dd18c6e6be8e39ffae"
    assert parse_script(b2h(s))["type"] == "NON_STANDARD"

    s = "522102953397b893148acec2a9da8341159e9e7fb3d32987c3563e8bdf22116213623"
    s += "441048da561da64584fb1457e906bc2840a1f963b401b632ab98761d12d74dd795bbf"
    s += "410c7b6d6fd39acf9d870cb9726578eaf8ba430bb296eac24957f3fb3395b8b042060"
    s += "466616fb675310aeb024f957b4387298dc28305bc7276bf1f7f662a6764bcdffb6a97"
    s += "40de596f89ad8000f8fa6741d65ff1338f53eb39e98179dd18c6e6be8e3951ae"
    assert parse_script(b2h(s))["type"] == "NON_STANDARD"

    s = "518102953397b893148acec2a9da8341159e9e7fb3d32987c3563e8bdf22116213623"
    s += "441048da561da64584fb1457e906bc2840a1f963b401b632ab98761d12d74dd795bbf"
    s += "410c7b6d6fd39acf9d870cb9726578eaf8ba430bb296eac24957f3fb3395b8b042060"
    s += "466616fb675310aeb024f957b4387298dc28305bc7276bf1f7f662a6764bcdffb6a97"
    s += "40de596f89ad8000f8fa6741d65ff1338f53eb39e98179dd18c6e6be8e3953ae"
    assert parse_script(b2h(s))["type"] == "NON_STANDARD"

    assert parse_script([
        OP_1,
        "3303295ba1e53005b622b5c959a66185fe9ad4564597c99d43d99e7824add7d755de",
        "3303295ba1e53005b622b5c959a66185fe9ad4564597c99d43d99e7824add7d755de",
        OP_2, OP_CHECKMULTISIGVERIFY
    ])["type"] == "NON_STANDARD"

    assert parse_script([
        OP_1, b"\x21",
        "03295ba1e53005b622b5c959a66185fe9ad4564597c99d43d99e7824add7d755de",
        b"\x21",
        "03295ba1e53005b622b5c959a66185fe9ad4564597c99d43d99e7824add7d755de",
        OP_2, OP_CHECKMULTISIGVERIFY
    ])["reqSigs"] == 1

    assert parse_script([
        OP_3, OP_1, b"\x21",
        "03295ba1e53005b622b5c959a66185fe9ad4564597c99d43d99e7824add7d755de",
        b"\x21",
        "03295ba1e53005b622b5c959a66185fe9ad4564597c99d43d99e7824add7d755de",
        OP_2, OP_CHECKMULTISIGVERIFY
    ])["reqSigs"] == 1

    assert parse_script([
        OP_3, b"\x21",
        "03295ba1e53005b622b5c959a66185fe9ad4564597c99d43d99e7824add7d755de",
        b"\x21",
        "03295ba1e53005b622b5c959a66185fe9ad4564597c99d43d99e7824add7d755de",
        OP_2, OP_CHECKMULTISIGVERIFY
    ])["reqSigs"] == 20

    assert parse_script([
        OP_1, OP_PUSHDATA1, b"\x21",
        "03295ba1e53005b622b5c959a66185fe9ad4564597c99d43d99e7824add7d755de",
        b"\x21",
        "03295ba1e53005b622b5c959a66185fe9ad4564597c99d43d99e7824add7d755de",
        OP_2, OP_CHECKMULTISIGVERIFY
    ])["reqSigs"] == 20

    assert parse_script([
        OP_1, OP_PUSHDATA2,
        pack('<H', 33),
        "03295ba1e53005b622b5c959a66185fe9ad4564597c99d43d99e7824add7d755de",
        b"\x21",
        "03295ba1e53005b622b5c959a66185fe9ad4564597c99d43d99e7824add7d755de",
        OP_2, OP_CHECKMULTISIGVERIFY
    ])["reqSigs"] == 20

    assert parse_script([OP_1, OP_PUSHDATA1])["reqSigs"] == 0
    assert parse_script([OP_1, OP_PUSHDATA2])["reqSigs"] == 0
    assert parse_script([OP_1, OP_PUSHDATA4])["reqSigs"] == 0
    assert parse_script([OP_1, OP_CHECKSIG])["reqSigs"] == 1
    assert parse_script([OP_1, OP_CHECKSIGVERIFY])["reqSigs"] == 1

    assert parse_script([OP_1, OP_0])["type"] == "NON_STANDARD"
    assert parse_script([OP_3, OP_1, OP_1])["type"] == "NON_STANDARD"
示例#10
0
    def test_parse_script(self):

        k = tools.parse_script(
            "76a9144b2832feeda5692c96c0594a6314136a998f515788ac")
        address = functions.hash_to_address(k["addressHash"],
                                            witness_version=None)
        self.assertEqual(address, "17rPqUf4Hqu6Lvpgfsavt1CzRy2GL19GD3")
        self.assertEqual(k["type"], "P2PKH")
        self.assertEqual(k["nType"], 0)
        self.assertEqual(k["reqSigs"], 1)
        self.assertEqual(functions.address_to_script(address, 1),
                         "76a9144b2832feeda5692c96c0594a6314136a998f515788ac")

        k = tools.parse_script(
            "76a914a307d67484911deee457779b17505cedd20e1fe988ac")
        address = functions.hash_to_address(k["addressHash"],
                                            testnet=True,
                                            witness_version=None)
        self.assertEqual(address, "mvNyptwisQTmwL3vN8VMaVUrA3swVCX83c")
        self.assertEqual(k["type"], "P2PKH")
        self.assertEqual(k["nType"], 0)
        self.assertEqual(k["reqSigs"], 1)
        self.assertEqual(functions.address_to_script(address, 1),
                         "76a914a307d67484911deee457779b17505cedd20e1fe988ac")

        k = tools.parse_script(
            "a914b316ac9bdd0816ecdec6773d1192c0eaf52ae66487")
        address = functions.hash_to_address(k["addressHash"],
                                            script_hash=True,
                                            witness_version=None)
        self.assertEqual(address, "3J1x3KHjgjoTjqHjrwKax2zeT8LSDkZJae")
        self.assertEqual(k["type"], "P2SH")
        self.assertEqual(k["nType"], 1)
        self.assertEqual(k["reqSigs"], None)
        self.assertEqual(functions.address_to_script(address, 1),
                         "a914b316ac9bdd0816ecdec6773d1192c0eaf52ae66487")

        k = tools.parse_script("0014751e76e8199196d454941c45d1b3a323f1433bd6")
        address = functions.hash_to_address(k["addressHash"],
                                            script_hash=False,
                                            witness_version=0,
                                            testnet=False)
        self.assertEqual(address, "bc1qw508d6qejxtdg4y5r3zarvary0c5xw7kv8f3t4")
        self.assertEqual(k["type"], "P2WPKH")
        self.assertEqual(k["nType"], 5)
        self.assertEqual(k["reqSigs"], 1)
        self.assertEqual(functions.address_to_script(address, 1),
                         "0014751e76e8199196d454941c45d1b3a323f1433bd6")

        s = [
            HEX_OPCODE['OP_HASH160'], '14',
            '92c2f2da37093971ca335824edae06468e60ea20', HEX_OPCODE['OP_EQUAL']
        ]
        h = ''.join(s)
        s = unhexlify(h)
        k = tools.parse_script(s)
        address = functions.hash_to_address(k["addressHash"],
                                            script_hash=True,
                                            witness_version=None,
                                            testnet=False)
        self.assertEqual(address, "3F527pX8o2pgr6FuNdNvngA2Do2wVvDoZi")
        self.assertEqual(k["type"], "P2SH")
        self.assertEqual(k["nType"], 1)
        self.assertEqual(k["reqSigs"], None)
        self.assertEqual(functions.address_to_script(address, 1), h)

        s = [
            HEX_OPCODE['OP_3'], '21',
            '021ecd2e5eb5dbd7c8e59f66e37da2ae95f7d61a07f4b2567c3bb10bbb1b2ec953',
            '21',
            '023bd78b0e7606fc1205721e4403355dfc0dbe4f1b15712cbbb17b1dc323cc8c0b',
            '21',
            '02afa49972b95496b39e7adc13437239ded698d81c85e9d029debb88641733528d',
            '21',
            '02b63fe474a5daac88eb74fdc9ce0ec69a8f8b81d2d89ac8d518a2f54d4bcaf4a5',
            '21',
            '02fb394aaf232e114c06b1d1ca15f97602d2377c33e6fe5a1287421b09b08a5a3e',
            '21',
            '03fedb540dd71a0211170b1857a3888d9f950231ecd0fcc7a37ffe094721ca151f',
            HEX_OPCODE['OP_6'], HEX_OPCODE['OP_CHECKMULTISIG']
        ]
        h = ''.join(s)
        s = unhexlify(h)
        k = tools.parse_script(s)
        sh = tools.script_to_hash(h, 0, 0)
        address = functions.hash_to_address(sh,
                                            script_hash=True,
                                            witness_version=None,
                                            testnet=False)
        self.assertEqual(address, "3D2oetdNuZUqQHPJmcMDDHYoqkyNVsFk9r")
        self.assertEqual(k["type"], "MULTISIG")
        self.assertEqual(k["nType"], 4)
        self.assertEqual(k["reqSigs"], 3)

        s = [
            HEX_OPCODE['OP_0'], '21',
            '021ecd2e5eb5dbd7c8e59f66e37da2ae95f7d61a07f4b2567c3bb10bbb1b2ec953',
            '21',
            '023bd78b0e7606fc1205721e4403355dfc0dbe4f1b15712cbbb17b1dc323cc8c0b',
            '21',
            '02afa49972b95496b39e7adc13437239ded698d81c85e9d029debb88641733528d',
            '21',
            '02b63fe474a5daac88eb74fdc9ce0ec69a8f8b81d2d89ac8d518a2f54d4bcaf4a5',
            '21',
            '02fb394aaf232e114c06b1d1ca15f97602d2377c33e6fe5a1287421b09b08a5a3e',
            '21',
            '03fedb540dd71a0211170b1857a3888d9f950231ecd0fcc7a37ffe094721ca151f',
            HEX_OPCODE['OP_6'], HEX_OPCODE['OP_CHECKMULTISIG']
        ]
        h = ''.join(s)
        s = unhexlify(h)
        k = tools.parse_script(s)
        sh = tools.script_to_hash(h, 0, 0)
        self.assertEqual(k["type"], "NON_STANDARD")
        self.assertEqual(k["nType"], 7)
        self.assertEqual(k["reqSigs"], 20)

        s = [
            HEX_OPCODE['OP_1'], '21',
            '021ecd2e5eb5dbd7c8e59f66e37da2ae95f7d61a07f4b2567c3bb10bbb1b2ec953',
            '21',
            '023bd78b0e7606fc1205721e4403355dfc0dbe4f1b15712cbbb17b1dc323cc8c0b',
            '21',
            '02afa49972b95496b39e7adc13437239ded698d81c85e9d029debb88641733528d',
            '21',
            '02b63fe474a5daac88eb74fdc9ce0ec69a8f8b81d2d89ac8d518a2f54d4bcaf4a5',
            '21',
            '02fb394aaf232e114c06b1d1ca15f97602d2377c33e6fe5a1287421b09b08a5a3e',
            '21',
            '03fedb540dd71a0211170b1857a3888d9f950231ecd0fcc7a37ffe094721ca151f',
            HEX_OPCODE['OP_6'], HEX_OPCODE['OP_CHECKMULTISIG']
        ]
        h = ''.join(s)
        s = unhexlify(h)
        k = tools.parse_script(s)
        self.assertEqual(k["type"], "MULTISIG")
        self.assertEqual(k["nType"], 4)
        self.assertEqual(k["reqSigs"], 1)

        s = [
            HEX_OPCODE['OP_1'], HEX_OPCODE['OP_1'], '21',
            '021ecd2e5eb5dbd7c8e59f66e37da2ae95f7d61a07f4b2567c3bb10bbb1b2ec953',
            '21',
            '023bd78b0e7606fc1205721e4403355dfc0dbe4f1b15712cbbb17b1dc323cc8c0b',
            '21',
            '02afa49972b95496b39e7adc13437239ded698d81c85e9d029debb88641733528d',
            '21',
            '02b63fe474a5daac88eb74fdc9ce0ec69a8f8b81d2d89ac8d518a2f54d4bcaf4a5',
            '21',
            '02fb394aaf232e114c06b1d1ca15f97602d2377c33e6fe5a1287421b09b08a5a3e',
            '21',
            '03fedb540dd71a0211170b1857a3888d9f950231ecd0fcc7a37ffe094721ca151f',
            HEX_OPCODE['OP_6'], HEX_OPCODE['OP_CHECKMULTISIG']
        ]
        h = ''.join(s)
        s = unhexlify(h)
        k = tools.parse_script(s)
        sh = tools.script_to_hash(h, 0, 0)
        self.assertEqual(k["type"], "NON_STANDARD")
        self.assertEqual(k["nType"], 7)
        self.assertEqual(k["reqSigs"], 1)

        s = [
            HEX_OPCODE['OP_1'], HEX_OPCODE['OP_6'], '21',
            '021ecd2e5eb5dbd7c8e59f66e37da2ae95f7d61a07f4b2567c3bb10bbb1b2ec953',
            '21',
            '023bd78b0e7606fc1205721e4403355dfc0dbe4f1b15712cbbb17b1dc323cc8c0b',
            '21',
            '02afa49972b95496b39e7adc13437239ded698d81c85e9d029debb88641733528d',
            '21',
            '02b63fe474a5daac88eb74fdc9ce0ec69a8f8b81d2d89ac8d518a2f54d4bcaf4a5',
            '21',
            '02fb394aaf232e114c06b1d1ca15f97602d2377c33e6fe5a1287421b09b08a5a3e',
            '21',
            '03fedb540dd71a0211170b1857a3888d9f950231ecd0fcc7a37ffe094721ca151f',
            HEX_OPCODE['OP_6'], HEX_OPCODE['OP_CHECKMULTISIG']
        ]
        h = ''.join(s)
        s = unhexlify(h)
        k = tools.parse_script(s)
        self.assertEqual(k["type"], "NON_STANDARD")
        self.assertEqual(k["nType"], 7)
        self.assertEqual(k["reqSigs"], 6)

        s = [
            HEX_OPCODE['OP_1'], HEX_OPCODE['OP_6'], '21',
            '021ecd2e5eb5dbd7c8e59f66e37da2ae95f7d61a07f4b2567c3bb10bbb1b2ec953',
            '21',
            '023bd78b0e7606fc1205721e4403355dfc0dbe4f1b15712cbbb17b1dc323cc8c0b',
            '21',
            '02afa49972b95496b39e7adc13437239ded698d81c85e9d029debb88641733528d',
            '21',
            '02b63fe474a5daac88eb74fdc9ce0ec69a8f8b81d2d89ac8d518a2f54d4bcaf4a5',
            '21',
            '02fb394aaf232e114c06b1d1ca15f97602d2377c33e6fe5a1287421b09b08a5a3e',
            '21',
            '03fedb540dd71a0211170b1857a3888d9f950231ecd0fcc7a37ffe094721ca151f',
            HEX_OPCODE['OP_6'], HEX_OPCODE['OP_6'],
            HEX_OPCODE['OP_CHECKMULTISIG']
        ]
        h = ''.join(s)
        s = unhexlify(h)
        k = tools.parse_script(s)
        self.assertEqual(k["type"], "NON_STANDARD")
        self.assertEqual(k["nType"], 7)
        self.assertEqual(k["reqSigs"], 20)

        s = [
            HEX_OPCODE['OP_1'], HEX_OPCODE['OP_6'], '21',
            '021ecd2e5eb5dbd7c8e59f66e37da2ae95f7d61a07f4b2567c3bb10bbb1b2ec953',
            '21',
            '023bd78b0e7606fc1205721e4403355dfc0dbe4f1b15712cbbb17b1dc323cc8c0b',
            '21',
            '02afa49972b95496b39e7adc13437239ded698d81c85e9d029debb88641733528d',
            '21',
            '02b63fe474a5daac88eb74fdc9ce0ec69a8f8b81d2d89ac8d518a2f54d4bcaf4a5',
            '21',
            '02fb394aaf232e114c06b1d1ca15f97602d2377c33e6fe5a1287421b09b08a5a3e',
            '21',
            '03fedb540dd71a0211170b1857a3888d9f950231ecd0fcc7a37ffe094721ca151f',
            HEX_OPCODE['OP_6'], HEX_OPCODE['OP_CHECKSIG'],
            HEX_OPCODE['OP_CHECKMULTISIG']
        ]
        h = ''.join(s)
        s = unhexlify(h)
        k = tools.parse_script(s)
        self.assertEqual(k["type"], "NON_STANDARD")
        self.assertEqual(k["nType"], 7)
        self.assertEqual(k["reqSigs"], 21)

        s = [
            HEX_OPCODE['OP_1'], HEX_OPCODE['OP_6'], '21',
            '021ecd2e5eb5dbd7c8e59f66e37da2ae95f7d61a07f4b2567c3bb10bbb1b2ec953',
            '21',
            '023bd78b0e7606fc1205721e4403355dfc0dbe4f1b15712cbbb17b1dc323cc8c0b',
            '21',
            '02afa49972b95496b39e7adc13437239ded698d81c85e9d029debb88641733528d',
            '21',
            '02b63fe474a5daac88eb74fdc9ce0ec69a8f8b81d2d89ac8d518a2f54d4bcaf4a5',
            '21',
            '02fb394aaf232e114c06b1d1ca15f97602d2377c33e6fe5a1287421b09b08a5a3e',
            '21',
            '03fedb540dd71a0211170b1857a3888d9f950231ecd0fcc7a37ffe094721ca151f',
            '21',
            '02fb394aaf232e114c06b1d1ca15f97602d2377c33e6fe5a1287421b09b08a5a3e',
            HEX_OPCODE['OP_6'], HEX_OPCODE['OP_CHECKMULTISIG']
        ]
        h = ''.join(s)
        s = unhexlify(h)
        k = tools.parse_script(s)
        self.assertEqual(k["type"], "NON_STANDARD")
        self.assertEqual(k["nType"], 7)
        self.assertEqual(k["reqSigs"], 20)

        s = [
            HEX_OPCODE['OP_6'], '21',
            '021ecd2e5eb5dbd7c8e59f66e37da2ae95f7d61a07f4b2567c3bb10bbb1b2ec953',
            '21',
            '023bd78b0e7606fc1205721e4403355dfc0dbe4f1b15712cbbb17b1dc323cc8c0b',
            '21',
            '02afa49972b95496b39e7adc13437239ded698d81c85e9d029debb88641733528d',
            '21',
            '02b63fe474a5daac88eb74fdc9ce0ec69a8f8b81d2d89ac8d518a2f54d4bcaf4a5',
            '21',
            '02fb394aaf232e114c06b1d1ca15f97602d2377c33e6fe5a1287421b09b08a5a3e',
            '21',
            '03fedb540dd71a0211170b1857a3888d9f950231ecd0fcc7a37ffe094721ca151f',
            '21',
            '02fb394aaf232e114c06b1d1ca15f97602d2377c33e6fe5a1287421b09b08a5a3e',
            HEX_OPCODE['OP_6'], HEX_OPCODE['OP_CHECKMULTISIG']
        ]
        h = ''.join(s)
        s = unhexlify(h)
        k = tools.parse_script(s)
        self.assertEqual(k["type"], "NON_STANDARD")
        self.assertEqual(k["nType"], 7)
        self.assertEqual(k["reqSigs"], 20)

        s = [
            HEX_OPCODE['OP_6'], '21',
            '023bd78b0e7606fc1205721e4403355dfc0dbe4f1b15712cbbb17b1dc323cc8c0b',
            '21',
            '02afa49972b95496b39e7adc13437239ded698d81c85e9d029debb88641733528d',
            '21',
            '02b63fe474a5daac88eb74fdc9ce0ec69a8f8b81d2d89ac8d518a2f54d4bcaf4a5',
            '21',
            '02fb394aaf232e114c06b1d1ca15f97602d2377c33e6fe5a1287421b09b08a5a3e',
            '21',
            '03fedb540dd71a0211170b1857a3888d9f950231ecd0fcc7a37ffe094721ca151f',
            '21',
            '02fb394aaf232e114c06b1d1ca15f97602d2377c33e6fe5a1287421b09b08a5a3e',
            HEX_OPCODE['OP_6'], HEX_OPCODE['OP_CHECKMULTISIG']
        ]
        h = ''.join(s)
        s = unhexlify(h)
        k = tools.parse_script(s)
        self.assertEqual(k["type"], "MULTISIG")
        self.assertEqual(k["nType"], 4)
        self.assertEqual(k["reqSigs"], 6)

        s = [
            HEX_OPCODE['OP_1'], '21',
            '023bd78b0e7606fc1205721e4403355dfc0dbe4f1b15712cbbb17b1dc323cc8c0b',
            '21',
            '02afa49972b95496b39e7adc13437239ded698d81c85e9d029debb88641733528d',
            '21',
            '02b63fe474a5daac88eb74fdc9ce0ec69a8f8b81d2d89ac8d518a2f54d4bcaf4a5',
            '21',
            '02fb394aaf232e114c06b1d1ca15f97602d2377c33e6fe5a1287421b09b08a5a3e',
            '21',
            '03fedb540dd71a0211170b1857a3888d9f950231ecd0fcc7a37ffe094721ca151f',
            '21',
            '02fb394aaf232e114c06b1d1ca15f97602d2377c33e6fe5a1287421b09b08a5a3e',
            HEX_OPCODE['OP_6'], HEX_OPCODE['OP_CHECKMULTISIG']
        ]
        h = ''.join(s)
        s = unhexlify(h)
        k = tools.parse_script(s)
        self.assertEqual(k["type"], "MULTISIG")
        self.assertEqual(k["nType"], 4)
        self.assertEqual(k["reqSigs"], 1)

        s = [
            HEX_OPCODE['OP_1'], '21',
            '02afa49972b95496b39e7adc13437239ded698d81c85e9d029debb88641733528d',
            '21',
            '02b63fe474a5daac88eb74fdc9ce0ec69a8f8b81d2d89ac8d518a2f54d4bcaf4a5',
            '21',
            '02fb394aaf232e114c06b1d1ca15f97602d2377c33e6fe5a1287421b09b08a5a3e',
            '21',
            '03fedb540dd71a0211170b1857a3888d9f950231ecd0fcc7a37ffe094721ca151f',
            '21',
            '02fb394aaf232e114c06b1d1ca15f97602d2377c33e6fe5a1287421b09b08a5a3e',
            HEX_OPCODE['OP_6'], HEX_OPCODE['OP_CHECKMULTISIG']
        ]
        h = ''.join(s)
        s = unhexlify(h)
        k = tools.parse_script(s)
        self.assertEqual(k["type"], "NON_STANDARD")
        self.assertEqual(k["nType"], 7)
        self.assertEqual(k["reqSigs"], 20)

        s = [
            HEX_OPCODE['OP_1'], '21',
            '023bd78b0e7606fc1205721e4403355dfc0dbe4f1b15712cbbb17b1dc323cc8c0b',
            '21',
            '02afa49972b95496b39e7adc13437239ded698d81c85e9d029debb88641733528d',
            HEX_OPCODE['OP_DUP'], '21',
            '02fb394aaf232e114c06b1d1ca15f97602d2377c33e6fe5a1287421b09b08a5a3e',
            '21',
            '03fedb540dd71a0211170b1857a3888d9f950231ecd0fcc7a37ffe094721ca151f',
            '21',
            '02fb394aaf232e114c06b1d1ca15f97602d2377c33e6fe5a1287421b09b08a5a3e',
            HEX_OPCODE['OP_6'], HEX_OPCODE['OP_CHECKMULTISIG']
        ]
        h = ''.join(s)
        s = unhexlify(h)
        k = tools.parse_script(s)
        self.assertEqual(k["type"], "NON_STANDARD")
        self.assertEqual(k["nType"], 7)
        self.assertEqual(k["reqSigs"], 20)