Search Apps Documentation Source Content File Folder Download Copy Actions Download State String Boolean Number Struct Map Slice Pointer Function Closure Reference Nil Package Type Interface Unknown

polls.gno

1.37 Kb · 59 lines
 1// Package polls implements a single fixed-choice poll where each address
 2// may cast one vote.
 3package polls
 4
 5import (
 6	"strconv"
 7
 8	"gno.land/p/nt/avl/v0"
 9)
10
11type option struct {
12	text  string
13	votes int
14}
15
16var (
17	question string
18	options  []*option
19	voters   avl.Tree // address string -> struct{}
20)
21
22func init() {
23	question = "What's your favorite gno.land feature?"
24	for _, text := range []string{
25		"Realms (on-chain smart contracts in Go-like Gno)",
26		"GRC20 tokens",
27		"Render() — realms rendering their own web pages",
28		"The gnokey CLI",
29	} {
30		options = append(options, &option{text: text})
31	}
32}
33
34// Vote casts a vote for the option at index i. Each address may vote once.
35// EOA-only — MsgRun callers are rejected.
36func Vote(cur realm, i int) {
37	if !cur.Previous().IsUserCall() {
38		panic("only a direct EOA call may vote")
39	}
40	if i < 0 || i >= len(options) {
41		panic("invalid option index")
42	}
43	addr := cur.Previous().Address().String()
44	if voters.Has(addr) {
45		panic("this address already voted")
46	}
47	options[i].votes++
48	voters.Set(addr, struct{}{})
49}
50
51// Render shows the poll question, options, and current vote tally.
52func Render(path string) string {
53	out := "# " + question + "\n\n"
54	for i, o := range options {
55		out += strconv.Itoa(i) + ". " + o.text + " — " + strconv.Itoa(o.votes) + " votes\n"
56	}
57	out += "\nCall Vote(i) with your option's index to vote.\n"
58	return out
59}