def get_contract(self, node_to_ask, contract_id):
        """
        Will query the given node to fetch a contract given its hash.
        If the returned contract doesn't have the same hash, it will return None.

        After acquiring the contract it will download all the associated images if it
        does not already have them in cache.

        Args:
            node_to_ask: a `dht.node.Node` object containing an ip and port
            contract_id: a 20 byte hash in raw byte format
        """

        def get_result(result):
            try:
                if result[0]:
                    contract = json.loads(result[1][0], object_pairs_hook=OrderedDict)
                    id_in_contract = contract["vendor_offer"]["listing"]["contract_id"]

                    if id_in_contract != contract_id.encode("hex"):
                        raise Exception("Contract ID doesn't match")

                    # TODO: verify the guid in the contract matches this node's guid
                    signature = contract["vendor_offer"]["signatures"]["guid"]
                    verify_obj = json.dumps(contract["vendor_offer"]["listing"], indent=4)

                    verify_key = nacl.signing.VerifyKey(node_to_ask.pubkey)
                    verify_key.verify(verify_obj, base64.b64decode(signature))

                    bitcoin_key = contract["vendor_offer"]["listing"]["id"]["pubkeys"]["bitcoin"]
                    bitcoin_sig = contract["vendor_offer"]["signatures"]["bitcoin"]
                    valid = bitcointools.ecdsa_raw_verify(verify_obj, bitcointools.decode_sig(bitcoin_sig),
                                                          bitcoin_key)
                    if not valid:
                        raise Exception("Invalid Bitcoin signature")

                    if "moderators" in contract["vendor_offer"]["listing"]:
                        for moderator in contract["vendor_offer"]["listing"]["moderators"]:
                            guid = moderator["guid"]
                            guid_key = moderator["pubkeys"]["guid"]
                            bitcoin_key = moderator["pubkeys"]["bitcoin"]["key"]
                            bitcoin_sig = base64.b64decode(moderator["pubkeys"]["bitcoin"]["signature"])
                            h = nacl.hash.sha512(unhexlify(guid_key))
                            pow_hash = h[40:]
                            if int(pow_hash[:6], 16) >= 50 or guid != h[:40]:
                                raise Exception('Invalid GUID')
                            verify_key = nacl.signing.VerifyKey(guid_key, encoder=nacl.encoding.HexEncoder)
                            verify_key.verify(unhexlify(bitcoin_key), bitcoin_sig)
                            #TODO: should probably also validate the handle here.
                    self.cache(result[1][0], id_in_contract)
                    if "image_hashes" in contract["vendor_offer"]["listing"]["item"]:
                        for image_hash in contract["vendor_offer"]["listing"]["item"]["image_hashes"]:
                            self.get_image(node_to_ask, unhexlify(image_hash))
                    return contract
                else:
                    self.log.warning("Fetched an invalid contract from %s" % node_to_ask.id.encode("hex"))
                    return None
            except Exception:
                return None

        if node_to_ask.ip is None:
            return defer.succeed(None)
        self.log.info("fetching contract %s from %s" % (contract_id.encode("hex"), node_to_ask))
        d = self.protocol.callGetContract(node_to_ask, contract_id)
        return d.addCallback(get_result)
dataset/ETHPy150Open OpenBazaar/OpenBazaar-Server/market/network.py/Server.get_contract/original