def _is_valid_claim(self, claim, tx):
     """
     TODO: must be the first update (for the claim) in tx if there is more than one
     """
     if type(claim) == deserialize.ClaimUpdate:
         claim_id = deserialize.claim_id_bytes_to_hex(claim.claim_id)
         claim_name = self.get_claim_name(claim_id)
         # claim is invalid if its name does not match
         # what its updating
         if claim_name != claim.name:
             logger.warn('found invalid update, name mismatch,{}/{}'.format(
                 claim_name, claim.name))
             return False
         # claim is invalid if it does not spend the claim it
         # is updating
         for i in tx.get('inputs'):
             txid = i['prevout_hash']
             nout = i['prevout_n']
             logger.warn(
                 "txid:{}, nout:{}, claim id:{}, claim id from outpoint:{}".
                 format(txid, nout, claim_id,
                        self.get_claim_id_from_outpoint(txid, nout)))
             if claim_id == self.get_claim_id_from_outpoint(txid, nout):
                 return True
         logger.warn(
             "found invalid update, claim not found: {} for {}".format(
                 claim_id, claim.name))
         return False
     else:
         return True
    def _analyze_tx(self, txid, tx):
        """ analyze transaction to get list of abandons and claims """
        #dict of abandons where key = claim_id , value = {'txid', 'nout',}
        abandons = dict()
        #list of claims : [{'claim': , 'nout':, 'claim_id', 'claim_address': 'amount':}, ]
        list_claims = []
        for x in tx.get('inputs'):
            claim_id = self.get_claim_id_from_outpoint(x['prevout_hash'],
                                                       x['prevout_n'])
            if claim_id:
                abandons[claim_id] = {
                    'txid': x['prevout_hash'],
                    'nout': x['prevout_n']
                }
        for x in tx.get('outputs'):
            script = x.get('raw_output_script').decode('hex')
            nout = x.get('index')
            amount = x.get('value')
            decoded_script = [s for s in deserialize.script_GetOp(script)]
            out = deserialize.decode_claim_script(decoded_script)
            if out is False:
                continue
            claim, claim_script = out
            claim_address = deserialize.get_address_from_output_script(script)
            if not self._is_valid_claim(claim, tx):
                continue
            if type(claim) in [
                    deserialize.NameClaim, deserialize.ClaimSupport
            ]:
                claim_id = self._get_claim_id(txid, nout)
            else:  #ClaimUpdate
                claim_id = deserialize.claim_id_bytes_to_hex(claim.claim_id)
                del abandons[claim_id]

            claim_info = {
                'claim': claim,
                'nout': nout,
                'claim_id': claim_id,
                'claim_address': claim_address,
                'amount': amount
            }
            list_claims.append(claim_info)

        return {
            'abandons': abandons,
            'claims': list_claims,
        }
 def _get_claim_id(self, txid, nout):
     """ get claim id in hex from txid in hex and nout int """
     claim_id = deserialize.claim_id_hash(
         deserialize.rev_hex(txid).decode('hex'), nout)
     claim_id = deserialize.claim_id_bytes_to_hex(claim_id)
     return claim_id