-
Notifications
You must be signed in to change notification settings - Fork 612
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Polls RFC 69 #320
Open
toadlyBroodle
wants to merge
61
commits into
nostr-protocol:master
Choose a base branch
from
toadlyBroodle:master
base: master
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Polls RFC 69 #320
Changes from all commits
Commits
Show all changes
61 commits
Select commit
Hold shift + click to select a range
230c8ba
Create 69
toadlyBroodle 1fa1d05
Rename 69 to 69.md
toadlyBroodle bac216d
Update README.md
toadlyBroodle 71cfaae
Update README.md
toadlyBroodle 455d2f4
Update 69.md
toadlyBroodle 72260b2
Update 69.md
toadlyBroodle 255c4d9
add RFC
toadlyBroodle 8fa390a
definition
toadlyBroodle 9573ad3
add outcomes
toadlyBroodle ce4c128
enhance definitions
toadlyBroodle 4f337ed
standardize poll format
toadlyBroodle a55a79e
adjust poll format
toadlyBroodle 4d6da84
zap vote format
toadlyBroodle 25ad6d7
rename closing_time->closed_at
toadlyBroodle 4ad8b36
format clarifications
toadlyBroodle ae55cbf
codify tally_method
toadlyBroodle edd1353
section clarifications
toadlyBroodle 4d173a5
add poll tags
toadlyBroodle e92e50d
reformat tag table
toadlyBroodle a38ff0b
fix poll option values
toadlyBroodle aa293a6
add nip links
toadlyBroodle cdd6281
sync master
toadlyBroodle 510b3d9
spell check
toadlyBroodle d39fa6d
spell check
toadlyBroodle 19dfd63
typo fix
toadlyBroodle fe6bd67
add header labels
toadlyBroodle 2bae130
update TODOs
toadlyBroodle 980e132
Apply suggestions from code review
toadlyBroodle d061eb0
convert poll_options array to json serialized key-value array, change…
toadlyBroodle 5d0ad89
merge with remote master
toadlyBroodle a2f6b39
add value_minimum attribute, poll_option syntax fix
toadlyBroodle 9ce8a86
elaborate on purpose of value/count tally_methods based on feedback
toadlyBroodle f292a7e
remove tally_method tag, add value_maximum tag, rewrite affected sect…
toadlyBroodle e20343c
add poll_option tag to zap event format and README, minor changes to …
toadlyBroodle 6410475
more precisely define consensus_threshold, remove reference to fraudu…
toadlyBroodle f435bc8
require e/p tags be specified, require primary hosting relay be speci…
toadlyBroodle b8d39fd
require ots tags accompany closed_at tags
toadlyBroodle cf17e33
allow for additional p-keys to be included in poll events and tallies
toadlyBroodle c5027b9
add description of multiple p-keys to introduction section
toadlyBroodle db4741d
elaborate on purpose of multiple-p keys
toadlyBroodle c7d8700
update poll_options value to json serialized Map<Int, String>
toadlyBroodle b61e25c
add Zap Voting section, change poll_options tag from nested json to m…
toadlyBroodle c2e8269
add clarifying requirements for voting- tallying-clients
toadlyBroodle 313ae7c
clarify that `e` tag is optional
toadlyBroodle 0de2196
refine overview section, alter atomic poll tally rules
toadlyBroodle cd8ed5e
move poll_option tag from 9735->9734
toadlyBroodle 4d22b2d
rename to Zap Polls
toadlyBroodle 900268c
Merge branch 'master' into master
toadlyBroodle 4782bd4
dont allow poll authors to vote on own polls, fix event table formatting
toadlyBroodle 678f0c0
Merge remote-tracking branch 'nostr-protocol/master'
toadlyBroodle df236f4
merge recent changes
toadlyBroodle 5429dce
rename poll->zap poll
toadlyBroodle 141b296
fix CRLFs
toadlyBroodle a0de6c0
fix 01.md CRLFs
toadlyBroodle cf1d475
revert 57.md example formatting
toadlyBroodle 948c9eb
revert remaining 57.md formatting
toadlyBroodle ecbf7dd
revert 57.md changes and add poll_option references
toadlyBroodle e47f23a
remove windows newlines from 69.md
toadlyBroodle 1be5e63
Merge branch 'master' into master
toadlyBroodle dff65f4
remove ots requirement
toadlyBroodle 8268215
remove additional ots references
toadlyBroodle File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,119 @@ | ||
# Zap Poll event | ||
|
||
`draft` `optional` `author:toadlyBroodle` | ||
|
||
A zap poll note is a [nostr event](01.md) (kind `6969`) for conducting paid polls—herein referred to simply as '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. Polls may include multiple recipients which participants may choose from when zapping their votes. Polls may specify `value_maximum` and `value_minimum` satoshi valuations for determining which zaps are included in the tally. Polls may specify a `consensus_threshold` for assessing the state of consensus. Polls should specify a `closed_at` time, after which results be unblinded, closed to new votes, and the tally considered final. | ||
|
||
## Purpose | ||
|
||
The purpose of poll notes is to conduct quantitative public opinion polls over nostr by requiring voters pay to participate. By tying results to real satoshi valuations, nostr polls intend to provide superior signal compared to other free polling models. Imposing real monetary costs for participation should also discourage undesired attempts to sway results. | ||
|
||
Pollers may specify multiple `p` keys, to allow participants to choose which recipient they zap, regardless of their vote choice. The option for such distribution of funds should also incentivize participation by increasing voter optionality, poller authenticity, and legitimacy of results by mitigating certain unauthentic attack vectors. | ||
|
||
By including a `value_maximum` limit, polls can stop single 'whale' votes discounting many smaller 'shrimp' votes. Likewise, by including a `value_minimum` limit, polls can make automated low-value vote flooding attacks prohibitively expensive. However, both limits remain optional to allow for freedom in poll design. | ||
|
||
By setting `value_maximum` and `value_minimum` equal, a more traditional style poll may be designed, which weights each vote equal and limits each participant to a single vote. | ||
|
||
The optional `consensus_threshold` is intended as a simple 'measuring bar', defined as the minimum percentage for any single `poll_option`'s percentage of the total tally to attain poll consensus status. | ||
|
||
A careful balancing of all poll attributes should enable pollers to conduct tailored polls that deliver meaningful and valuable outcomes. | ||
|
||
## Zap poll format | ||
|
||
A poll event: | ||
* MUST specify 1 or more `p` tags, each including the same primary hosting relay | ||
* if an `e` tag is specified, it: | ||
* MUST include the same primary hosting relay URL as the `p` tags | ||
* MUST contain a primary description string, specified in the `content` field | ||
* MUST contain at least 2 `poll_option` tags, each specifying an index and a unique description string, formatted as below | ||
toadlyBroodle marked this conversation as resolved.
Show resolved
Hide resolved
|
||
* SHOULD specify a `closed_at` time: | ||
* when specified, MAY include a valid [`ots` tag](03.md), proving original poll publishing time | ||
* a `closed_at` value of null or 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 | ||
* `value_minimum` MUST be less than or equal to `value_maximum`, when both are specified | ||
* MAY include a `consensus_threshold` (0-100), representing a percentage threshold for any single vote option to achieve poll consensus | ||
toadlyBroodle marked this conversation as resolved.
Show resolved
Hide resolved
|
||
* a `consensus_threshold` of '0' indicates no threshold is specified. | ||
|
||
```json | ||
{ | ||
"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 the poll event>, <primary poll host relay URL>], | ||
["p", <32-bytes hex of the key>, <primary poll host relay URL>], | ||
["poll_option", "0", "poll option 0 description string"], | ||
["poll_option", "1", "poll option 1 description string"], | ||
["poll_option", "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"], | ||
], | ||
"ots": <base64-encoded OTS file data> | ||
"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 voting | ||
|
||
Poll options are voted on by sending [zap events](57.md) (referencing the original poll event's `e` and `p` values) that indicate their chosen vote option in a `poll_option` tag. To ensure all eligible votes are included in the tally, all `e` and `p` tags must specify the same primary hosting relay. | ||
|
||
A voting client: | ||
* SHOULD NOT allow submission of zap events with amounts greater than `value_maximum` (when specified) | ||
* SHOULD NOT allow submission of zap events with amounts less than `value_minimum` (when specified) | ||
* SHOULD NOT allow submission of zap events after `closed_at` time (when specified) | ||
* SHOULD NOT allow poll author to vote on their own polls | ||
* SHOULD hide tally results, until after a user has zapped the note | ||
|
||
## Zap vote format | ||
|
||
The zap request event (kind `9734`): | ||
* MUST specify an `e` tag that references the original poll event | ||
* MUST include a primary hosting relay URL in the `e` tag | ||
* MUST include at least 1 `p` tag specifying the recipient's key, chosen from the original poll event's list of keys | ||
* MUST include the same primary hosting relay URL in all `p` tags as is specified in the `e` tag | ||
* MUST include exactly 1 `poll_option` tag which references the chosen vote option by its corresponding index `n` | ||
|
||
```json | ||
... | ||
"tags": [ | ||
["e", <32-bytes hex of the id of the original poll event>, <primary poll host relay URL>], | ||
["p", <32-bytes hex of the recipient's key>, <primary poll host relay URL>], | ||
["poll_option", "n"], | ||
... | ||
], | ||
"ots": <base64-encoded OTS file data> | ||
... | ||
``` | ||
|
||
## Zap poll outcome | ||
|
||
Polls results are tallied by summing the exact satoshi values from all eligible zaps for each `poll_option`. The total tally is the sum of all individual `poll_option` tallies, and `poll_option` results are calculated by their percentage of the total tally value. | ||
|
||
To avoid ambiguity of results, strict adherence to the following rules is vital when tallying and rendering poll outcomes. | ||
|
||
A tallying client: | ||
* MUST ONLY include full satoshi value amounts in option tallies from ALL eligible zaps that meet ALL following criteria: | ||
* MUST ONLY tally zaps that reference the original poll event by its `e` tag value | ||
* MUST ONLY tally zaps sent to a `p` key specified in the original poll event | ||
* MUST NOT tally zaps from the poll author's `p` | ||
* MUST ONLY include zap amounts less than or equal to `value_maximum`, if specified | ||
* MUST ONLY include zap amounts greater than or equal to `value_minimum`, if specified | ||
* if both `value_maximum` and `value_minimum` are specified AND are equal: | ||
* MUST ONLY count 1 zap per option, per participant | ||
* if a `closed_at` time is specified, clients: | ||
* MUST ONLY tally zaps including a valid `created_at` time greater than or equal to the original poll event's `created_at` time | ||
* MUST ONLY tally zaps including a valid `created_at` time less than or equal to the original polle event's `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 show tally results to all note zappers, even if they haven't voted on an option | ||
* SHOULD publicly show 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 | ||
|
||
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. |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No reason to modify NIP-57 for this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is under optional MAY conditional list, for documentation purposes. It is a required field for zap-poll event zap requests: which is why it's included here. Still want it removed?