import os from flask import Flask, jsonify, request from bitcoinlib.services.bitcoind import BitcoindClient from dotenv import load_dotenv # Lade die Variablen aus der .env-Datei in die Umgebung load_dotenv() app = Flask(__name__) # --- ZUGANGSDATEN AUS UMGEBUNGSVARIABLEN LADEN --- # os.getenv sucht nach dem Namen und liest den Wert aus RPC_USER = os.getenv('RPC_USER') RPC_PASS = os.getenv('RPC_PASS') # Da das Skript IN der Windows-VM läuft, ist der Node lokal erreichbar: IP_ADRESSE = '192.168.178.225' # Sicherheits-Check: Falls die .env fehlt oder leer ist, bricht das Skript ab if not RPC_USER or not RPC_PASS: raise ValueError("Fehler: RPC_USER oder RPC_PASS wurden nicht in der Umgebung gefunden!") rpc_url = f'http://{RPC_USER}:{RPC_PASS}@{IP_ADRESSE}:8332' def get_node(): return BitcoindClient(network='bitcoin', base_url=rpc_url).proxy # ========================================== # ENDPUNKT 1: Aktuelle Blockhöhe abfragen # ========================================== @app.route('/api/blockhoehe', methods=['GET']) def get_blockhoehe(): try: node = get_node() info = node.getblockchaininfo() return jsonify({ 'status': 'success', 'blockhoehe': info['blocks'], 'sync_fortschritt_prozent': round(info.get('verificationprogress', 0) * 100, 2) }) except Exception as e: return jsonify({'status': 'error', 'message': str(e)}), 500 # ========================================== # ENDPUNKT 2: Bestimmten Block abfragen # ========================================== @app.route('/api/block/', methods=['GET']) def get_block(hoehe): try: node = get_node() block_hash = node.getblockhash(hoehe) block_daten = node.getblock(block_hash, 2) return jsonify({'status': 'success', 'block': block_daten}) except Exception as e: return jsonify({'status': 'error', 'message': str(e)}), 500 # ========================================== # ENDPUNKT 3: Einzelne Transaktion abfragen # ========================================== @app.route('/api/tx/', methods=['GET']) def get_tx(txid): try: node = get_node() tx_daten = node.getrawtransaction(txid, True) return jsonify({'status': 'success', 'transaction': tx_daten}) except Exception as e: return jsonify({'status': 'error', 'message': str(e)}), 500 # ========================================== # ENDPUNKT 4: Guthaben einer beliebigen Adresse # ========================================== @app.route('/api/guthaben/', methods=['GET']) def get_guthaben(adresse): try: node = get_node() scan_result = node.scantxoutset("start", [f"addr({adresse})"]) return jsonify({ 'status': 'success', 'adresse': adresse, 'guthaben_btc': scan_result.get('total_amount', 0), 'anzahl_utxos': len(scan_result.get('unspents', [])), # NEU: Wir schicken die komplette Liste der Münzen mit! 'utxos': scan_result.get('unspents', []) }) except Exception as e: return jsonify({'status': 'error', 'message': str(e)}), 500 # ========================================== # NEU: ENDPUNKT 5: Transaktion senden (POST) # ========================================== @app.route('/api/sendtx', methods=['POST']) def send_tx(): try: # Wir erwarten ein JSON-Body mit dem Inhalt: {"hex": "01000000..."} daten = request.get_json() if not daten or 'hex' not in daten: return jsonify({'status': 'error', 'message': 'Kein gueltiger Hex-String uebergeben. Sende ein JSON mit dem Key "hex".'}), 400 raw_tx_hex = daten['hex'] node = get_node() # Sende die Transaktion an den Node, der sie ins Netzwerk broadcastet txid = node.sendrawtransaction(raw_tx_hex) return jsonify({ 'status': 'success', 'message': 'Transaktion erfolgreich an das Netzwerk uebermittelt!', 'txid': txid }) except Exception as e: return jsonify({'status': 'error', 'message': str(e)}), 500 # ========================================== # Server starten # ========================================== if __name__ == '__main__': print("🚀 API Server startet...") # host='0.0.0.0' bedeutet, dass die API von anderen Geräten im Heimnetzwerk erreichbar ist! app.run(host='0.0.0.0', port=5001)