मुख्य सामग्री पर जाएँ

Voting types

How to shape a question's ballot - single choice or multichoice out of the box, and approval, ranked or quadratic through a raw override. Each question in a process picks its own type, so one process can mix them.

Each question in a process shapes its own ballot. You pick a named type and tune it with typeSetup, or drop to a raw ballotProtocol override for shapes that do not have a named preset yet. Because the type is per question, one process can mix a single-choice question with an approval question.

Named types

Set type and, optionally, typeSetup on the question:

type Ballot typeSetup
singlechoice Pick one of N options - the ballot is [chosenIndex]. -
multichoice Approve a subset of N options - the ballot is [0/1 per option]. maxChoices caps how many may be selected; minChoices is a validation hint.
// single choice: pick one of the choices
{ "type": "singlechoice",
  "choices": [ { "title": { "default": "Ada Lovelace" }, "value": 0 },
               { "title": { "default": "Alan Turing" }, "value": 1 } ] }

// multichoice: approve up to 2 of the choices
{ "type": "multichoice",
  "typeSetup": { "minChoices": 1, "maxChoices": 2, "uniqueChoices": false },
  "choices": [ /* N options */ ] }

typeSetup fields:

Field Type Description
minChoices integer Validation hint for the minimum selections (not enforced on-chain).
maxChoices integer Maximum selections for multichoice.
uniqueChoices boolean Require every field in the ballot to hold a distinct value.

Raw ballot override

For approval variants, ranked, or quadratic voting, set ballotProtocol on the question. When present it takes priority over type/typeSetup and maps directly onto the on-chain election parameters. Note the field names differ from typeSetup: the raw override uses maxCount/maxValue/uniqueValues (protocol names), where typeSetup used maxChoices/uniqueChoices.

Field Type Description
maxCount integer Number of fields in the ballot.
maxValue integer Largest value any field may take (0 = values are amounts to aggregate).
uniqueValues boolean Require distinct values across fields (ranked).
costExponent integer Exponent applied per value when computing ballot cost (quadratic uses a squared cost).
maxTotalCost integer Cap on the summed cost across the ballot (e.g. the number of approvals, or a credit budget).
costFromWeight boolean Use each voter's census weight as their credit budget.
maxVoteOverwrites integer How many times a voter may change their vote.
  • Ranked - uniqueValues: true with maxValue = choices - 1, so each rank is used once.
  • Quadratic / budget - maxValue: 0 with a costExponent and a maxTotalCost budget (or costFromWeight: true to derive the budget from a weighted census).
// quadratic: allocate a credit budget across options, squared cost
{ "ballotProtocol": {
    "maxCount": 4, "maxValue": 0,
    "costExponent": 2, "maxTotalCost": 100
  },
  "choices": [ /* 4 options to fund */ ] }

Exact encoding

ballotProtocol is the raw protocol contract - the precise numeric encoding (including any cost scaling) is defined by the ballot protocol, not the SaaS. Confirm values against the OpenAPI specification and the vocdoni-ballot-protocol skill before relying on a particular curve. Shapes that need a minimum value or an exactly-K selection count are not yet expressible.

Secret results

Set "secretUntilTheEnd": true on a question to keep its tally encrypted until it ends. Voters seal their ballots with the question's on-chain encryption keys - see Casting votes.

Reading the results

Whatever the type, a question's results come back as results[field][value]. Single choice reads discretely; approval reads the per-option results[i][1]; ranked and quadratic read index-weighted. See Results for the response shape and the reading each type uses.

For the complete, machine-readable contract, see the OpenAPI specification.