Lendo o recibo de uma transação TRON: energia usada, taxa de energia, bandwidth e o resultado
A página de uma transação num explorador de blocos mostra uma transferência de USDT como uma palavra, uma taxa e alguns números de recursos. Um nó devolve o recibo da mesma transação em gettransactioninfobyid, com um nome em cada número: energy_usage, energy_usage_total, origin_energy_usage, energy_penalty_total, energy_fee, net_usage, net_fee e result. energy_fee é o TRX queimado por energia que a conta não tinha, a 100 sun por unidade, net_fee é o TRX queimado pelos bytes, e em todo recibo deste texto o fee de nível superior é a soma dos dois. Guardamos recibos da mainnet para cada caso que vale a leitura: uma transferência com energia alugada, uma paga em TRX, chamadas em que o contrato pagou parte da energia, e transferências que pararam em OUT_OF_ENERGY ou REVERT.
Um campo ausente quer dizer zero
Um recibo omite todo campo cujo valor é zero. Uma transferência que não queimou TRX por energia não tem energy_fee, e uma cujos bytes não custaram nada não tem net_fee. Os valores, energy_fee, net_fee e o fee de nível superior, estão em sun, um milionésimo de TRX.
Uma transferência com energia alugada, uma paga em TRX
As duas transferências abaixo consumiram 130,285 unidades, o valor para um destinatário sem saldo de USDT. A primeira é nossa: em 2 de setembro de 2026 alugamos energia na JustLend DAO para uma segunda carteira e enviamos um USDT dela (quanto custou esse pedido). A segunda é de outro remetente, de 6 de outubro de 2026, sem energia na conta. Lemos a segunda na lista de transações do remetente, que escreve os mesmos campos achatados ao lado da transação, zeros incluídos, e deixa energy_penalty_total de fora.
| Campo | Energia alugada, 2 de setembro de 2026 | Sem energia, 6 de outubro de 2026 |
|---|---|---|
Resultado: receipt.result, ou contractRet na lista | SUCCESS | SUCCESS |
energy_usage | 130,285 | 0 |
energy_fee, sun | ausente | 13,028,500 |
energy_usage_total | 130,285 | 130,285 |
energy_penalty_total | 100,635 | não está na lista |
net_usage, bytes | ausente | 0 |
net_fee, sun | 345,000 | 345,000 |
fee, sun | 345,000 | 13,373,500 |
| A taxa em TRX | 0.345 TRX | 13.3735 TRX |
energy_usage_total é o que a chamada consumiu. energy_usage é a parte que quem envia pagou com energia que já tinha, de stake ou delegada, e energy_fee é o resto, comprado queimando TRX a 100 sun por unidade. Na nossa transferência os dois primeiros são iguais e o terceiro está ausente, então a delegação pagou cada unidade. O outro remetente não tinha energia, e 13,028,500 sun foram em 130,285 unidades, exatamente 100 sun cada.
As linhas de bandwidth coincidem. Nenhuma das duas contas cobriu os bytes com bandwidth próprio, então cada uma pagou 345,000 sun: 345 bytes a 1,000 sun por byte, a taxa dos parâmetros da cadeia que lemos em 2 de setembro de 2026.
Quando o contrato paga parte da energia
O implantador de um contrato pode assumir parte da energia de cada chamada a ele. O recibo então traz origin_energy_usage, a parte do implantador. Quem chama paga o resto do jeito que uma transferência é paga, primeiro com a própria energia e depois queimando. O mercado de energia da JustLend DAO fixa a parte de quem chama em um décimo (consume_user_resource_percent é 10), e em todos os 83 recibos dele na nossa amostra a parte de quem chama é igual a energy_usage mais um centésimo de energy_fee.
| Campo, 2 de setembro de 2026 | A nossa chamada de aluguel | Chamada de devolução de outro locatário |
|---|---|---|
energy_usage | 8,429 | 24 |
energy_fee, sun | ausente | 739,000 |
origin_energy_usage | 75,861 | 66,721 |
energy_usage_total | 84,290 | 74,135 |
| Parte de quem chama, total menos origem | 8,429 | 7,414 |
net_usage, bytes | 383 | ausente |
net_fee, sun | ausente | 378,000 |
fee, sun | ausente | 1,117,000 |
O segundo chamador tinha 24 unidades próprias e queimou 739,000 sun pelas outras 7,390. A nossa chamada de aluguel não tem fee, embora tenha enviado um pré-pagamento ao contrato: esse dinheiro viaja como o valor da chamada, e fee conta só o que a rede cobrou (para onde foi o pré-pagamento). Nenhum dos recibos de USDT deste texto traz um origin_energy_usage: em cada um, a energia própria de quem envia e a queima dela somam o total inteiro.
Um origin_energy_usage ausente quer dizer que o implantador não pagou nada e quem chama pagou pela chamada inteira. Esse é o caso mais caro, e se parece exatamente com um campo que ninguém preencheu. A parte do implantador sai da própria energia dele, e só enquanto resta alguma. Na mesma tarde, menos de três horas antes do nosso aluguel, a chamada de aluguel de outro locatário no mesmo mercado não trouxe origin_energy_usage e pagou sozinha todas as 52,672 unidades, 51,492 delas queimadas.
Bandwidth: net_usage contra net_fee
O bandwidth é medido em bytes da transação assinada (energia e bandwidth lado a lado). net_usage conta os bytes que uma conta cobriu com o próprio bandwidth, a cota diária de graça ou um stake de bandwidth. net_fee é o que ela pagou em TRX pelos bytes que não conseguiu cobrir. Em todo recibo que temos é um ou o outro.
O nosso pedido na JustLend mostra os dois. A chamada de aluguel acima tem net_usage 383 e nenhum net_fee: o bandwidth de graça da carteira a cobriu. A nossa própria chamada de devolução, da mesma carteira 144 segundos depois e fora da tabela acima, não tem net_usage e tem um net_fee de 378,000 sun. A cota de graça é de 600 por dia pelo getFreeNetLimit da cadeia, e o que o aluguel deixou dela não cobriu a devolução. Dos 83 recibos da JustLend na nossa amostra, 29 pagaram pelos seus bytes, cada um a 1,000 sun por byte.
O que a palavra de resultado decide
A palavra aparece duas vezes num recibo. Um recibo que falhou traz um result de nível superior FAILED seja qual for o problema, com um resMessage em hexadecimal. A causa está um nível abaixo, em receipt.result: SUCCESS, OUT_OF_ENERGY ou REVERT. Um recibo bem-sucedido não tem result de nível superior nenhum, então um script que lê só o campo de fora arquiva toda falha sob um nome só.
Três registros de uma carteira em 6 de outubro de 2026 mostram como OUT_OF_ENERGY acontece. São uma transferência assinada três vezes, lidos da lista de transações porque o fee_limit pertence à transação assinada. A terceira é a transferência paga em TRX da primeira tabela.
| 6 de outubro de 2026 | 15:49 UTC | 16:24 UTC | 16:26 UTC |
|---|---|---|---|
fee_limit, sun | 1,100,000 | não definido | 13,046,000 |
Resultado, contractRet | OUT_OF_ENERGY | OUT_OF_ENERGY | SUCCESS |
energy_usage_total | 11,000 | 0 | 130,285 |
energy_fee, sun | 1,100,000 | 0 | 13,028,500 |
net_usage, bytes | 344 | 0 | 0 |
net_fee, sun | 0 | 339,000 | 345,000 |
| A taxa em TRX | 1.1 TRX | 0.339 TRX | 13.3735 TRX |
A primeira tentativa parou em exatamente 11,000 unidades, o seu fee_limit dividido por 100 sun: um nó limita a energia de uma chamada a fee_limit sobre o preço da energia, tenha a conta o que tiver. A segunda não levava fee_limit, que conta como zero, então não podia gastar energia nenhuma. O recibo dela não tem campos de energia, e o resMessage dela se decodifica em “Not enough energy for 'PUSH1' operation executing: curInvokeEnergyLimit[0], …”. Três minutos depois, a mesma conta pagou a terceira tentativa, então não estava vazia. A energia delegada cai sob o mesmo limite, e é por isso que a nossa API recusa uma transferência do mode B assinada sem fee_limit suficiente, com fee_limit_too_low, antes de comprarmos qualquer energia.
Duas outras transferências de USDT dos mesmos poucos minutos mostram as duas palavras de falha, cada uma FAILED no nível superior.
| Campo, 6 de outubro de 2026 | Ficou sem energia | Recusada pelo contrato |
|---|---|---|
receipt.result | OUT_OF_ENERGY | REVERT |
energy_usage | 44,165 | 8,624 |
energy_fee, sun | 1,383,400 | ausente |
energy_usage_total | 57,999 | 8,624 |
energy_penalty_total | 25,905 | 6,640 |
net_fee, sun | 345,000 | 345,000 |
| A taxa em TRX | 1.7284 TRX | 0.345 TRX |
O primeiro remetente tinha 44,165 unidades próprias, queimou TRX por mais 13,834 e ficou sem energia em 57,999, tudo o que a energia e o TRX dele juntos podiam comprar. O fee_limit assinado dele permitia 350,000 unidades, então desta vez a conta é que foi o limite. Na segunda, o contrato recusou a transferência: o resMessage diz “REVERT opcode executed”, e o USDT não dá motivo quando reverte. A nossa referência da API dá duas causas: um remetente que não tem mais o valor, e um congelado pelo emissor do token (as falhas que as mesas de pagamento encontram).
Só um recibo SUCCESS registra tokens se movendo: o log dele guarda o evento Transfer do token, como o da nossa transferência alugada. Os recibos OUT_OF_ENERGY e REVERT não trazem log, porque nenhum token se moveu. A taxa deles é gasta do mesmo jeito, já que tudo o que a chamada consumiu antes de parar fica pago (por que o TRX se foi depois de OUT_OF_ENERGY).
Quando transmitimos a transferência assinada de um cliente no mode B, o recibo também decide quem paga a energia. Um recibo OUT_OF_ENERGY que gastou menos que a exigência da transferência, 64,285 unidades para um endereço com USDT ou 130,285 para um sem, quer dizer que a nossa energia não estava no endereço quando a chamada rodou. O item fecha como expired e cobramos por ele, a menos que os nossos registros mostrem que o vendedor retomou a delegação antes do bloco da transferência, ou que outra transferência sua do mesmo endereço gastou essa energia. Então a falta é nossa, como é quando um recibo gastou pelo menos a exigência e mesmo assim ficou sem energia porque a nossa estimativa foi curta: o item fecha como failed e devolvemos a reserva. Um recibo que temos consumiu 108,047 unidades e mesmo assim parou: numa transferência que tínhamos dimensionado para um destinatário com USDT, essa falta seria nossa. Cobramos também por um REVERT.
A penalidade faz parte do total
Na nossa transferência alugada o total é 130,285 unidades, a carteira tirou exatamente 130,285 da sua delegação, e 100,635 dessas unidades levam o rótulo de penalidade. As transferências que falharam concordam: a energia da conta mais a energia queimada dá o total, penalidade incluída.
Os valores que temos são 100,635 numa transferência concluída para um endereço sem USDT, 25,905 em duas transferências que ficaram sem energia e 6,640 na que o contrato recusou. Um dry-run de nó de uma transferência informa um energy_penalty correspondente: 100,635 ao lado de 130,285 para um destinatário sem USDT, e 49,635 ao lado de 64,285 para um que tem algum. Os parâmetros da cadeia que lemos em 2 de setembro de 2026 têm a energia dinâmica ligada (getAllowDynamicEnergy é 1), e o nome combina com uma penalidade que cresce com o destinatário mais caro. Não conferimos a aritmética do nó contra esses parâmetros, então o que a penalidade cobra continua sem medição aqui.
Conferindo um aluguel contra o recibo dele
Depois de alugar energia, dois campos do recibo da transferência dizem se o aluguel cumpriu o papel: energy_fee está ausente, e energy_usage, mais qualquer origin_energy_usage, é igual a energy_usage_total. Um energy_fee numa transferência para a qual você alugou significa que parte da energia dela foi comprada com TRX, afinal. A delegação era menor que a chamada, não tinha chegado quando a chamada rodou, já tinha sido retomada, ou foi gasta antes por outra transferência da mesma carteira (como uma delegação começa e termina). A própria conta pode ser lida antes de enviar (como alugar energia com segurança).
Entregue-nos a transferência assinada no mode B e o recibo passa a ser nosso para ler, item por item: todos os motivos com que um item pode fechar, na referência da API →