TRON API Precision: 4 Critical int64 Reading Checks

Written by

in

TRON API precision depends on how a numeric field reaches and passes through a client. An integer can be exact on the chain yet be rounded after a JavaScript client parses it as a Number. A decimal string can preserve the digits for read-only computation, but changing the type after rounding cannot recover a lost digit.

This guide compares two ordinary reads of one real Mainnet receipt, then separates those observations from fifteen local cases. We used TronWeb 6.5.1 and Node v24.19.0 on November 2, 2026. No key, wallet connection, transaction building or broadcast was used. The actual receipt values were within the safe-integer range; we do not claim that they suffered precision loss.

Original TRON API precision comparison showing equal safe receipt values returned as Numbers and raw int64 strings
Original Tronscan News precision worksheet, checked November 2, 2026. Real safe values and synthetic large-number tests are labelled separately.

Four checks for API number precision

  1. Field meaning: identify whether the value is a fee, block number, timestamp, token quantity or another field.
  2. Returned type: record whether the client receives a number, decimal string or hexadecimal encoding.
  3. Parsing boundary: preserve the original representation before a lossy conversion.
  4. Use boundary: keep a read-only result separate from transaction construction and submission.

These checks solve a different task from selecting token decimals. An exact integer can still be divided by the wrong scale, and a correctly selected scale does not repair an integer that has already been rounded. Keep representation precision and asset units as two columns in your evidence note.

What trx.raw promises, and what we actually tested

The official trx.raw reference describes read methods that request string encoding for protobuf int64 and uint64 fields using int64_as_string. It documents node-version and method-coverage limitations, and explicitly restricts these responses to reading, display and off-chain computation. Not every numeric field or every method changes type.

Our test did not determine the provider’s binary version or inspect every SDK method. We compared getTransactionInfo for one fixed historical hash through the ordinary and raw namespaces. This is a direct observation of three returned fields in a named client version, rather than a blanket compatibility certificate.

The checked identifier was the public historical hash shown in the example below. Its receipt reported block 87161427 and a successful result. We selected an immutable record so two sequential reads would refer to the same transaction, rather than compare changing latest balances. The query did not create or re-execute that transaction.

Actual comparison: all three values agreed

Field Ordinary client result Raw client result Precision conclusion
fee 1697800 / number 1697800 / string Exact agreement for this safe value
blockNumber 87161427 / number 87161427 / string Exact agreement for this safe value
blockTimeStamp 1792157241000 / number 1792157241000 / string Exact agreement for this safe value

The ordinary fee was the number 1697800, while the raw fee was the string 1697800. The block number and block timestamp showed the same number-versus-string distinction. Exact comparison with BigInt agreed for all three. This positive case establishes a type difference without inventing an actual large-balance failure.

The fee’s unit remains a separate question from its JavaScript type. A string does not mean a dollar amount, a token quantity or an already formatted TRX value. Likewise, the block timestamp remains a timestamp after its representation changes. Record the field name with the value so a downstream table does not silently relabel it.

Reproduce the bounded read-only comparison

With Node and TronWeb 6.5.1 installed, the following example reads the same public receipt and prints the selected types and values. It has no private key, signer, transaction builder or send method. We ran its two named SDK reads in our saved test; availability and provider limits can change after this observation.

const { TronWeb } = require('tronweb');
const tronWeb = new TronWeb({ fullHost: 'https://api.trongrid.io' });
const txID = '0cb7d79bd0511ed98b061edb586bf36a868cb510158071ca6fbe3dc56ff86f93';
(async () => {
  const normal = await tronWeb.trx.getTransactionInfo(txID);
  const raw = await tronWeb.trx.raw.getTransactionInfo(txID);
  for (const field of ['fee', 'blockNumber', 'blockTimeStamp']) {
    console.log(field, typeof normal[field], normal[field],
      typeof raw[field], raw[field]);
  }
})().catch(error => console.error(error.message));

If a provider rejects or limits the request, preserve that response and follow its normal access policy. Do not keep retrying an unchanged failure or infer that the historical transaction disappeared. One unavailable result is not a value of zero, and a successful result from another host would be a separate observation.

The synthetic precision-loss case

The JavaScript safe-integer reference defines the maximum safe integer as 2^53 minus 1, or 9007199254740991. We tested a deliberately larger local value, 9007199254740993. It was not a balance, fee or quantity retrieved from TRON.

Parsing that value as an unquoted JSON numeric token in Node produced 9007199254740992. Preserving it as a quoted decimal string retained 9007199254740993. The one-unit difference demonstrates a representation problem in a controlled fixture; it does not establish its frequency in blockchain applications.

const rounded = JSON.parse('{"n":9007199254740993}').n;
const preserved = JSON.parse('{"n":"9007199254740993"}').n;
console.log(String(rounded));        // 9007199254740992
console.log(BigInt(rounded).toString()); // still 9007199254740992
console.log(BigInt(preserved).toString()); // 9007199254740993

We ran those exact three comparisons locally. Converting the rounded Number to BigInt kept the rounded integer. It did not infer the original digit. The useful repair point is before that loss: preserve an exact source representation or obtain an appropriately encoded new read. Reformatting the already rounded number is insufficient.

Original TRON API precision fixture showing a synthetic large JSON number rounding while a decimal string remains exact
Original Tronscan News precision worksheet, checked November 2, 2026. Real safe values and synthetic large-number tests are labelled separately.

An exact non-negative reader with a narrow contract

The helper below accepts a canonical non-negative decimal string or a non-negative safe integer and returns a BigInt. It deliberately rejects unsafe Number values. It does not know the schema range of every field, select an asset’s decimals, convert hexadecimal event data or validate a transaction.

function readExactNonnegative(value){
  if(typeof value==='string' && /^(0|[1-9][0-9]*)$/.test(value))return BigInt(value);
  if(typeof value==='number' && Number.isSafeInteger(value) && value>=0)return BigInt(value);
  throw new Error('Need a canonical decimal string or a non-negative safe integer');
}
module.exports={readExactNonnegative};

Its accepted fixtures covered the large exact decimal string, a safe integer, zero and the actual raw fee from our receipt. Rejected fixtures covered an unsafe Number, fraction, Boolean, negative number, exponent-form string, leading-zero string, null and an empty string. Three additional parsing/conversion fixtures produced the precision results above, for fifteen total checks. All passed.

Rejecting a leading-zero string is a policy of this small canonical-input helper, not a statement that every API prohibits that spelling. Similarly, allowing a non-negative string does not prove it fits an int64 field’s allowed range. Validate the specific schema separately instead of treating this utility as a universal number decoder.

The BigInt reference describes integer arithmetic and its integration boundaries. If you serialize our result into a JSON report, explicitly use a decimal string for that field. Do not add a global serializer workaround or silently cast the result back to Number just to make a downstream library accept it.

Raw does not mean suitable for signing

The SDK documentation warns that raw-read blocks and transactions must not flow into local transaction building or transaction-consuming node endpoints. We respected that boundary: both our live reads and local helper were used only for inspection. We did not test the behavior of signing or broadcasting with altered numeric types.

Nor does trx.raw mean the raw_data_hex bytes used to recompute a transaction identifier. The namespace selects a read representation; a byte-level transaction-hash check is a separate operation. Keep that distinction visible when naming files or passing records between tools, so a reviewer does not mistake one kind of β€œraw” for another.

Keep a useful precision regression note

Client version / host / network / check time:
Method and fixed record identifier:
Field name / documented unit / allowed schema range:
Original response representation / returned runtime type:
Exact parsing rule / comparison result:
Real provider observation or synthetic fixture:
Read-only use / unresolved compatibility limits:

A good regression note preserves the field path as well as the type. If a later release changes one field, compare that field under the same host and record context. Do not call a change in display formatting a change in the on-chain amount. Conversely, identical-looking strings are not enough if one came from a previously rounded Number.

For a clean comparison, retain the original response or exact fixture alongside the summarized result. A table that stores only a formatted decimal may lose the evidence needed to diagnose where precision changed. Keep any private application data out of a public example; our test used one already public receipt and deliberately synthetic large integers.

Choose the related next check

The TRON API validation review handles request construction and deployment evidence. The native and JSON-RPC comparison worksheet adds a dated balance and Energy-price comparison, plus separate quantity and response-envelope tests. The interface and unit must be established before formatting the exact integer. Link checked November 3, 2026. The token-decimal reading guide handles the separate unit-scale question after the exact integer is established.

Frequently asked questions

Did the real receipt lose numeric precision?

No loss was observed for the three checked values. They agreed exactly and were within the safe-integer range.

Was the large integer a real wallet balance?

No. It was a clearly synthetic local parsing fixture.

Can BigInt recover a number that already rounded?

Our test preserved the rounded result. It did not recover the original integer.

Does every raw field become a string?

No. Consult the method and schema coverage, and inspect the actual returned type. Our live comparison covered only three fields.

Were raw responses used to build a transaction?

No. We performed read-only comparisons and local arithmetic without signing or broadcasting.

Independent Tronscan News guide with AI-assisted drafting and primary-source checks on November 2, 2026. Two original diagrams, three actual field comparisons and fifteen local fixtures support this precision review. No chainwide error rate, arbitrary-provider compatibility, wallet action or transaction-building test is claimed. Browse the Tronscan News homepage; use About & Standards for corrections.

Rate this post

Comments

Leave a Reply

Your email address will not be published. Required fields are marked *