Exemple #1
0
    def get_transaction(self, txid):
        url = '{api_url}/tx/{txid}?verbose=3'.format(api_url=self.url,
                                                     txid=txid)
        try:
            LOG.info('GET %s' % url)
            r = requests.get(url)
            data = r.json()
        except Exception as ex:
            LOG.error('Unable to get transaction %s from BTC.com: %s' %
                      (txid, ex))
            return {
                'error': 'Unable to get transaction %s from BTC.com' % txid
            }

        data = data['data'] if data['data'] is not None else {}

        # todo check key names , test by setting testnet wrong on explorers
        tx = TX()
        tx.txid = txid
        tx.wtxid = data['witness_hash']
        tx.lock_time = data['lock_time']
        tx.block_height = data[
            'block_height'] if 'block_height' in data and data[
                'block_height'] != -1 else None
        tx.confirmations = data[
            'confirmations'] if 'confirmations' in data else None

        for item in data['inputs']:
            tx_input = TxInput()
            tx_input.address = item['prev_addresses'][0] if len(
                item['prev_addresses']) > 0 else None
            tx_input.value = item['prev_value']
            tx_input.txid = item['prev_tx_hash']
            tx_input.n = item['prev_position'] if item[
                'prev_position'] is not -1 else None
            tx_input.script = item['script_hex']
            tx_input.sequence = item['sequence']

            tx.inputs.append(tx_input)

        for i, item in enumerate(data['outputs']):
            tx_output = TxOutput()
            tx_output.address = item['addresses'][0] if len(
                item['addresses']) > 0 else None
            tx_output.value = item['value']
            tx_output.n = i
            tx_output.spent = False if item['spent_by_tx'] is None else True
            tx_output.script = item['script_hex']

            if item['script_hex'][:2] == '6a':
                tx_output.op_return = tx.decode_op_return(item['script_hex'])

            tx.outputs.append(tx_output)

        return {'transaction': tx.json_encodable()}
    def get_transaction(self, txid):
        url = self.url + '/tx/' + str(txid)
        try:
            LOG.info('GET %s' % url)
            r = requests.get(url)
            data = r.json()
        except Exception as ex:
            LOG.error('Unable to get transaction %s from %s: %s' %
                      (txid, self.url, ex))
            return {
                'error':
                'Unable to get transaction %s from %s' % (txid, self.url)
            }

        tx = TX()
        tx.txid = txid
        tx.block_height = data['blockheight'] if 'blockheight' in data else None
        tx.lock_time = data['locktime']

        for item in data['vin']:
            tx_input = TxInput()
            tx_input.address = item['addr'] if 'addr' in item else None
            tx_input.value = item['valueSat'] if 'valueSat' in item else 0
            tx_input.txid = item['txid'] if 'txid' in item else None
            tx_input.n = item['n'] if 'coinbase' not in item else None
            tx_input.script = item['scriptSig'][
                'hex'] if 'scriptSig' in item else None
            if 'coinbase' in item:
                tx_input.script = item['coinbase']
            tx_input.sequence = item['sequence']

            tx.inputs.append(tx_input)

        for item in data['vout']:
            tx_output = TxOutput()
            tx_output.address = item['scriptPubKey']['addresses'][
                0] if 'addresses' in item['scriptPubKey'] else None
            tx_output.value = int(float(item['value']) * 1e8)
            tx_output.n = item['n']
            tx_output.spent = True if 'spentTxId' in item and item[
                'spentTxId'] is not None else False
            tx_output.script = item['scriptPubKey']['hex']
            if item['scriptPubKey']['hex'][:2] == '6a':
                tx_output.op_return = tx.decode_op_return(
                    item['scriptPubKey']['hex'])

            tx.outputs.append(tx_output)

        tx.confirmations = data[
            'confirmations'] if 'confirmations' in data else None

        return {'transaction': tx.json_encodable()}
    def get_transaction(self, txid):
        url = '{api_url}/rawtx/{txid}'.format(api_url=self.url, txid=txid)
        try:
            LOG.info('GET %s' % url)
            r = requests.get(url)
            data = r.json()
        except Exception as ex:
            LOG.error('Unable to get tx %s from Blockchain.info: %s' %
                      (txid, ex))
            return {'error': 'Unable to get tx %s from Blockchain.info' % txid}

        tx = TX()
        tx.txid = txid
        tx.lock_time = data['lock_time']
        tx.block_height = data[
            'block_height'] if 'block_height' in data else None
        tx.confirmations = self.get_latest_block_height(
        ) - tx.block_height + 1 if tx.block_height is not None else 0

        for item in data['inputs']:
            tx_input = TxInput()
            tx_input.address = item['prev_out'][
                'addr'] if 'prev_out' in item else None
            tx_input.value = item['prev_out'][
                'value'] if 'prev_out' in item else 0
            tx_input.n = item['prev_out']['n'] if 'prev_out' in item else None
            tx_input.txid = ''  # Blockchain.info does not provide the txid of a tx input only their own tx_index, can be resolved for example via https://testnet.blockchain.info/tx-index/197277768?format=json but this would require too many http requests!!!
            tx_input.script = item['script']
            tx_input.sequence = item['sequence']

            tx.inputs.append(tx_input)

        for item in data['out']:
            tx_output = TxOutput()
            tx_output.address = item['addr'] if 'addr' in item else None
            tx_output.value = item['value']
            tx_output.n = item['n']
            tx_output.spent = item['spent']
            tx_output.script = item['script']
            if item['script'][:2] == '6a':
                tx_output.op_return = tx.decode_op_return(item['script'])

            tx.outputs.append(tx_output)

        return {'transaction': tx.json_encodable()}
    def get_transaction(self, txid):
        url = '{api_url}/get_tx/{network}/{txid}'.format(api_url=self.url,
                                                         network=self.network,
                                                         txid=txid)
        try:
            LOG.info('GET %s' % url)
            r = requests.get(url)
            data = r.json()
        except Exception as ex:
            LOG.error('Unable to get transaction %s from Chain.so: %s' %
                      (txid, ex))
            return {
                'error': 'Unable to get transaction %s from Chain.so' % txid
            }

        if 'data' not in data:
            LOG.error('Invalid response data from Chain.so: %s' % data)
            return {'error': 'Invalid response data from Chain.so: %s' % data}

        data = data['data']

        tx = TX()
        tx.txid = txid

        block_data = self.get_block_by_hash(block_hash=data['blockhash'])
        if not ('block' in block_data and 'height' in block_data['block']):
            LOG.error(
                'Unable to get block %s to get the block height from chain.so'
                % data['blockhash'])
            return {
                'error':
                'Unable to get block %s to get the block height from chain.so'
                % data['blockhash']
            }

        tx.block_height = block_data['block']['height']
        tx.confirmations = data['confirmations']

        for item in data['inputs']:
            tx_input = TxInput()
            tx_input.address = item[
                'address'] if item['address'] != 'coinbase' else None
            tx_input.value = btc2satoshis(
                btc=item['value']) if item['address'] != 'coinbase' else 0
            tx_input.n = item['from_output']['output_no'] if item[
                'from_output'] is not None else None
            tx_input.txid = item['from_output']['txid'] if item[
                'from_output'] is not None else None
            tx_input.script = item['script']
            tx_input.sequence = None  # Chain.so does not provide the sequence

            tx.inputs.append(tx_input)

        for item in data['outputs']:
            tx_output = TxOutput()
            tx_output.address = item[
                'address'] if item['address'] != 'nonstandard' else None
            tx_output.value = btc2satoshis(btc=item['value'])
            tx_output.n = item['output_no']
            tx_output.spent = None  # Chain.so does not provide information if an output has been spent already or not
            tx_output.script = item['script']
            if item['script'][:10] == 'OP_RETURN ':
                tx_output.op_return = binascii.unhexlify(tx_output.script[10:])

                # Sometimes the unhexed data is encoded in another coded than utf-8 which could cause problems when converting to json later
                try:
                    tx_output.op_return = tx_output.op_return.decode('utf-8')
                except UnicodeDecodeError:
                    try:
                        tx_output.op_return = tx_output.op_return.decode(
                            'cp1252')
                    except Exception as ex:
                        LOG.error(
                            'Unable to decode OP_RETURN data %s in utf-8 or cp1252: %s'
                            % (tx_output.op_return, ex))
                        tx_output.op_return = 'Unable to decode hex data'

            tx.outputs.append(tx_output)

        return {'transaction': tx.json_encodable()}