Build real things · ≈ 14 min

Voting that cannot be voted twice

Proposals, a deadline, one vote per address, and a result nobody can quietly change afterwards.

On-chain voting is attractive for one reason: the tally is computed from records anyone can re-check, so the count is not something you have to trust anyone about.

That only holds if three things are true:

1. One vote per voter — enforced by storage, not by good manners 2. A deadline that comes from consensus, not from a clock 3. A tally nobody can edit after the fact

Use abi.block_height() for deadlines, not a timestamp where you can help it. Height is a count every node agrees on exactly. Block timestamps are also agreed, but they are permitted to drift within a tolerance, and a miner has some influence over them. If a few minutes of slack would change who wins, height is the safer clock.

Animica blocks average about two minutes (121 seconds measured), so "roughly a day" is about 715 blocks. Write that arithmetic in a comment — the next person to read deadline = start + 715 will not otherwise know whether you meant a day or a week.

Everything on-chain is public, including your vote. A ballot stored in contract storage is readable by anyone forever. If secrecy matters, the pattern is commit-reveal: first submit hash(choice + secret), then reveal the choice after voting closes. That is a substantially harder contract, and worth knowing exists before you promise anyone a private vote.

Your turn

Implement vote(yes) and result(). A voter may vote once — a second attempt reverts b"already_voted" and must not change the tally. Voting after the deadline reverts b"closed". result() returns 1 if yes beats no, 2 if no beats yes, 0 for a tie.

Hints

Stuck? Ask

Answered by Animica's own free inference network. It is donated GPU capacity, so give it 20-30 seconds.