wallet/votewitnessaccount
Vote for Super Representatives using TRX voting power from frozen balance.
Endpoint
POST /wallet/votewitnessaccount
Parameters
Required Parameters
Parameter | Type | Description |
---|---|---|
owner_address | string | Voter's account address (base58) |
votes | array | Array of vote objects with SR address and vote count |
Vote Object Structure
Field | Type | Description |
---|---|---|
vote_address | string | Super Representative address |
vote_count | number | Number of votes to cast |
Optional Parameters
Parameter | Type | Description |
---|---|---|
permission_id | number | Permission ID for multi-signature (default: 0) |
visible | boolean | Return base58 addresses (default: false returns hex) |
Response
Returns unsigned transaction containing the voting operation. Transaction must be signed and broadcast.
Response Fields
txID
- Transaction hashraw_data
- Transaction raw datacontract
- Voting contract detailsexpiration
- Transaction expiration timestamptimestamp
- Transaction creation timestamp
visible
- Address format indicator
Important Notes
Voting Rules
- Voting Power: 1 frozen TRX = 1 vote
- Vote Distribution: Can split votes among multiple SRs
- Vote Persistence: Votes remain until changed or TRX unfrozen
- Immediate Effect: Votes count immediately after confirmation
- Rewards: Voting rewards distributed daily based on SR performance
Implementation Examples
- JavaScript
- Python
- cURL
// Vote for single SR
const response = await fetch('https://api-tron-mainnet.n.dwellir.com/YOUR_API_KEY/wallet/votewitnessaccount', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
owner_address: 'TVoterAddress...',
votes: [
{
vote_address: 'TSRAddress...',
vote_count: 1000000 // 1M votes
}
],
visible: true
}),
});
const transaction = await response.json();
console.log('Vote transaction created:', transaction.txID);
// Vote for multiple SRs
const multiVoteResponse = await fetch('https://api-tron-mainnet.n.dwellir.com/YOUR_API_KEY/wallet/votewitnessaccount', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
owner_address: 'TVoterAddress...',
votes: [
{
vote_address: 'TSR1Address...',
vote_count: 500000
},
{
vote_address: 'TSR2Address...',
vote_count: 300000
},
{
vote_address: 'TSR3Address...',
vote_count: 200000
}
],
visible: true
}),
});
const multiVoteTx = await multiVoteResponse.json();
console.log('Multi-vote transaction:', multiVoteTx.txID);
// Clear all votes (vote with empty array)
const clearVotesResponse = await fetch('https://api-tron-mainnet.n.dwellir.com/YOUR_API_KEY/wallet/votewitnessaccount', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
owner_address: 'TVoterAddress...',
votes: [],
visible: true
}),
});
import requests
url = "https://api-tron-mainnet.n.dwellir.com/YOUR_API_KEY/wallet/votewitnessaccount"
# Vote for single SR
single_vote = {
"owner_address": "TVoterAddress...",
"votes": [
{
"vote_address": "TSRAddress...",
"vote_count": 1000000 # 1M votes
}
],
"visible": True
}
response = requests.post(url, json=single_vote)
print(f"Single vote TX: {response.json()['txID']}")
# Vote for multiple SRs with weighted distribution
multi_vote = {
"owner_address": "TVoterAddress...",
"votes": [
{
"vote_address": "TSR1Address...",
"vote_count": 600000 # 60% of votes
},
{
"vote_address": "TSR2Address...",
"vote_count": 300000 # 30% of votes
},
{
"vote_address": "TSR3Address...",
"vote_count": 100000 # 10% of votes
}
],
"visible": True
}
multi_response = requests.post(url, json=multi_vote)
print(f"Multi-vote TX: {multi_response.json()['txID']}")
# Update existing votes
update_vote = {
"owner_address": "TVoterAddress...",
"votes": [
{
"vote_address": "TNewSRAddress...",
"vote_count": 1000000
}
],
"visible": True
}
update_response = requests.post(url, json=update_vote)
print(f"Updated votes TX: {update_response.json()['txID']}")
# Vote for single SR
curl -X POST https://api-tron-mainnet.n.dwellir.com/YOUR_API_KEY/wallet/votewitnessaccount \
-H "Content-Type: application/json" \
-d '{
"owner_address": "TVoterAddress...",
"votes": [
{
"vote_address": "TSRAddress...",
"vote_count": 1000000
}
],
"visible": true
}'
# Vote for multiple SRs
curl -X POST https://api-tron-mainnet.n.dwellir.com/YOUR_API_KEY/wallet/votewitnessaccount \
-H "Content-Type: application/json" \
-d '{
"owner_address": "TVoterAddress...",
"votes": [
{
"vote_address": "TSR1Address...",
"vote_count": 500000
},
{
"vote_address": "TSR2Address...",
"vote_count": 300000
},
{
"vote_address": "TSR3Address...",
"vote_count": 200000
}
],
"visible": true
}'
# Clear all votes
curl -X POST https://api-tron-mainnet.n.dwellir.com/YOUR_API_KEY/wallet/votewitnessaccount \
-H "Content-Type: application/json" \
-d '{
"owner_address": "TVoterAddress...",
"votes": [],
"visible": true
}'
Example Response
{
"visible": true,
"txID": "f9e8d7c6b5a4e3d2c1b0a9f8e7d6c5b4a3d2c1e0f9e8d7c6b5a4e3d2c1b0a9f8",
"raw_data": {
"contract": [
{
"parameter": {
"value": {
"owner_address": "TVoterAddress...",
"votes": [
{
"vote_address": "TSRAddress...",
"vote_count": 1000000
}
]
},
"type_url": "type.googleapis.com/protocol.VoteWitnessContract"
},
"type": "VoteWitnessContract"
}
],
"ref_block_bytes": "8d7e",
"ref_block_hash": "6f5a9b8c7d6e5f4a",
"expiration": 1702456849000,
"timestamp": 1702456789000
}
}
Voting Strategies
class VotingStrategy {
constructor(apiKey) {
this.apiKey = apiKey;
this.baseUrl = `https://api-tron-mainnet.n.dwellir.com/${apiKey}`;
}
// Get available voting power
async getVotingPower(address) {
const response = await fetch(`${this.baseUrl}/wallet/getaccount`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ address, visible: true })
});
const account = await response.json();
const frozenTRX = account.frozen?.[0]?.frozen_balance || 0;
return frozenTRX / 1000000; // Convert to TRX
}
// Calculate optimal vote distribution
async optimizeVotes(voterAddress, srAddresses, strategy = 'balanced') {
const votingPower = await this.getVotingPower(voterAddress);
if (strategy === 'balanced') {
// Equal distribution
const votePerSR = Math.floor(votingPower / srAddresses.length);
return srAddresses.map(sr => ({
vote_address: sr,
vote_count: votePerSR
}));
} else if (strategy === 'weighted') {
// Weighted by SR performance
const witnesses = await this.getWitnesses();
const selectedSRs = witnesses.filter(w => srAddresses.includes(w.address));
// Weight by reliability
const totalReliability = selectedSRs.reduce((sum, sr) => {
const reliability = sr.totalProduced / (sr.totalProduced + sr.totalMissed);
return sum + reliability;
}, 0);
return selectedSRs.map(sr => {
const reliability = sr.totalProduced / (sr.totalProduced + sr.totalMissed);
const weight = reliability / totalReliability;
return {
vote_address: sr.address,
vote_count: Math.floor(votingPower * weight)
};
});
}
}
// Get current votes
async getCurrentVotes(address) {
const response = await fetch(`${this.baseUrl}/wallet/getaccount`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ address, visible: true })
});
const account = await response.json();
return account.votes || [];
}
// Estimate voting rewards
async estimateRewards(voterAddress) {
const votes = await this.getCurrentVotes(voterAddress);
const witnesses = await this.getWitnesses();
let estimatedDaily = 0;
for (const vote of votes) {
const sr = witnesses.find(w => w.address === vote.vote_address);
if (sr && sr.brokerage) {
// SR shares (100 - brokerage)% of rewards with voters
const rewardShare = (100 - sr.brokerage) / 100;
const srDailyReward = 16 * 20 * 60 * 24; // 16 TRX per block
const voterShare = (vote.vote_count / sr.voteCount) * srDailyReward * rewardShare;
estimatedDaily += voterShare;
}
}
return {
daily: estimatedDaily,
monthly: estimatedDaily * 30,
yearly: estimatedDaily * 365,
apy: (estimatedDaily * 365 / (votes.reduce((sum, v) => sum + v.vote_count, 0) / 1000000)) * 100
};
}
}
// Example usage
async function manageVoting() {
const strategy = new VotingStrategy('YOUR_API_KEY');
// Check voting power
const power = await strategy.getVotingPower('TVoterAddress...');
console.log(`Available voting power: ${power} TRX`);
// Optimize vote distribution
const srList = ['TSR1...', 'TSR2...', 'TSR3...'];
const optimizedVotes = await strategy.optimizeVotes(
'TVoterAddress...',
srList,
'weighted'
);
console.log('Optimized vote distribution:', optimizedVotes);
// Estimate rewards
const rewards = await strategy.estimateRewards('TVoterAddress...');
console.log(`Estimated APY: ${rewards.apy.toFixed(2)}%`);
}
Best Practices
1. Research Before Voting
- Check SR reliability (>99.5% uptime)
- Review SR contributions to ecosystem
- Verify reward distribution policies
2. Vote Management
- Regularly review and update votes
- Monitor SR performance changes
- Rebalance votes based on performance
3. Security
- Use multi-signature for large voting accounts
- Verify SR addresses before voting
- Keep voting transactions records
4. Optimization
- Diversify votes across multiple reliable SRs
- Consider both rewards and network health
- Participate in governance discussions
Common Errors
Error | Description | Solution |
---|---|---|
Insufficient frozen balance | Not enough voting power | Freeze more TRX first |
Invalid witness address | SR address not found | Verify SR address from listwitnesses |
Total votes exceed frozen balance | Votes > available power | Reduce total vote count |
Contract validate error | Invalid transaction format | Check parameter structure |
Use Cases
- Governance Participation: Vote for network validators
- Reward Earning: Earn passive income from voting
- SR Support: Support specific Super Representatives
- Network Decentralization: Distribute voting power
- Strategic Voting: Optimize rewards through vote management
Related Methods
- wallet/listwitnesses - Get list of Super Representatives
- wallet/freezebalancev2 - Freeze TRX for voting power
- wallet/getaccount - Check current votes