So automatisieren Sie die TRON-Energie-Miete mit der API

2026-05-13

Warum die Energie-Miete überhaupt automatisieren

Wenn Sie eine Hot Wallet, eine Auszahlungs-Engine einer Börse oder einen Smart Contract betreiben, der TRC-20-Überweisungen im Namen von Nutzern auslöst, kennen Sie das Problem bereits: Sie brauchen TRON-Energie in der Sekunde bereit, in der eine Transaktion gefeuert wird. Energie manuell über eine UI nachzuladen, skaliert nicht über eine Handvoll Überweisungen pro Tag hinaus. Verpassen Sie das Zeitfenster, verbrennt die Transaktion stattdessen TRX aus der sendenden Adresse, oft zu deutlich höheren Kosten als vorab gemietete Energie.

Die Lösung besteht darin, die Miet-API in dem Moment aufzurufen, in dem Ihr Backend kurz davor steht, eine Transaktion zu senden, sodass Energie programmgesteuert bereitgestellt wird, ohne dass ein Mensch eingreifen muss. Dieser Artikel zeigt genau, wie das gegen tronenergyrent.com funktioniert: das tatsächliche Anfrageformat, der asynchrone Bestellungs-Lebenszyklus, sinnvolle Abwägungen bei der Mietdauer und ein lauffähiges Python-Beispiel, das Sie direkt in Ihren Dienst einbauen können.

Was die API tatsächlich On-Chain bewirkt

Bevor Sie Code schreiben, hilft es, die On-Chain-Mechanik zu verstehen, damit Sie nicht blind debuggen müssen.

Das Ressourcenmodell von TRON trennt Berechnung (Energie) von der Transaktionsgröße (bandwidth). Eine standardmäßige USDT-TRC-20-Überweisung verbraucht etwa 65,000 Energie, wenn der Empfänger bereits USDT hält, und rund 130,000, wenn das USDT-Guthaben des Empfängers null ist. Die erste eingehende Überweisung bezahlt die Speicherkosten für das Anlegen des Guthaben-Eintrags. Deshalb hängen die Kosten ausschließlich vom Empfänger ab, nicht vom Sender. Die bandwidth-Nutzung für eine Überweisung liegt bei etwa 345 Bytes, was klein genug ist, dass die meisten Konten dies aus ihrem täglichen kostenlosen Kontingent abdecken.

Wenn Sie die Miet-API aufrufen, staked der Dienst eigene TRX und delegiert die daraus resultierende Energie an die von Ihnen angegebene Adresse, unter Verwendung von DelegateResourceContract aus Stake 2.0. Die Delegation ist adressspezifisch und zeitlich begrenzt. Sobald der Mietzeitraum abläuft, wird die Energie automatisch vom Anbieter zurückgenommen.

Ein wichtiges Detail: Die Miete ist asynchron. Der API-Aufruf gibt sofort eine orderId und einen Zustand PAID_BY_USER zurück, aber die On-Chain-Delegations-Transaktion wird im Hintergrund gesendet und landet typischerweise innerhalb weniger Sekunden. Ihre Integration sollte die initiale Antwort als Bestätigung behandeln, dass die Bestellung angenommen und bezahlt wurde, und dann den Endpunkt für die Bestelldetails abfragen, bis der Zustand auf ENERGY_DELEGATED wechselt.

Die richtige Mietdauer wählen

Die API akzeptiert einen Parameter period mit vier zulässigen Werten: 1h, 1d, 3d, 30d. Die Preise schwanken mit dem On-Chain-Energie-Markt und ändern sich im Tagesverlauf, daher stehen die aktuellen Zahlen stets auf der Preisseite. Die relative Reihenfolge ist stabil: 1h ist pro Aufruf am günstigsten, 30d ist am günstigsten, wenn man die Kosten über viele Überweisungen von derselben Adresse umrechnet.

Für ein ereignisgesteuertes System, bei dem Sie pro ausgehender Überweisung eine Miete auslösen, ist die Stufe 1h fast immer die richtige Wahl. Sie zahlen die niedrigsten absoluten Kosten und die Energie wird innerhalb von Sekunden nach der Delegation verbraucht. Die Stufen 1d und länger sind sinnvoll, wenn Sie vorhersehbare Batch-Workloads betreiben, etwa einen nächtlichen Auszahlungs-Job, und einen großen Energieblock einmal mieten möchten, statt die API dutzendfach aufzurufen.

Wenn Ihr System konstant mehr als 20-30 Überweisungen pro Stunde von derselben Adresse feuert, ist die Miete eines auf Ihr erwartetes Volumen ausgelegten 1d-Blocks sauberer als Aufrufe pro Überweisung. Die Vorabkosten steigen, aber der API-Overhead und die On-Chain-Bestätigungslatenz verschwinden aus dem Hot Path.

Authentifizierung und Anfragestruktur

Der Miet-Endpunkt liegt unter:

GET https://api.tronenergyrent.com/place-energy-order

Es ist eine einfache GET-Anfrage mit Query-Parametern. Die Authentifizierung erfolgt über den Query-Parameter apiKey, den Sie nach der Registrierung und dem Aufladen Ihres Kontos in Ihrem Dashboard generieren. Es gibt keine Header-basierte Authentifizierung und keinen JSON-Anfrageinhalt für diesen Endpunkt.

Die Parameter sind:

  • apiKey (erforderlich): Ihr API-Schlüssel aus dem Dashboard.
  • period (erforderlich): Mietdauer, einer der Werte 1h, 1d, 3d, 30d.
  • energyAmount (erforderlich): wie viel Energie delegiert werden soll. Minimum ist 15000. Für eine standardmäßige USDT-Überweisung an einen Empfänger, der bereits USDT hält, ist 65000 der sichere Wert; für eine erste Überweisung an einen neuen USDT-Inhaber verwenden Sie 130000.
  • destinationAddress (erforderlich): die TRON-Adresse (base58check, beginnt mit T), die die delegierte Energie empfängt.
  • preActivateDestinationAddress (optional, Standardwert 0): auf 1 setzen, wenn die Zieladresse noch nie TRX empfangen hat und daher On-Chain nicht aktiviert ist. Der Dienst sendet dann 1.5 TRX aus Ihrem Vorab-Guthaben, um die Adresse vor der Energie-Delegation zu aktivieren. Wenn die Adresse bereits aktiv ist, lassen Sie diesen Wert auf 0, um die zusätzlichen Kosten zu vermeiden.

Die Antwort wird stets mit HTTP-Status 200 zurückgegeben, unabhängig davon, ob die Bestellung erfolgreich war oder fehlgeschlagen ist. Verzweigen Sie auf das Feld status im JSON-Body statt auf den HTTP-Status. Ein Erfolgs-Body sieht so aus:

{
  "status": "SUCCESS",
  "errorCode": null,
  "errorDescription": null,
  "requestId": "2651eacd-2428",
  "payload": {
    "orderId": "128de799-501e-44b2-8d6f-1fa825c2deed",
    "totalPriceSun": 5662800,
    "totalPriceTrx": 5.6628,
    "state": "PAID_BY_USER"
  }
}

Ein Fehler-Body enthält status: "ERROR", einen maschinenlesbaren errorCode und eine menschenlesbare errorDescription:

{
  "status": "ERROR",
  "errorCode": "INVALID_ENERGY_AMOUNT",
  "errorDescription": "energyAmount is less than 15000",
  "requestId": "71431087-4",
  "payload": null
}

Loggen Sie immer die requestId in beiden Zweigen. Wenn Sie jemals den Support bitten müssen, eine bestimmte Miete nachzuverfolgen, ist diese ID das, wonach gesucht wird.

Der Bestellungs-Lebenszyklus

Das Feld state im Payload durchläuft eine kleine feste Sequenz:

  • PAID_BY_USER: Initialzustand, die Bestellung wurde aus Ihrem Guthaben bezahlt, aber es ist noch keine On-Chain-Aktion erfolgt.
  • WAITING_DELEGATION: Der Dienst hat die Bestellung aufgenommen und bereitet die Delegations-Transaktion vor.
  • ENERGY_DELEGATED: Die Delegations-Transaktion ist On-Chain gelandet. Die Zieladresse hält nun die gemietete Energie und kann sie für die nächste ausgehende Transaktion ausgeben.
  • ERROR_DELEGATION: Die Delegation ist aus irgendeinem Grund fehlgeschlagen. Selten, aber bei starker Netzwerkauslastung möglich.
  • CANCELLED: Die Bestellung wurde storniert und die Mittel auf Ihr Guthaben zurückerstattet.

Um den aktuellen Zustand zu prüfen, rufen Sie auf:

GET https://api.tronenergyrent.com/single-order-details?apiKey=YOUR_API_KEY&orderId=ORDER_ID

Die Antwort verwendet dieselbe Hülle aus status / errorCode / payload, mit dem aktuellen state innerhalb von payload. Fragen Sie diesen nach dem Platzieren der Bestellung alle ein bis zwei Sekunden ab und fahren Sie mit Ihrer TRC-20-Überweisung erst fort, nachdem Sie ENERGY_DELEGATED sehen. In der Praxis sind das meist ein oder zwei Abfragen.

Eine lauffähige Python-Integration

Hier ist ein minimales, aber produktionsnahes Muster. Es platziert die Miete, fragt ab, bis die Delegation On-Chain ist, und meldet einen klaren Fehler, falls etwas schiefgeht.

import logging
import time
import requests

API_BASE = "https://api.tronenergyrent.com"
API_KEY = "your_api_key_here"
ENERGY_FOR_TRANSFER = 65_000   # use 130_000 if recipient has zero USDT balance
HTTP_TIMEOUT_SECS = 10
POLL_INTERVAL_SECS = 1
POLL_TIMEOUT_SECS = 30


def place_order(destination_address: str, period: str = "1h",
                energy_amount: int = ENERGY_FOR_TRANSFER) -> dict:
    resp = requests.get(
        f"{API_BASE}/place-energy-order",
        params={
            "apiKey": API_KEY,
            "period": period,
            "energyAmount": energy_amount,
            "destinationAddress": destination_address,
            "preActivateDestinationAddress": 0,
        },
        timeout=HTTP_TIMEOUT_SECS,
    )
    resp.raise_for_status()
    body = resp.json()
    if body.get("status") != "SUCCESS":
        raise RuntimeError(
            f"place-energy-order failed: {body.get('errorCode')} "
            f"({body.get('errorDescription')}) requestId={body.get('requestId')}"
        )
    return body["payload"]


def wait_for_delegation(order_id: str) -> dict:
    deadline = time.monotonic() + POLL_TIMEOUT_SECS
    while time.monotonic() < deadline:
        resp = requests.get(
            f"{API_BASE}/single-order-details",
            params={"apiKey": API_KEY, "orderId": order_id},
            timeout=HTTP_TIMEOUT_SECS,
        )
        resp.raise_for_status()
        body = resp.json()
        if body.get("status") != "SUCCESS":
            raise RuntimeError(
                f"single-order-details failed: {body.get('errorCode')} "
                f"({body.get('errorDescription')})"
            )
        state = body["payload"]["state"]
        if state == "ENERGY_DELEGATED":
            return body["payload"]
        if state == "ERROR_DELEGATION":
            raise RuntimeError(f"Delegation failed for order {order_id}")
        if state == "CANCELLED":
            raise RuntimeError(f"Order {order_id} was cancelled")
        time.sleep(POLL_INTERVAL_SECS)
    raise TimeoutError(f"Order {order_id} did not reach ENERGY_DELEGATED in {POLL_TIMEOUT_SECS}s")


def rent_energy(destination_address: str) -> dict:
    placed = place_order(destination_address)
    logging.info(
        "Order placed: id=%s priceSun=%s priceTrx=%s",
        placed["orderId"], placed["totalPriceSun"], placed["totalPriceTrx"],
    )
    delegated = wait_for_delegation(placed["orderId"])
    logging.info("Order delegated: id=%s", delegated["orderId"])
    return delegated

Einige Punkte sind hervorzuheben. Die explizite Prüfung status == "SUCCESS" ist wichtig, weil der HTTP-Status immer 200 ist, sodass resp.raise_for_status() allein nichts über das tatsächliche Ergebnis aussagt. Die Polling-Schleife hat einen harten Timeout, damit eine festhängende Bestellung Ihre Überweisungs-Pipeline nicht unbegrenzt blockieren kann. Die Verzweigung auf state behandelt die drei terminalen Ergebnisse (ENERGY_DELEGATED, ERROR_DELEGATION, CANCELLED) explizit, statt sich auf ein generisches "nicht erfolgreich" zu verlassen.

In Ihrem Überweisungs-Workflow rufen Sie zuerst rent_energy() auf und senden dann die TRC-20-Überweisung. Die Reihenfolge der Schritte zählt: Senden Sie zuerst, verbrennt die Transaktion TRX aus dem Sender, weil die Delegation noch nicht gelandet ist.

Ihr Vorab-Guthaben dimensionieren

Die Mietkosten werden von einem Vorab-Guthaben abgezogen, das Sie in Ihrem tronenergyrent.com-Konto vorhalten. Richten Sie eine Benachrichtigung oder automatische Aufladung ein, wenn das Guthaben unter eine Schwelle fällt. Eine sinnvolle Untergrenze ist alles, was zwei Stunden Spitzenvolumen abdeckt.

Um das aktuelle Guthaben programmgesteuert abzurufen:

GET https://api.tronenergyrent.com/account-info?apiKey=YOUR_API_KEY

Der Payload enthält Ihr aktuelles Guthaben und den Kontostand. Verdrahten Sie das in Ihrem Monitoring-Stack und Sie werden um 2 Uhr morgens nie von einem leeren Guthaben überrascht. Beachten Sie, dass die minimale Aufladung Ihres tronenergyrent.com-Guthabens 10 TRX beträgt.

Fehlerbehandlung in der Praxis

Drei Fehlermodi treten in der Produktion am häufigsten auf. Die unten genannten Fehlercodes stammen aus der echten API und Sie können sicher auf sie verzweigen.

  1. INSUFFICIENT_BALANCE: Ihr Vorab-Guthaben ist zu niedrig, um die angeforderte Miete plus eine etwaige Voraktivierung abzudecken. Wiederholen Sie nicht, ein Retry behebt das Problem nicht. Fangen Sie diesen Fall gezielt ab und lösen Sie eine Benachrichtigung oder einen Auflade-Ablauf aus. Fügen Sie die requestId Ihrem Benachrichtigungs-Payload hinzu.
  2. INVALID_ADDRESS: Die destinationAddress hat die base58check-Dekodierung auf dem Server nicht bestanden. Wenn Ihr System Adressen dynamisch konstruiert, etwa aus Nutzereingaben, validieren Sie sie lokal, bevor Sie die API aufrufen. Die Python-Bibliothek tronpy stellt dafür is_address() bereit; falsche Eingaben clientseitig abzulehnen ist schneller, als auf den Round-Trip zu warten.
  3. INACTIVE_DESTINATION_ADDRESS_ERROR: Die Zieladresse wurde nie On-Chain aktiviert und Sie haben den Dienst nicht gebeten, sie zu aktivieren. Beheben Sie dies, indem Sie die Adresse entweder vorab mit einem kleinen TRX-Betrag von anderswo befüllen oder beim nächsten Aufruf preActivateDestinationAddress=1 übergeben, sodass der Dienst sie für 1.5 TRX aktiviert.

Ein subtilerer Fall: ORDER_IS_ALREADY_IN_PROGRESS kann zurückkommen, wenn mehrere Worker gleichzeitig Mieten für dasselbe Ziel platzieren. Der Fix liegt prozessseitig, nicht API-seitig. Nehmen Sie ein verteiltes Lock (Redis funktioniert gut), das mit der Zieladresse als Schlüssel arbeitet und gehalten wird, bis die Delegation abgeschlossen ist.

On-Chain verifizieren

Für die meisten Integrationen reicht das Pollen von /single-order-details bis ENERGY_DELEGATED. Wenn Sie mit Gürtel und Hosenträgern verifizieren möchten, können Sie zusätzlich den TRON-Full-Node direkt abfragen, nachdem die Delegation gelandet ist:

GET https://api.trongrid.io/v1/accounts/{destinationAddress}

Die Antwort enthält den aktuellen Ressourcenzustand der Adresse, einschließlich der von externen Adressen an sie delegierten Energie. Der genaue Feldname hängt von der aktuellen Stake-2.0-Sicht ab, also konsultieren Sie die aktuelle TRON-HTTP-API-Dokumentation, wenn Sie das verdrahten. Als weiche Prüfung, die eine Warnung loggt statt die Überweisung zu blockieren, ist dies ein nützlicher Kanarienvogel für den seltenen Fall, dass nach der Miet-API etwas schiefgeht.

Diese zusätzliche Prüfung erspart Ihnen Stunden des Debuggens an dem einen Mal, an dem die Miete in der API erfolgreich aussieht, aber On-Chain etwas anderes schiefgeht.

Mochten Sie bei TRON-Transaktionsgebuhren sparen? Prufen Sie jetzt die Energiepreise. Preis berechnen
Zuruck zum Blog