fix(sdk-coin-trx): emit canonical AccountCreate raw_data_hex#8837
Open
bhavidhingra wants to merge 1 commit into
Open
fix(sdk-coin-trx): emit canonical AccountCreate raw_data_hex#8837bhavidhingra wants to merge 1 commit into
bhavidhingra wants to merge 1 commit into
Conversation
Ticket: CHALO-457
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
AccountCreateContract's enum value is0— the proto3 default for the outerTransaction.Contract.typefield. The SDK explicitly encoded it, soraw_data_hexcarried a stray 2-byte0800tag inside the contract envelope.TRON's node re-serializes
raw_datafrom broadcast JSON under strict proto3 semantics, which omits default-valued fields. Its canonicalraw_data_hexis 2 bytes shorter, with a differentsha256(=txID).For TSS wallets the signature is computed over
sha256(SDK_raw_data_hex)but TRON validates againstsha256(canonical_raw_data_hex). ECDSA recovery against the mismatched digest returns an unrelated pubkey, whose TRON address is not in the wallet's permission set, and broadcast fails with:Hot-wallet flows sign-and-recover locally against the same buggy bytes and so don't trip this.
Why only AccountCreate
typeenum valueEvery other commonly-used TRON contract type has a non-default enum value, so the SDK's encoding happens to match TRON's canonical re-serialization. The analogous proto3-default guard for the inner
resource: BANDWIDTH=0field is already present infreezeBalanceTxBuilder.ts:175-181with an explanatory comment — this PR applies the same idea to the outertypefield for AccountCreate.Fix
In
getAccountCreateTxRawDataHex, omit the explicittypefield from thetxContractliteral so protobufjs doesn't emit the default-valued tag. The decoded protobuf still reportstype = AccountCreateContractbecause that's the field's default value.Also removes the now-unused
ContractTypeimport.Verification
Re-encoding the failure-case inputs (real production broadcast bytes) with the fix produces the canonical 132-byte
raw_data_hex, and ECDSA-recovering the production signature againstsha256(canonical)returns exactly the address TRON's error reported (TMAFWDcE5hpDvcQVn89gGB5oACwGXZKZqV) — confirming the diagnosis is precisely the failure mechanism.Test plan
npm test -w modules/sdk-coin-trx -- --grep "proto3 default"— new regression test assertsraw_data_hexdoes not contain5a68080012(buggy framing with the default-valued enum tag) and does contain5a661264(canonical framing).🤖 Generated with Claude Code