nips/69.md

94 lines
5.7 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 23:39:30 -05:00
`draft` `optional` `author:toadlyBroodle`
A poll note is a [nostr event](01.md) (kind `6969`) for conducting paid polls. A poll presents two or more voting options, which participants my vote on by sending regular [zap events](57.md) which include an additional `poll_option` vote tag. Poll results should be blinded, until after users have voted. Polls should specify a `closed_at` time, after which results be unblinded, closed to new votes, and the tally considered final. Polls may specify either `value_maximum` or `value_minimum` satoshi valuations for determining which zaps are included in the tally. Polls may also specify a `consensus_threshold` for assessing the state of consensus.
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 tallying results 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.
By including a `value_maximum` limit, polls can reduce the likelihood of 'whale' votes discounting many smaller 'shrimp' votes. Likewise, by including a `value_minimum` limit, polls can make automated vote flooding attacks prohibitively expensive. However, both limits remain optional to allow for freedom in poll design.
A careful balancing of all poll attributes should enable pollers to conduct polls with meaningful and valuable outcomes.
## Poll format
A poll event:
* MUST contain a primary description string, specified in the `content` field
* MUST contain a `poll_options` tag, containing a serialized key-value array of vote options, formatted as below
* MUST include at least 2 voting options, each with its own unique description string
* 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 specify a `value_maximum` satoshi value for zapped votes to be included in the tally
* MAY specify a `value_minimum` satoshi value for zapped votes to be included in the tally
2023-03-04 22:01:33 -05:00
* MAY include a `consensus_threshold` (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
{
2023-03-02 23:27:12 -05:00
"id": <32-bytes lowercase hex-encoded sha256 of 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']]"],
["value_maximum", "maximum satoshi value for inclusion in tally"],
["value_minimum", "minimum satoshi value for inclusion in tally"],
["consensus_threshold", "required percentage to attain consensus <0..100>"],
["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](57.md) (to the original poll event) which include 1 additional `poll_option` tag in the zap request event.
The zap request event (kind `9734`):
* MUST include exactly 1 `poll_option` tag
* MUST reference the vote option by its corresponding integer `n`, chosen from the original poll event's key-value array of predefined `polling_options`
```json
"tags": [
...
["poll_option", "n"],
...
]
```
## Poll outcome
To avoid ambiguity of results, strict adherence to the following rules is vital when tallying and rendering poll outcomes.
A tallying client:
* MUST clearly indicate the `value_maximum`, `value_minimum`, and `closed_at` attributes (when specified) to participants before they vote
* MUST ONLY include full satoshi value amounts in option tallies from all eligible zaps, according to the following criteria:
* if a `value_maximum` is specified, clients:
* MUST include zap amounts less than or equal to `value_maximum` in the tally
* MUST NOT include zap amounts greater than `value_maximum` in the tally
* if a `value_minimum` is specified, clients:
* MUST include zap amounts greater than or equal to `value_minimum` in the tally
* MUST NOT include zap amounts less than `value_minimum` in the tally
* if a valid `closed_at` time is specified, clients:
* MUST NOT tally late votes received after `closed_at` time
Additionally, a tallying client:
* MUST display the distribution percentages, from the tally total, for each vote option tally
* MUST display the `consensus_threshold` (if specified) relative to the winning vote percentage
* SHOULD publicly blind results until after a user's vote has been received
* SHOULD publicly display results after the `closed_at` time has passed (if specified)
* MAY display the counts of zap events received for each option, along with other poll statistics
2023-03-02 23:27:12 -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 achieving 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
2023-03-02 23:41:26 -05:00
* refine NIP#69 based RFC feedback
* implement polls in 2 clients
* merge with nostr-protocol/NIPs