Participate in Governance
This tutorial explains how to participate in ACDC on-chain governance, including viewing proposals, voting, and creating your own proposals.
Overview
ACDC uses on-chain governance for protocol decisions:
- Proposals: Suggested changes to the protocol
- Voting: Token holders vote based on stake
- Execution: Approved proposals are automatically executed
Voting Power
Your voting power equals your staked ACDC:
- 1 staked ACDC = 1 vote
- Delegated stake counts for the validator, not the delegator
- Votes can be: Yes, No, or Abstain
Proposal Types
| Type | Description | Threshold |
|---|---|---|
| Parameter | Change protocol parameters | 50% + 1 |
| Upgrade | Protocol upgrades | 66.7% |
| Spend | Treasury spending | 50% + 1 |
| Emergency | Critical fixes | 75% |
Viewing Proposals
Using CLI
# List active proposals
acdc governance list
# Output:
# Active Proposals:
# #42 - Increase Block Gas Limit
# Status: Active | Ends: 2024-01-20
# For: 45.2% | Against: 12.1% | Abstain: 5.3%
#
# #43 - Add New Validator Rewards
# Status: Active | Ends: 2024-01-22
# For: 62.8% | Against: 8.4% | Abstain: 3.1%
# View proposal details
acdc governance show 42
# Output:
# Proposal #42: Increase Block Gas Limit
# ========================================
# Proposer: dx1proposer123...
# Type: Parameter
# Status: Active
# Voting Period: 2024-01-15 to 2024-01-20
#
# Description:
# This proposal increases the block gas limit from 30M to 50M
# to accommodate higher transaction throughput.
#
# Actions:
# - setParameter("blockGasLimit", 50000000)
#
# Votes:
# For: 45,234,567 ACDC (45.2%)
# Against: 12,123,456 ACDC (12.1%)
# Abstain: 5,345,678 ACDC (5.3%)
# Quorum: 37.6% of 50% required
# List all proposals (including past)
acdc governance list --all
# Filter by status
acdc governance list --status passed
acdc governance list --status rejected
Using TypeScript SDK
import { AcdcClient, Governance } from '@acdc/sdk';
async function viewProposals() {
const client = new AcdcClient({
chain: 'delta',
network: 'mainnet'
});
const governance = new Governance(client);
// Get active proposals
const active = await governance.getProposals({ status: 'active' });
console.log('Active Proposals:');
for (const proposal of active) {
console.log(`\n#${proposal.id}: ${proposal.title}`);
console.log(` Status: ${proposal.status}`);
console.log(` Ends: ${new Date(proposal.endTime * 1000).toISOString()}`);
console.log(` For: ${proposal.votesFor.percentage}%`);
console.log(` Against: ${proposal.votesAgainst.percentage}%`);
}
// Get specific proposal
const proposal = await governance.getProposal(42);
console.log('\nProposal Details:');
console.log('Title:', proposal.title);
console.log('Description:', proposal.description);
console.log('Proposer:', proposal.proposer);
console.log('Actions:', proposal.actions);
}
viewProposals().catch(console.error);
Voting on Proposals
Prerequisites
- Have staked ACDC tokens
- Not have voted on this proposal yet
- Proposal must be in active voting period
Using CLI
# Vote yes
acdc governance vote 42 yes
# Output:
# Voting YES on Proposal #42...
# Transaction: 0xabc123...
# Vote submitted successfully!
# Your voting power: 10,000 ACDC
# Vote no
acdc governance vote 42 no
# Vote abstain (counts toward quorum but not for/against)
acdc governance vote 42 abstain
Using TypeScript SDK
import { AcdcClient, Wallet, Governance } from '@acdc/sdk';
async function vote() {
const client = new AcdcClient({
chain: 'delta',
network: 'mainnet'
});
const wallet = Wallet.fromMnemonic(process.env.MNEMONIC!);
const signer = wallet.connect(client);
const governance = new Governance(signer);
// Check voting power
const power = await governance.getVotingPower(wallet.address);
console.log(`Your voting power: ${power.formatted} ACDC`);
if (power.raw === 0n) {
console.log('You need to stake ACDC to vote');
return;
}
// Check if already voted
const hasVoted = await governance.hasVoted(42, wallet.address);
if (hasVoted) {
console.log('You have already voted on this proposal');
return;
}
// Cast vote
console.log('Voting YES on proposal #42...');
const tx = await governance.vote(42, 'yes');
console.log('Transaction:', tx.hash);
await tx.wait();
console.log('Vote submitted successfully!');
}
vote().catch(console.error);
Creating Proposals
Requirements
- Minimum 100,000 staked ACDC (proposal threshold)
- Proposal deposit: 10,000 ACDC (returned if passed, slashed if rejected)
Using CLI
# Create parameter change proposal
acdc governance propose \
--type parameter \
--title "Increase Block Gas Limit" \
--description "Increase gas limit from 30M to 50M for higher throughput" \
--action "setParameter blockGasLimit 50000000"
# Create treasury spend proposal
acdc governance propose \
--type spend \
--title "Fund Development Grant" \
--description "Allocate 100,000 ACDC for ecosystem development" \
--action "transfer dx1recipient... 100000000000000000000000"
# Output:
# Creating proposal...
# Deposit: 10,000 ACDC
# Transaction: 0xdef456...
# Proposal created!
# Proposal ID: 44
# Voting starts: 2024-01-15
# Voting ends: 2024-01-22
Using TypeScript SDK
import { AcdcClient, Wallet, Governance, parseUnits } from '@acdc/sdk';
async function createProposal() {
const client = new AcdcClient({
chain: 'delta',
network: 'mainnet'
});
const wallet = Wallet.fromMnemonic(process.env.MNEMONIC!);
const signer = wallet.connect(client);
const governance = new Governance(signer);
// Check if eligible to propose
const power = await governance.getVotingPower(wallet.address);
const threshold = await governance.getProposalThreshold();
if (power.raw < threshold.raw) {
console.log(`Need ${threshold.formatted} staked ACDC to propose`);
console.log(`You have: ${power.formatted} staked ACDC`);
return;
}
// Create proposal
const proposal = {
title: 'Increase Block Gas Limit',
description: `
## Summary
This proposal increases the block gas limit from 30M to 50M.
## Motivation
Current gas limit restricts throughput during peak usage.
## Specification
Set blockGasLimit parameter to 50,000,000.
## Risk Assessment
Low risk - similar limits work well on other networks.
`,
type: 'parameter',
actions: [
{
target: 'dx1paramcontract...',
function: 'setParameter',
args: ['blockGasLimit', 50000000]
}
]
};
console.log('Creating proposal...');
console.log('Deposit required: 10,000 ACDC');
const tx = await governance.propose(proposal);
console.log('Transaction:', tx.hash);
const receipt = await tx.wait();
// Get proposal ID from event
const event = receipt.events.find(e => e.event === 'ProposalCreated');
const proposalId = event.args.proposalId;
console.log(`Proposal created! ID: ${proposalId}`);
}
createProposal().catch(console.error);
Delegation
Delegate your voting power to another address:
Using CLI
# Delegate to an address
acdc governance delegate dx1delegate...
# Check your delegate
acdc governance delegate --show
# Remove delegation (self-delegate)
acdc governance delegate --self
Using TypeScript SDK
// Delegate voting power
const tx = await governance.delegate('dx1delegate...');
await tx.wait();
// Check current delegate
const delegate = await governance.getDelegate(wallet.address);
console.log('Delegated to:', delegate);
// Self-delegate (remove delegation)
const selfTx = await governance.delegate(wallet.address);
await selfTx.wait();
Monitoring Governance
Subscribe to Events
// Subscribe to new proposals
governance.on('ProposalCreated', (id, proposer, title) => {
console.log(`New proposal #${id}: ${title}`);
console.log(`Proposer: ${proposer}`);
});
// Subscribe to votes
governance.on('VoteCast', (proposalId, voter, vote, weight) => {
console.log(`Vote on #${proposalId}: ${vote}`);
console.log(`Voter: ${voter}, Weight: ${weight}`);
});
// Subscribe to proposal state changes
governance.on('ProposalExecuted', (id) => {
console.log(`Proposal #${id} executed!`);
});
governance.on('ProposalCanceled', (id) => {
console.log(`Proposal #${id} canceled`);
});
Query Historical Data
// Get vote history for an address
const votes = await governance.getVoteHistory(wallet.address);
for (const vote of votes) {
console.log(`Proposal #${vote.proposalId}: ${vote.vote}`);
console.log(` Weight: ${vote.weight}`);
console.log(` Time: ${new Date(vote.timestamp * 1000)}`);
}
// Get proposals by proposer
const myProposals = await governance.getProposals({
proposer: wallet.address
});
Governance Parameters
View current governance settings:
acdc governance params
# Output:
# Governance Parameters:
# Proposal Threshold: 100,000 ACDC
# Proposal Deposit: 10,000 ACDC
# Voting Period: 7 days
# Quorum: 50%
# Pass Threshold: 50% + 1
# Upgrade Threshold: 66.7%
# Emergency Threshold: 75%
# Timelock Delay: 2 days
Complete Voting Script
// governance-voter.ts
import { AcdcClient, Wallet, Governance, formatUnits } from '@acdc/sdk';
async function main() {
const client = new AcdcClient({
chain: 'delta',
network: process.env.NETWORK || 'mainnet'
});
const wallet = Wallet.fromMnemonic(process.env.MNEMONIC!);
const signer = wallet.connect(client);
const governance = new Governance(signer);
console.log('ACDC Governance Voter');
console.log('=====================');
console.log('Address:', wallet.address);
// Check voting power
const power = await governance.getVotingPower(wallet.address);
console.log(`Voting Power: ${power.formatted} ACDC`);
if (power.raw === 0n) {
console.log('\nNo voting power. Stake ACDC to participate.');
return;
}
// Get active proposals
const proposals = await governance.getProposals({ status: 'active' });
if (proposals.length === 0) {
console.log('\nNo active proposals.');
return;
}
console.log('\nActive Proposals:');
for (const p of proposals) {
const hasVoted = await governance.hasVoted(p.id, wallet.address);
console.log(`\n#${p.id}: ${p.title}`);
console.log(` Type: ${p.type}`);
console.log(` Ends: ${new Date(p.endTime * 1000).toLocaleDateString()}`);
console.log(` For: ${p.votesFor.percentage}%`);
console.log(` Against: ${p.votesAgainst.percentage}%`);
console.log(` Your vote: ${hasVoted ? 'Already voted' : 'Not yet voted'}`);
}
// Vote on first unvoted proposal
const proposalId = process.env.PROPOSAL_ID;
const voteChoice = process.env.VOTE; // 'yes', 'no', or 'abstain'
if (proposalId && voteChoice) {
const hasVoted = await governance.hasVoted(
parseInt(proposalId),
wallet.address
);
if (hasVoted) {
console.log(`\nAlready voted on proposal #${proposalId}`);
return;
}
console.log(`\nVoting ${voteChoice.toUpperCase()} on proposal #${proposalId}...`);
const tx = await governance.vote(
parseInt(proposalId),
voteChoice as 'yes' | 'no' | 'abstain'
);
console.log('Transaction:', tx.hash);
await tx.wait();
console.log('Vote submitted successfully!');
}
}
main().catch(console.error);
Run:
MNEMONIC="your mnemonic" \
PROPOSAL_ID=42 \
VOTE=yes \
npx ts-node governance-voter.ts
Best Practices
-
Research Before Voting
- Read the full proposal description
- Understand the technical implications
- Check community discussion
-
Consider Delegation
- If you lack time to research, delegate to someone you trust
- You can always override delegation by voting directly
-
Participate Regularly
- Governance requires active participation
- Low turnout can lead to poor decisions
-
Proposal Quality
- Write clear, detailed proposals
- Include risk assessments
- Engage with community feedback
Next Steps
- Staking Guide - Stake ACDC to gain voting power
- Send Your First Transaction - Basic transactions
- API Reference - Programmatic access