On this page
Abstract
A vote is an author-signed upvote, downvote, or vote cancellation on a comment. Votes are published to a community like any other publication (BSIP-4); the community counts them and reflects the totals in the comment’s update (BSIP-5). This BSIP defines the vote format, the rules a community applies when accepting a vote, and how votes are counted.
Motivation
Voting is the simplest publication type, but clients still need to agree on its exact shape — which comment it targets, the allowed values, and which fields are signed — and communities need to count votes the same way, so that vote counts mean the same thing across implementations.
Specification
The key words “MUST”, “MUST NOT”, “REQUIRED”, “SHALL”, “SHALL NOT”, “SHOULD”, “SHOULD NOT”, “RECOMMENDED”, “NOT RECOMMENDED”, “MAY”, and “OPTIONAL” in this document are to be interpreted as described in RFC 2119 and RFC 8174.
Fields
A vote is a JSON object with the common publication fields and two vote-specific fields:
commentCid— REQUIRED. The CID of the comment being voted on.vote— REQUIRED. One of1(upvote),-1(downvote), or0(cancel the author’s previous vote).
Votes are published inside a CHALLENGEREQUEST under the vote key (BSIP-4). Unlike
comments, accepted votes are not published individually; only their totals are.
Example vote:
{
"commentCid": "QmQwin4X1VAmELE5KsDHBfz3ZhaLiN8NcH663nvBJNMqUm",
"vote": -1,
"communityPublicKey": "12D3KooWBexQF4qDvyaxDgK4r2qPNk5z8s9b1eU5z2bnR6dExamPLe",
"communityName": "jokes.bso",
"author": { "name": "john.bso" },
"timestamp": 1728174027,
"protocolVersion": "1.0.0",
"signature": {
"type": "ed25519",
"signature": "<base64>",
"publicKey": "<base64, 32 bytes>",
"signedPropertyNames": ["author", "communityPublicKey", "communityName", "protocolVersion", "timestamp", "commentCid", "vote"]
}
}
Signing
A vote is signed by its author following BSIP-2, Signatures. Every field of
the vote except signature MUST be listed in signedPropertyNames. The convenience field
communityAddress is never signed and never appears on the wire.
Acceptance
In addition to the rules for every publication (BSIP-4), which reject votes on comments that do not exist, were removed or deleted, are pending approval or disapproved, or sit in an archived or locked thread, a community MUST reject a vote that:
- has
vote0when the same author has no effective vote on that comment; - is disallowed by the community’s
features(BSIP-3):noUpvotes,noDownvotes, or, for a post (depth0) or a reply,noPostUpvotes,noPostDownvotes,noReplyUpvotes, ornoReplyDownvotes.
Votes in a locked thread are rejected for everyone, moderators included.
Counting
An author is identified for counting by the IPNS name of the vote’s signature.publicKey. A community
MUST count at most one effective vote per author per comment: each accepted vote replaces that
author’s previous vote on the comment, and a vote of 0 leaves the author with no effective vote. The
comment update’s upvoteCount and downvoteCount (BSIP-5) are the numbers of
effective 1 and -1 votes. An author’s postScore and replyScore in the community
(BSIP-5) are the sums of upvotes minus downvotes on their
posts and replies.
Rationale
- A single
votefield with values1/0/-1keeps voting minimal and makes cancellation explicit rather than requiring a separate message type. - Author-signed votes, community-counted totals keep the trust model consistent: each vote is attributable to an author key, while the community is the authority on the aggregate it publishes.
- Not publishing individual votes keeps comment updates small and avoids exposing who voted for what.
Security Considerations
- One effective vote per author. Counting MUST be idempotent per author per comment, or an author could inflate a tally by republishing.
- Sybil resistance is the community’s job. A vote only proves that some keypair voted, and keypairs are free. Resistance to vote manipulation comes from the community’s anti-spam challenges and exclusion policy (BSIP-3), not from the vote format.
- Target binding.
commentCidis signed, so a vote cannot be moved to a different comment. - Replays. Within the five-minute timestamp window, resending an author’s earlier signed vote would replace their current one. A community SHOULD reject a vote whose signature it has already accepted (BSIP-4).
- Unverifiable totals. Because individual votes are not published, readers cannot audit a community’s counts; they are as trustworthy as the community that signs them.
Copyright
Copyright and related rights waived via CC0.