nips/69.md

80 lines
4.9 KiB
Markdown
Raw Normal View History

2023-02-26 22:12:09 -05:00
# Poll event
2023-02-26 22:00:50 -05:00
2023-03-02 05:38:22 -05:00
A poll note is a nostr event (kind `6969`) for conducting paid polls. A poll presents two or more voting options, which participants my vote on by sending regular zap events which include an additional `poll_option` vote tag. Poll results may be blinded, until after users have voted. Polls may specify a `closed_at` time, after which results should be unblinded, closed to new votes, and considered final. Polls may also specify a `consensus_threshold`.
2023-02-26 22:00:50 -05:00
## Purpose
2023-02-26 22:12:09 -05:00
The purpose of poll notes is to conduct quantitative public opinion polls over nostr by requiring voters pay to participate. By tying vote amounts and counts to real satoshi valuations, nostr polls intend to provide superior signal compared to other free polling models. Imposing real monetary costs on participants should also discourage attempts at fraudulent result manipulation, by automated or other means.
## Poll format
A poll event:
* MUST contain a primary description string, specified in the `content` field
* MUST contain a predefined list of voting options, defined in a `poll_options` tag
* MUST include at least 2 voting options, each with its own unique description string
2023-03-02 05:38:22 -05:00
* MUST specify a primary `tally_method`: either `value` OR `count`
* SHOULD specify a `closed_at` time:
* a `closed_at` value of less than or equal to the `created_at` field indicates a poll SHOULD NOT be closed.
* MAY include a `consensus_threshold` integar (0-100), representing a percentage threshold for any single vote option to achieve poll consensus
* a `consensus_threshold` of '0' indicates no threshold is specified.
```json
{
"id": <32-bytes lowercase hex-encoded sha256 of the the serialized event data>
"pubkey": <32-bytes lowercase hex-encoded public key of the event creator>,
"created_at": <unix timestamp in seconds>,
"kind": 6969,
"tags": [
["e", <32-bytes hex of the id of another event>, <recommended relay URL>],
["p", <32-bytes hex of the key>, <recommended relay URL>],
["poll_options": [
["0", <poll option 0 description string>],
["1", <poll option 1 description string>],
["n", <poll option n description string>],
],
["tally_method", "value"||"count"],
["consensus_threshold", <integar (0..100)>],
2023-03-02 04:53:27 -05:00
["closed_at", <unix timestamp in seconds>],
],
"content": <primary poll description string>,
"sig": <64-bytes hex of the signature of the sha256 hash of the serialized event data, which is the same as the "id" field>
}
```
## Zap vote format
Poll options are voted on by sending zap events (to the original poll event) which include 1 additional `poll_option` tag within their otherwise standard json structure.
Zap vote events (kind `9734` and `9735`):
* MUST include exactly 1 `poll_option` tag
* MUST reference the chosen vote option by its corresponding integar `n`, from the original poll event's list of predefined `polling_options`
* MUST transmit the exact `poll_option` between between kind `9734` and `9735`
```json
"tags": [
...
["poll_option", "n"],
...
]
```
## Poll outcomes
2023-03-02 05:38:22 -05:00
Votes may be tallied either by value or by count. To avoid ambiguity of a winning outcome, a primary `tally_method` MUST be specified as either `value` or `count`. When a `count` `tally_method` is specified, only a single vote (the most recent) per unique voter MUST be included in the tally, zap amounts MUST be ignored, and anonymous zaps MUST NOT be counted.
2023-03-02 05:38:22 -05:00
If a `closed_at` time is specified, after it is passed, a poll should be unblinded publicly and MUST be treated as closed (late votes must not be tallied). Once closed, the option associated with either the most satoshis (value) or the most votes (counts), depending on `tally_method`, MUST be treated as the winning option; while the distribution percentages across all vote options MUST be considered respresentative of the distribution of opinion amongst participants.
2023-03-02 04:53:27 -05:00
If a `closed_at` time is not specified (or is less than or equal to `created_at`), all votes SHOULD be tallied into perpetuity, and the most recent tally SHOULD be treated as the definitive outcome.
Additionally, if a consensus threshold percentage is specified, and any single option's associated value (or vote count) percentage of the poll's total value (or vote count, respectively) exceeds the consensus threshold, then consensus MUST be considered attained.
2023-03-02 04:53:27 -05:00
Strict adherence to these requirements should enable a standardized means of quantitatively assessing the distribution of opinion regarding a poll's content amongst poll participants, determining a winning outcome, and possibly acheiving consensus. However, until this protocol is further tested, refined, and proven robust, polls should probably not be considered authoritative nor binding.
2023-02-26 22:00:50 -05:00
## TODO
* refine standardized polling formats based on dev feedback
* send pull request (RFC) to nostr-protocol/NIPs
* implement polls in 1 relay
* implement polls in 2 clients
* merge with nostr-protocol/NIPs