This blogpost describes voting system presented in NRS(Nxt Reference Software) 1.5 for application developers & experienced users. For simple use cases, wallet’s UI is self-explanatory and enough.
Different voting models supported: voting by account(1 account = 1 vote), balance(1 Nqt = 1 vote), asset balance(1 Qnt = 1 vote), or Monetary System token balance(1 currency unit = 1 vote)
Voting has finite predefined duration(finish block height, to say precisely)
Poll has minimum and maximum number of options to provide opinion for. E.g. choose from 2 to 5 options out of 8
Range is the vote parameter. E.g. give a rate from 0 to 10.
By combining number of options & range a lot of specific poll types could be done. E.g. binary poll is poll where range is from 0 to 1 (i.e. no or yes). UI can handles some ranges in such a meaningful way.
Anonymous voting ( https://bitbucket.org/JeanLucPicard/nxt/issue/176/private-polls ) is not implemented. It could be implemented with e.g. Blind signatures(https://en.wikipedia.org/wiki/Blind_signature) but it’s not known how to implement that on top of the blockchain. So it seems an anonymous voting could be implemented by trusted 3rd party services only.
Four voting models exist:
By account, 1 account = 1 Vote
By balance, 1 Nqt = 1 Vote (nqt, not nxt!)
By asset, 1 Asset Qnt = 1 Vote
By Monetary System token, 1 curency unit = 1 Vote
All the models could be enhanced by additional parameter, describing min balance in units(nqt/qnt/currency units).
Counting happens at the finish block height set during poll creation. And a vote being counted only if it satisfies poll parameters(min balance etc) at that finish height. Please note, a voter could vote with balance < min balance needed to vote(at height where vote has been sent), and that’s valid, but a vote will be counted only if balance >= threshold balance at poll finish height.
name - a poll’s title, no more than 100 characters
description - detailed poll description, no more than 1000 characters
options - possible options titles to choose from and give a rate to. Minimum one option, maximum 100.
votingModel - four possible values for by-account, by-balance, by-asset, by-token voting
finishHeight - block height in future poll is finishing and counting taking at. Minimum 1 block since inclusion height(so set current height + 2 at least), maximum 14*1440 blocks = 20160 blocks since inclusion height
minNumberOfOptions , maxNumberOfOptions - minimum and maximum number of options a voter can choose
minRangeValue , maxRangeValue - a vote’s value is within this range
minBalance - 0 by default. A vote is counted only if account balance @ finishing height (in nqts/qnts/MS tokens) >= minBalance. Mandatory for by-account voting (i.e. should be more than 0 in case of by-account voting)
minBalanceModel - used in by-account voting to distinguish which kind of units used for minbalance, nqt balance / assets / currency units. For last two options holdingId parameter is also required
- holdingId - for voting by assets or MS tokens, also used for minBalance in by-account voting
- Voting by asset could be started by anyone, not just asset/currency issuer or even owner
- Create poll
Use POST request to createPoll API call to create a new poll. Example with curl:
name - mandatory - poll title, not longer than 100 chars
description - mandatory - detailed poll description, max 1000 chars
finishHeight - mandatory - height of block when voting will be finished i.e. counted(should be > current one)
votingModel - mandatory - by-asset, by-account, or by-balance. see corresponding numeric value below
minBalance - mandatory for by-account voting, optional for other types - min amount of money or assets to vote, in nxt or qnt. by default 0(if skipped)
minBalanceModel - mandatory for by-account voting - what kind of tokens to use for vote threshold, nqt/qnt/ms token. See below for possible field values.
minNumberOfOptions - mandatory - min number of options to choose
maxNumberOfOptions - mandatory - max number of options to choose
minRangeValue - mandatory - min vote value possible, no more than 100
maxRangeValue - mandatory - max vote value possible, no less than -100
holdingId - mandatory in case of by-asset voting, could be also usedin addition with minBalance in by-account voting - asset or ms token id in unsigned form
option00,option01,option02,option03,…option99 - titles of corresponding options, please note parameter is always with two digits, starting with 00
Use following numerical values to set voting model:
1 2 3 4
Use following numerical values to set voting minBalanceModel:
1 2 3 4
- Vote casting
Use POST request to castVote API call to send your vote to the NRS. Example:
Parameters are pretty straightforward. Use poll’s transaction id as poll parameter value, use vote00..vote99 to provide weights for option00..option99 options.
Please note, poll should be included into the blockchain to vote on it.
- Get poll data
Use GET request getPoll to get poll data, e.g.
could returns something like
- Get poll results
Use GET request getPollResult to get poll results, e.g.
“finished” value is false, so voting still happens!
The request accepts some interesting parameters: votingModel , holding , minBalance , minBalanceModel - you can play with these parameters to see how results could be different depending on polls' input parameters(with the same set of voters).
- Get polls
Use POST request to getPolls :
There’s additional includeFinished parameter(self-explanatory). If account=0, all limited by indexes polls in the chain (active only if includeFinished=false) will be returned.
- Get vote(s) details
There’re two API calls to get vote details, getPollVote & getPollVotes . First one accepts poll & account parameters, while second accepts just poll (& firstIndex, lastIndex).
- Search polls
Use searchPoll to find relevant polls by text query. Example query with all the four parameters possible.
curl -d ‘query=cryptos&firstIndex=0&lastIndex=5&includeFinished=true’ http://localhost:6876/nxt?requestType=searchPolls
If poll contains less than 20 options, fee for it’s creation is 10 Nxt, otherwise each additional option costs 1 Nxt as well.
Vote fee is 1 Nxt.
There’s only one setting at the moment which could be overriden in nxt.properties:
1 2 3
Set the value to false if you run a lean node & don’t need for results of all the polls in the chain to be calculated & stored.
Use Cases & Application Ideas
Out of the scope of simple voting, there are a lot of possibilities Voting System provides:
- Distributed shareholders meetings (using assets as voting rights)
- Publicly verifiable community decisions (using e.g. Monetary System tokens as community currency)
Building consensus protocols on top of the blockchain with strong evidence of a consensus
(to be continued)
Internal details (for developers)
This section is for developers working with core, studying the NRS code, or writing apps working closely with the core(so using low-level Java API not HTTP, though that way isn’t recommended unless a developer knows why he’s doing that).
There are two kinds of attachments related to voting system: MessagingPollCreation & MessagingVoteCasting. Also please take a look PollBuilder helper implementing Builder pattern to create MessagingPollCreation objects:
1 2 3 4 5 6 7 8 9 10 11 12
There are two transaction types related to VS: Messaging.POLL_CREATION and Messaging.VOTE_CASTING.
Take a look to static methods of the Poll class to get data you want. E.g. getPoll(long id) returns poll by its id, getPollsByAccount returns polls created by an account specified etc.