Key takeaways
- Staking 1 TRX yields 1 TRON Power (TP), and TP is the hard ceiling on a wallet's total votes — every node validates the ballot's sum against the account's TP.
- Each VoteWitnessContract replaces the account's entire prior ballot ("the last vote replaces all previous voting records"), so every vote transaction discloses the wallet's full allocation.
- "No TRX will be consumed for voting" — votes persist and can be recast freely — but unstaking the TRX behind them retracts votes automatically and proportionally.
- Voters earn a share of the per-block vote reward by voting weight, after the SR's brokerage cut (default 20%), claimed via WithdrawBalanceContract at most once per 24 hours.
Half of TRON’s consensus story gets told from the top: 27 elected block producers, rotating slots, a recurring election — the machinery covered in DPoS and the 27. The other half happens at the level of an individual wallet, because every seat in that election is held up by votes, and every vote is a transaction some wallet signed.
The voter’s loop is compact. An account stakes TRX for voting weight, submits a ballot allocating that weight across candidates, and — if it cares to — claims a share of the rewards its chosen Super Representatives pass down. Three contract types carry the whole cycle.
For an investigator, the interesting property is intent. A vote spends the wallet’s own staked weight, allocated by explicit choice, revised over time by fresh transactions. That makes voting history one of the most deliberate trails a TRON wallet leaves.
One TRX staked, one vote of weight
Voting requires TRON Power (TP), and TP comes from staking. The staking documentation states the rate directly: “Staking 1 TRX, you will get 1 TP.”
Under Stake 2.0 — TIP-467, status Final, the model the network runs today — that TP is a byproduct of the same stake that buys resources. A single FreezeBalanceV2Contract stake yields both Bandwidth or Energy and 1 TP per staked TRX; there is no separate stake-for-votes operation. The resource half of that trade belongs to Stake 2.0. Resources and votes acquired under the older Stake 1.0 remain valid.
TP sets the ceiling. java-tron’s VoteWitnessActuator — the code every node runs to validate a ballot — rejects any vote transaction whose total vote count exceeds the account’s TronPower. A wallet can split its weight across several candidates in any proportion, but the sum can never top what it has staked.
The ballot: VoteWitnessContract
The transaction that carries a vote is minimal. A VoteWitnessContract holds an owner_address (the voter) and a votes list, each entry pairing a candidate SR’s address (vote_address) with a weight (vote_count). One transaction can back a single SR with the wallet’s full weight or spread it across many.
The semantics have a sharp edge. The official voting guide states it directly: “Only the last vote will be recorded, meaning that the last vote replaces all previous voting records.” The reference implementation shows why — when java-tron applies a VoteWitnessContract, it clears the account’s existing vote set and then writes the submitted list. Nothing merges.
The corollary matters whenever you read vote history. Every ballot must carry the wallet’s entire intended allocation: a wallet backing three SRs that wants to add a fourth submits all four, because a VoteWitnessContract naming only the newcomer would strip the other three of that wallet’s votes.
Votes persist; the stake is the tether
Casting costs nothing beyond the transaction itself. The voting guide again: “No TRX will be consumed for voting.” The TP stays staked, the votes stay counted, and the wallet can recast at will without staking anything further.
That persistence has a boundary, and the boundary is the stake. TIP-467 specifies that if an account has voted, unstaking automatically cancels the corresponding votes. The staking documentation details the order: the system reclaims idle TP first, then used TP, and where the wallet has voted for multiple SRs, votes are revoked in proportion from each. Votes are never spent by voting, but they never outlive their collateral either.
The reward loop
Per the Super Representative documentation, each block currently pays out twice: 8 TRX to the SR that produced it, and 128 TRX shared among all SRs and SR partners in proportion to their votes. Both figures are network parameters that governance can adjust — read them as documented current values, not constants.
The vote reward is what reaches voters. Each SR or SR partner deducts a brokerage commission — the documented default is 20% — and distributes the remainder to its voters according to their voting weights. A wallet’s cut of a candidate’s reward tracks its share of that candidate’s votes.
Accrued rewards do not arrive on their own; the voter claims them with a WithdrawBalanceContract transaction, allowed at most once per 24 hours. The same contract type serves SRs withdrawing their block rewards, so the type alone marks a reward claim — whether the claimant is a producer or a voter depends on whose address signed it.
Reading a voter off the chain
A wallet’s participation in consensus reduces to three contract types, all placed in the wider taxonomy at Transaction Types and What They Carry:
| Step | Contract type | What the record shows |
|---|---|---|
| Stake | FreezeBalanceV2Contract (type 54) | TRX staked; yields a resource plus 1 TP per TRX. Older histories show Stake 1.0’s deprecated FreezeBalanceContract instead. |
| Vote | VoteWitnessContract (type 4) | The full ballot: owner_address plus (vote_address, vote_count) pairs. |
| Claim | WithdrawBalanceContract (type 13) | A reward withdrawal, at most one per 24 hours. |
The on-chain facts are narrow and hard. A VoteWitnessContract proves the signing wallet allocated its own staked voting weight — the validation rule guarantees the ballot was backed by that account’s TP, and the overwrite rule guarantees the ballot you see is the account’s complete allocation at that moment. A recurring WithdrawBalanceContract cadence adds that someone keeps coming back to collect.
What that activity means is a matter of inference, layered on the sourced mechanic. A voting wallet reads as one under active, discretionary control: capital was staked, candidates were chosen, and a ballot was signed that overwrote whatever came before. The documentation establishes what the transaction is; the analyst decides what it suggests about who is behind the keys.
A wallet showing FreezeBalanceV2Contract stakes, periodic VoteWitnessContract ballots, and 24-hour-spaced WithdrawBalanceContract claims is a wallet under deliberate, repeated operation, with real capital committed to the outcome. Idle wallets don’t vote.
Sources
- Stake 2.0 overview — TRON Developer Hub — the current revision of the staking page, retitled and rewritten; it still states the ratio, as “1 TP per 1 TRX staked”, but no longer in the words quoted in the body, so the archived revision below is cited for the wording.
- Staking on the TRON network — TRON Developer Hub, archived 2026-06-10 — the revision carrying “Staking 1 TRX, you will get 1 TP”, quoted verbatim in the body.
- Unstaking & cancellation — TRON Developer Hub — unstaking reclaims idle TP first and then voted TP, revoking votes proportionally across the SRs an account voted for.
- TIP-467 — Stake 2.0, a new TRON staking model — the ratified staking model (status: Final); staking grants TRON Power voting rights plus Bandwidth or Energy; unstaking automatically cancels the corresponding votes.
- TRON Developer Hub — Super Representatives — the 8 TRX block-production reward, the 128 TRX per-block vote reward shared by vote proportion, the 20% default brokerage, and distribution to voters by voting weight.
- TRON Developer Hub — VoteWitnessAccount API reference — the VoteWitnessContract shape:
owner_addressplus a votes list of (vote_address,vote_count) pairs. - System contract types — TRON Developer Hub — VoteWitnessContract “Casts votes for SR candidates”; WithdrawBalanceContract for SR block-reward and voter vote-reward claims, one withdrawal per 24 hours; and the
FreezeBalanceContract/FreezeBalanceV2Contractidentifiers with their enum numbers. - tronprotocol/documentation — Guide to Voting — voting requires TP at 1 TP per frozen TRX; “the last vote replaces all previous voting records”; “No TRX will be consumed for voting.”
- tronprotocol/java-tron — VoteWitnessActuator — consensus-rule enforcement: a ballot’s vote sum may not exceed the account’s TronPower, and the account’s existing votes are cleared before the submitted list is applied.
- balance_contract.proto — tronprotocol/protocol — the protocol definition of
FreezeBalanceContract(owner_address,frozen_balance,frozen_duration,resource,receiver_address) andWithdrawBalanceContract(owner_address) — the message types this chapter names. Protocol-authoritative: a contract type is either declared incore/contract/or it does not exist. - witness_contract.proto — tronprotocol/protocol — the protocol definition of
VoteWitnessContract(owner_address,votes,support) — the message type this chapter names. Protocol-authoritative: a contract type is either declared incore/contract/or it does not exist.