Voting on Polls
Voting on a governance poll is one transaction that pays gas only. Nothing is locked, nothing is transferred, and you can change your mind as often as you like until the poll closes.
Read the poll first
Option numbers are 0-based and fixed at deployment in whatever order the author chose.
They are not alphabetical, "Yes" is not always 0, and two polls on the same subject may
number their options differently.
node scripts/superhero-governance.mjs info <poll_address>
node scripts/superhero-governance.mjs info-by-id <poll_id>Check three fields: vote_options for the index-to-label mapping, is_closed, and
my_vote. See Polls for the full output shape.
Cast a vote
node scripts/superhero-governance.mjs vote <poll_address> <option_number># Vote for option 0 on a specific poll
node scripts/superhero-governance.mjs vote ct_abc123... 0The script re-reads the poll before submitting. It refuses an option index the poll does not define (printing the valid options instead) and refuses to vote on a poll that is already closed. The contract enforces the same two rules:
stateful entrypoint vote(option : int) =
require(!is_closed(), "POLL_ALREADY_CLOSED")
require(Map.member(option, state.vote_options), "VOTE_OPTION_NOT_KNOWN")
put(state{ votes[Call.caller] = option})
Chain.event(Vote(Contract.address, Call.caller, option))is_closed() is Chain.block_height >= close_height for a poll that has one, and false for
a poll with close_height = None, which is how an open-ended poll stays votable forever.
The script prints the option label it voted for:
{
"success": true,
"action": "vote",
"poll_address": "ct_abc123...",
"option": "0",
"option_label": "Yes",
"tx_hash": "th_..."
}Change or revoke a vote
Voting again replaces your previous vote. One address has one vote per poll; calling
vote with a different option updates your choice. You do not need to revoke first.
This is the opposite of a community DAO vote, where a second vote is rejected
with VOTER_ALREADY_VOTED and you must revoke before changing anything.
node scripts/superhero-governance.mjs revoke <poll_address>Revoking removes your vote entirely, so the poll counts you as not having voted:
- Your AE stops counting for the option you had chosen.
- Your delegation comes back into effect for that poll. Voting directly overrides your delegation only while your vote stands; once revoked, whoever you delegated to speaks for your balance again. To abstain rather than hand your weight back to your delegatee, revoke your delegation too; see Delegation.
You can vote again after revoking, as long as the poll is still open. revoke_vote itself is
not restricted to open polls. The script checks that you have actually voted before
submitting a revocation, so a revoke on a poll you never voted in fails locally rather than
costing a transaction.
Nothing is locked
| Governance poll | Community DAO vote | |
|---|---|---|
| Allowance needed first | No | Yes, AEX-9 |
| Tokens transferred to the contract | No | Yes |
| Balance immobilised while voting | No | Yes, until you revoke or withdraw |
| What is counted | Your AE balance at the poll's close height | The token amount you locked |
| Changing your mind | Call vote again | Rejected: revoke_vote first |
| Revoking after the close | Allowed | Rejected: VOTE_ALREADY_CLOSED |
| Withdrawal step after closing | None | Required |
| Minimum to participate | None | The amount you stake, plus an allowance |
The Poll contract has no token field, no allowance surface and no withdrawal entrypoint. It
records which option your address chose; the weight behind that is computed off-chain from
your AE balance and your delegations at the close height. Your AE stays liquid and spendable
the whole time.
Your weight is not fixed when you vote. Spending AE after voting reduces the weight behind your choice; receiving AE increases it. What matters is your balance when the poll closes.
The snapshot only exists once the poll has closed:
| Poll state | Weighting is read at |
|---|---|
| Open, with a future close height | The current height; the figures move as balances move |
| Closed | The close height: fixed |
Open-ended (close_height = None) | The current height, forever. There is never a snapshot |
An open poll's percentages are a live reading, so two people loading the same open poll an hour apart can legitimately see different numbers.
There is no minimum balance to vote. An account with nothing in it can cast a vote that
records normally, emits a Vote event and appears in votes(). It contributes zero stake,
but it is counted in the backend's voteCount, the address count the app shows as "Total
Votes". See Polls.
Nothing about a governance poll executes on-chain. Acting on a result is a separate, off-chain process. See Community DAOs for the system where a passing vote moves money.
Vote from the app
- Open superhero.com/voting (opens in a new tab) and find the poll, or go
straight to
/voting/p/:pollAddress. - Connect your wallet.
- Read the title, description and reference link, then click the option you want. The options are lettered A, B, C in the interface but are indexed 0, 1, 2 on-chain.
- Approve the transaction.
Your chosen option is highlighted as Selected afterwards, and a Revoke Vote button appears. The same page shows live stake-weighted results and, below them, your account balance, your delegation status and how many accounts delegate to you.
The app's Total Votes figure and its per-option percentage bars are computed from address
counts. For the stake-weighted picture (the official result), read option_stake and
percentage_of_total_stake from the governance API, or the stake_weighted_results block in
the CLI's info output.
After voting
The app posts a contractEvent notification to the governance backend immediately after every
vote and revocation so the backend re-indexes promptly. If you vote through your own client and
skip that call, expect your vote to take longer to appear in stake-weighted results. The vote
itself is on-chain and counted regardless.
Related
- Polls: the data model, and why the stake-weighted figure is the real result.
- Delegation: what your vote overrides, and what comes back when you revoke it.
- Creating a Poll: asking the question rather than answering it.
- Voting in a community DAO: the other system, where voting locks your tokens.
- Governance with an agent: the read-before-voting workflow, automated.
- Vote on a poll (opens in a new tab): the live interface.