def gettransaction(self, tx_id): res = self.compose_request('dashboards/transaction/', data=tx_id) tx = res['data'][tx_id]['transaction'] confirmations = 0 if tx['block_id'] <= 0 else res['context']['state'] - tx['block_id'] status = 'unconfirmed' if confirmations: status = 'confirmed' witness_type = 'legacy' if tx['has_witness']: witness_type = 'segwit' input_total = tx['input_total'] t = Transaction(locktime=tx['lock_time'], version=tx['version'], network=self.network, fee=tx['fee'], size=tx['size'], hash=tx['hash'], date=None if not confirmations else datetime.strptime(tx['time'], "%Y-%m-%d %H:%M:%S"), confirmations=confirmations, block_height=tx['block_id'] if tx['block_id'] > 0 else None, status=status, input_total=input_total, coinbase=tx['is_coinbase'], output_total=tx['output_total'], witness_type=witness_type) index_n = 0 if not res['data'][tx_id]['inputs']: # This is a coinbase transaction, add input t.add_input(prev_hash=b'\00' * 32, output_n=0, value=0) for ti in res['data'][tx_id]['inputs']: if ti['spending_witness']: witnesses = b"".join([varstr(to_bytes(x)) for x in ti['spending_witness'].split(",")]) address = Address.import_address(ti['recipient']) if address.script_type == 'p2sh': witness_type = 'p2sh-segwit' else: witness_type = 'segwit' t.add_input(prev_hash=ti['transaction_hash'], output_n=ti['index'], unlocking_script=witnesses, index_n=index_n, value=ti['value'], address=address, witness_type=witness_type) else: t.add_input(prev_hash=ti['transaction_hash'], output_n=ti['index'], unlocking_script=ti['spending_signature_hex'], index_n=index_n, value=ti['value'], address=ti['recipient'], unlocking_script_unsigned=ti['script_hex']) index_n += 1 for to in res['data'][tx_id]['outputs']: try: deserialize_address(to['recipient'], network=self.network.name) addr = to['recipient'] except EncodingError: addr = '' t.add_output(value=to['value'], address=addr, lock_script=to['script_hex'], spent=to['is_spent'], output_n=to['index'], spending_txid=to['spending_transaction_hash'], spending_index_n=to['spending_index']) return t
def _parse_transaction(self, tx): status = 'unconfirmed' if tx['confirmations']: status = 'confirmed' witness_type = 'legacy' if 'inputs' in tx and [ti['witness'] for ti in tx['inputs'] if ti['witness'] and ti['witness'] != ['NULL']]: witness_type = 'segwit' input_total = tx['input_amount_int'] t_time = None if tx['time']: t_time = datetime.utcfromtimestamp(tx['time']) if tx['coinbase']: input_total = tx['output_amount_int'] t = Transaction(locktime=tx['locktime'], version=int(tx['version']), network=self.network, fee=tx['fee_int'], size=tx['size'], hash=tx['txid'], date=t_time, confirmations=tx['confirmations'], block_height=tx['block'], status=status, input_total=input_total, coinbase=tx['coinbase'], output_total=tx['output_amount_int'], witness_type=witness_type) index_n = 0 if tx['coinbase']: t.add_input(prev_hash=b'\00' * 32, output_n=0, value=input_total) else: for ti in tx['inputs']: unlocking_script = ti['script_sig']['hex'] witness_type = 'legacy' if ti['witness'] and ti['witness'] != ['NULL']: address = Address.import_address(ti['addresses'][0]) if address.script_type == 'p2sh': witness_type = 'p2sh-segwit' else: witness_type = 'segwit' unlocking_script = b"".join([varstr(to_bytes(x)) for x in ti['witness']]) t.add_input(prev_hash=ti['txid'], output_n=ti['vout'], unlocking_script=unlocking_script, index_n=index_n, value=ti['value_int'], address=ti['addresses'][0], sequence=ti['sequence'], witness_type=witness_type) index_n += 1 for to in tx['outputs']: spent = False spending_txid = None if 'spend_txid' in to and to['spend_txid']: spent = True spending_txid = to['spend_txid'] address = '' if to['addresses']: address = to['addresses'][0] t.add_output(value=to['value_int'], address=address, lock_script=to['script_pub_key']['hex'], spent=spent, output_n=to['n'], spending_txid=spending_txid) return t
def test_varstr(self): self.assertEqual(b'\x1eThis string has a length of 30', varstr('This string has a length of 30'))