예제 #1
0
    def compare(self, transaction):
        """ Check if any exchange belongs to a transaction retrieved from the blockchain """
        for exchange in list(self.exchanges):
            block_time_diff = (exchange["time_exchange"] -
                               transaction["blocktime"]).total_seconds()
            tx_time_diff = (exchange["time_exchange"] -
                            transaction["time"]).total_seconds()
            if tx_time_diff < -10 * 60:
                break
            elif tx_time_diff < 6 * 60:
                # Note: float rounds numbers here. str used because float comparation in python not always working.
                # This is needed if exchanges are retrieved from DB and not directly from the Shapeshift API
                for output in transaction["outputs"]:
                    if str(float(exchange["amount_from"]))[:9] == str(
                            float(output["amount"]))[:9]:
                        if output["address"]:
                            exchange_details = Shapeshift_api.get_exchange(
                                output["address"])
                            if not exchange_details:
                                print("No output address for tx: " +
                                      transaction["hash"])
                            else:
                                if exchange_details["status"] == "complete" and \
                                                exchange_details["outgoingType"] == exchange["currency_to"]and \
                                                exchange_details["incomingType"] == exchange["currency_from"]and \
                                                str(float(exchange_details["incomingCoin"]))[:9] == str(float(exchange["amount_from"]))[:9]:
                                    Database_manager.update_shapeshift_exchange(
                                        exchange_details["outgoingCoin"],
                                        transaction["fee"],
                                        exchange_details["address"],
                                        exchange_details["withdraw"],
                                        transaction["hash"],
                                        exchange_details["transaction"],
                                        transaction["time"],
                                        transaction["blocktime"],
                                        self.current_block_number,
                                        exchange["id"])

                                    self.search_withdrawal_data(
                                        exchange_details, exchange)
                                    self.exchanges.remove(exchange)
                                    # break both loops
                                    return
            elif block_time_diff >= 10 * 60:
                self.exchanges.remove(exchange)
예제 #2
0
    def get_new_exchanges(self):
        """ Main method which retrieves and handles the scraped data"""
        # Request last 50 Transactions from Shapeshift
        new_exchanges = Shapeshift_api.get_exchanges_shapeshift()

        if new_exchanges:
            for new_exchange in new_exchanges:
                duplicate = False
                for exchange in list(self.all_exchanges):
                    if str(new_exchange["timestamp"]) == str(exchange["timestamp"]) and \
                                    str(new_exchange["amount"]) == str(exchange["amount"]) and \
                                    new_exchange["curIn"] == exchange["curIn"] and \
                                    new_exchange["curOut"] == exchange["curOut"]:
                        duplicate = True
                        break
                # Append if not retrieved already
                if duplicate == False:
                    self.all_exchanges.append(new_exchange)
            # Sort
            self.all_exchanges.sort(key=lambda x: x["timestamp"], reverse=True)

            for exchange in reversed(list(self.all_exchanges)):
                # Write to DB if exchange older (1 min) than the last new retrieved exchange
                if (exchange["timestamp"] + 60 <
                        new_exchanges[-1]["timestamp"]):
                    # Get dollar rate and current Shapeshift fees
                    exchange[
                        "dollarvalue_from"] = self.currency_data.get_dollarvalue(
                            exchange["curIn"])
                    exchange[
                        "dollarvalue_to"] = self.currency_data.get_dollarvalue(
                            exchange["curOut"])
                    exchange[
                        "fee_exchange"] = self.shapeshift_fee_data.get_shapeshift_fee(
                            exchange["curOut"])
                    time_exchange = datetime.datetime.utcfromtimestamp(
                        exchange["timestamp"]).strftime('%Y-%m-%d %H:%M:%S')
                    Database_manager.insert_shapeshift_exchange(
                        exchange["curIn"], exchange["curOut"],
                        exchange["amount"], time_exchange,
                        exchange["fee_exchange"], exchange["dollarvalue_from"],
                        exchange["dollarvalue_to"])
                    self.all_exchanges.remove(exchange)
                else:
                    break
예제 #3
0
    def search_withdrawal_data(self, exchange_details, exchange):
        """ Search for additional data for the withdrawal transaction (Block number, tx time, block time and fee)"""
        currency = exchange_details["outgoingType"]
        tx_hash = exchange_details["transaction"]
        exchange_id = exchange["id"]

        Tor.change_ip()
        for attempt in range(5):
            try:
                if currency == "ETH":
                    transaction = requests.get(
                        "https://api.infura.io/v1/jsonrpc/mainnet/eth_getTransactionByHash?params=%5B%22"
                        + str(tx_hash) +
                        "%22%5D&token=Wh9YuEIhi7tqseXn8550").json()["result"]
                    block = requests.get(
                        "https://api.infura.io/v1/jsonrpc/mainnet/eth_getBlockByNumber?params=%5B%22"
                        + str(transaction["blockNumber"]) +
                        "%22%2C%20true%5D&token=Wh9YuEIhi7tqseXn8550").json(
                        )["result"]
                    time_to = datetime.datetime.utcfromtimestamp(
                        int(block["timestamp"],
                            16)).strftime('%Y-%m-%d %H:%M:%S')
                    time_block_to = time_to
                    fee_to = int(transaction["gas"], 16) * (
                        int(transaction["gasPrice"], 16) / 1E+18)
                    block_nr_to = int(transaction["blockNumber"], 16)
                    Database_manager.update_shapeshift_exchange_corresponding_tx(
                        time_to, time_block_to, fee_to, block_nr_to,
                        exchange_id)
                elif currency == "BTC":
                    transaction = requests.get(
                        "https://blockchain.info/de/rawtx/" +
                        str(tx_hash)).json()

                    if not ("block_height" in transaction):
                        print(
                            "Block not confirmed yet. Couldn't get the corresponding Transaction for "
                            + str(tx_hash))
                        return

                    block_nr_to = int(transaction["block_height"])
                    time_to = datetime.datetime.utcfromtimestamp(
                        transaction["time"]).strftime('%Y-%m-%d %H:%M:%S')
                    block = requests.get(
                        "https://blockchain.info/de/block-height/" +
                        (str(block_nr_to)) +
                        "?format=json").json()["blocks"][0]
                    time_block_to = datetime.datetime.utcfromtimestamp(
                        block["time"])

                    # Calculate fee
                    input_value = 0
                    output_value = 0
                    for tx_input in transaction["inputs"]:
                        if "prev_out" in tx_input and tx_input["prev_out"][
                                "value"] != 0 and "addr" in tx_input[
                                    "prev_out"]:
                            input_value = input_value + tx_input["prev_out"][
                                "value"] / 100000000
                    for tx_output in transaction["out"]:
                        if tx_output["value"] != 0 and "addr" in tx_output:
                            output_value = output_value + tx_output[
                                "value"] / 100000000
                    fee_to = input_value - output_value
                    # Don't save if coinbase transaction
                    if input_value != 0:
                        Database_manager.update_shapeshift_exchange_corresponding_tx(
                            time_to, time_block_to, fee_to, block_nr_to,
                            exchange_id)
            except:
                print("Wait half a minute")
                time.sleep(30)
                Tor.change_ip()
            else:
                break
        else:
            traceback.print_exc()
            print("Couldn't get the corresponding Transaction for " +
                  str(currency))
예제 #4
0
def setup_db():
    """ Database Setup """
    Database_manager.create_database()
    Database_manager.initialize_db()
    Database_manager.create_table_scraper()
예제 #5
0
 def prepare(self):
     """ Retrieve all exchanges without additional data and set initial block number"""
     self.exchanges = Database_manager.get_shapeshift_exchanges_by_currency(
         self.currency)
     self.current_block_number = Currency_apis.get_last_block_number(
         self.currency) - Settings.get_scraper_offset(self.currency)