Transaction TRON en attente, expirée ou introuvable : ce que chaque cas veut dire pour un transfert USDT
TRON produit un bloc toutes les trois secondes : cinq minutes sur la chaîne font donc cent blocs. Un transfert USDT encore affiché en attente après cela se trouve à l'un de quatre endroits : signé mais jamais diffusé, accepté par un nœud mais pas encore dans un bloc, dans un bloc pas encore irréversible, ou définitif sur la chaîne et attendant que la plateforme réceptrice le crédite. Deux autres mots tendent à surgir en chemin : un explorateur qui ne trouve pas le hash, et un nœud qui qualifie la transaction d'expirée. Chacun a son propre remède, et l'un d'eux, appliqué trop tôt, paie deux fois le même transfert.
Chaque transaction porte sa propre échéance
L'intervalle entre blocs est une constante du protocole, 3,000 millisecondes. L'autre nombre est à l'intérieur de la transaction. Quand un portefeuille construit un transfert, il écrit un temps d'expiration dans raw_data, la partie qui est signée, et chaque nœud le vérifie. Une transaction dont l'expiration est passée est refusée, et celle dont l'expiration se situe plus d'un jour au-delà du bloc de tête du nœud l'est aussi. Le mot du nœud pour les deux est TRANSACTION_EXPIRATION_ERROR.
Une seconde paire de champs lie la transaction à un bloc récent. ref_block_bytes et ref_block_hash nomment un bloc que le réseau conserve encore, et un nœud se souvient des 65,536 derniers blocs, soit environ 54 heures de chaîne. Une référence plus ancienne, ou prise sur un réseau de test, vaut plutôt TAPOS_ERROR. L'horloge des deux démarre quand la transaction est construite.
Les quatre choses que « en attente » peut vouloir dire
Signé, jamais diffusé
Un portefeuille ou un script de paiements peut signer un transfert puis ne jamais le remettre à un nœud, après un délai dépassé ou un plantage entre la signature et l'envoi. Le transfert a pourtant un hash, car le hash se calcule à partir des octets de la transaction elle-même. C'est le SHA-256 de raw_data, et il existe avant qu'un nœud ait rien vu. Un hash dans vos journaux prouve que le transfert a été construit. Un explorateur qui répond « introuvable » à son sujet a raison : aucun nœud dont il lit les données ne détient ces octets.
Accepté par un nœud, pas encore dans un bloc
Un nœud qui prend une transaction répond aussitôt et la garde dans son pool de transactions en attente jusqu'à ce qu'un bloc la porte. L'acceptation et l'inclusion sont deux événements distincts, et nos propres statuts de commande les tiennent séparés : en mode B, où nous diffusons un transfert que le client a signé, broadcasted veut dire qu'un nœud a accepté la transaction et ne dit encore rien d'un bloc. Sur une chaîne à trois secondes, cet état est court. Un nœud peut aussi accepter une transaction qu'aucun bloc ne porte jamais, le plus souvent parce qu'elle a été éjectée de ce pool. Un tel transfert est perdu pour de bon quand son expiration passe.
Dans un bloc, pas encore irréversible
Les blocs les plus récents, en tête de la chaîne, peuvent encore être remplacés. TRON tient un second pointeur derrière la tête, le dernier bloc solidifié, qui est le plus récent que le réseau traite comme irréversible, et un nœud sert les deux. La distance entre eux est le temps pendant lequel un transfert reste dans un bloc sans être définitif. Nous avons lu les deux pointeurs une fois sur un nœud complet public, avec deux appels passés au même moment.
| Lu le 27 octobre 2026, 21:27 UTC | Numéro de bloc | Heure du bloc, UTC |
|---|---|---|
| Dernier bloc | 87,487,718 | 21:27:06 |
| Dernier bloc solidifié | 87,487,699 | 21:26:09 |
| Écart | 19 blocs | 57 secondes |
L'écart en numéros de bloc et l'écart en horodatages concordent à trois secondes par bloc. Nos éléments en mode B n'atteignent confirmed qu'après la solidification, que notre référence d'API situe à environ une minute, et la lecture va dans ce sens. Cela donne la réponse habituelle à la durée d'un transfert USDT sur TRON : un bloc toutes les trois secondes, et la finalité environ une minute plus tard. C'est une lecture unique sur un seul nœud. Nous n'avons pas mesuré comment l'écart évolue au fil d'une journée, ni les délais de nos propres commandes entre la livraison, la diffusion et le bloc.
Définitif sur la chaîne, pas encore crédité
Une plateforme d'échange ou un prestataire de paiement crédite un dépôt après un nombre de blocs qu'il fixe lui-même. Nous ne connaissons le nombre d'aucune plateforme et n'en citons aucun. Avant d'interroger la plateforme, lisez le résultat écrit à côté du transfert. Un transfert peut être dans un bloc et avoir pourtant échoué, avec les frais dépensés et aucun jeton déplacé, et tout ce qui n'est pas SUCCESS à cet endroit est un échec (ce que veut dire OUT_OF_ENERGY, et les autres façons dont un transfert USDT échoue). Un transfert réussi dans un bloc solidifié est arrivé à l'adresse du destinataire. Ce qui reste est la comptabilité de la plateforme, et son support peut la retracer à partir du hash.
Ce que veut dire expirée, et comment renvoyer
Passée son expiration, une transaction ne peut entrer dans aucun bloc. Tout nœud la refuse : rediffuser les mêmes octets signés ne récolte qu'un refus de plus. Le remède est une nouvelle transaction : reconstruisez le transfert, avec une expiration neuve et une référence à un bloc récent, et signez-le.
La reconstruction ne paie pas deux fois. Une transaction qu'aucun bloc n'a portée n'a jamais été exécutée : elle n'a déplacé aucun jeton et n'a rien brûlé, car un transfert dépense son énergie et ses TRX pendant qu'il s'exécute dans un bloc. Une fois une transaction dans un bloc, aucun nœud ne l'exécutera une seconde fois. La seule façon d'envoyer l'argent deux fois est de signer un remplacement alors que l'original peut encore arriver. Un nœud juge l'expiration par rapport à l'heure de son bloc de tête, qui peut retarder sur votre horloge : un bloc produit dans les dernières secondes avant l'échéance peut donc encore porter l'original, et un nœud ou un explorateur en retard peut ne pas encore le montrer. Le logiciel qui a construit l'original le détient et peut lire raw_data.expiration, en millisecondes depuis l'epoch. Attendez que le dernier bloc solidifié ait dépassé cet instant, ce qui, dans notre lecture, prend environ une minute de plus, puis interrogez un nœud par hash. Si le nœud ne connaît toujours pas la transaction, l'original ne peut plus arriver, et le nouveau transfert est le seul.
En attente et expiré sur une commande d'énergie
L'énergie louée ajoute une seconde horloge. Quand l'énergie d'une commande est livrée, la commande porte send_before, la location moins trois secondes : 297 secondes sur la location de cinq minutes et 3,597 sur l'heure. La fenêtre est comptée à partir de la délégation que nous avons vue confirmée, et la location sur la chaîne a démarré un bloc et un cycle d'interrogation avant cela : considérez donc les dernières secondes de la fenêtre comme déjà perdues (combien de temps dure l'énergie louée). Un transfert qui atteint un bloc après que l'énergie a quitté le portefeuille brûle les TRX de l'expéditeur au tarif du protocole de 100 sun l'unité, environ 6.5 TRX pour un transfert vers une adresse qui détient des USDT.
Ce qui se passe à la fermeture de la fenêtre dépend de qui envoie. En mode A, vous diffusez le transfert vous-même. Nous surveillons le réseau, marquons l'élément sent quand votre transfert apparaît, et envoyons le webhook order.item.sent avec son hash dans data.txid. Si aucun transfert n'est apparu à send_before, l'élément passe à expired et est facturé, parce que l'énergie a été livrée.
En mode B, vous nous remettez une transaction signée et nous la diffusons dès que l'énergie arrive (comment fonctionne le mode B). L'élément passe par broadcasting et broadcasted jusqu'à confirmed, ce dernier seulement après la solidification. Nous ne diffusons jamais après send_before : un élément que nous n'avons pas envoyé à temps se ferme en failed avec error: broadcast_window_missed, et la réservation revient en entier. La fenêtre y est aussi plafonnée par l'expiration propre de la transaction, moins une marge pour la diffusion : une transaction qui nous parvient avec peu de vie restante reçoit donc une fenêtre courte.
Le mode B vérifie aussi l'expiration à l'entrée. Quand nous recevons la transaction, il lui faut au moins 180 secondes de vie restante et pas plus de 23 heures 59 minutes. Une échéance trop lointaine revient en 400 invalid_request avec details.reason à expiration_too_far, et trop peu de vie en le même 400 avec details.index seul. Les deux réponses arrivent avant l'achat de toute énergie.
Que vérifier, dans l'ordre
- Si un nœud a jamais accepté la transaction. Le logiciel qui l'a envoyée détient la réponse du nœud, ou ne détient rien parce que la diffusion n'a jamais eu lieu. Un hash ne tranche rien à lui seul, puisqu'il existe avant toute diffusion.
- Si le hash est trouvé, sur un explorateur ou auprès d'un nœud interrogé par hash. S'il n'est pas trouvé et que l'expiration n'est pas encore atteinte, rediffusez les mêmes octets signés. Si le dernier bloc solidifié a dépassé l'expiration et que le hash reste introuvable, construisez une nouvelle transaction et signez-la.
- Le résultat à côté d'un hash trouvé.
SUCCESSveut dire que le transfert est passé. Tout autre résultat veut dire qu'il s'est exécuté et a échoué, et que les frais sont déjà dépensés. - Si son bloc est solidifié. Dans notre lecture, le bloc irréversible le plus récent retardait d'environ une minute sur la tête, si bien qu'un transfert réussi plus jeune que cela est encore en train de se régler.
- Le nombre de blocs propre à la plateforme destinataire, puis son support, avec le hash.
- Sur une commande à nous, l'élément :
sentavec sontxiden mode A,confirmeden mode B. Quand la fenêtre s'est fermée la première, le mode A montreexpiredet le mode B montrefailedavecerror: broadcast_window_missed. Unexpireden mode B veut dire qu'un nœud a refusé la transaction pour ce qu'elle est, ou que la transaction a fait un revert dans un bloc, et elle est facturée.
Regardez un élément rester à ready puis passer à expired sans rien de réel en jeu : le bac à sable a un destinataire dont le transfert ne vient jamais →