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()}