Ternary Voting Concept

@desrever mentioned that I had been playing with the concept of adjusting the way that voting works in Nu to move it from a binary to ternary (or quaternary, etc.) system.

I’ve been tackling a bunch of priority items over the last few weeks, so this feel by the wayside before I had a chance to formally present it. I still don’t have a lot of time to write extensively on it, but I also want to start to float the idea to the community to get feedback.

I have a gist with a markdown document that I’ll make updates to, but to make it easy for the community to read it, I’ll publish the current version here.

Ternary Voting Concept

Something that TomJoad posted last night, about concerns that data feeds could become “politicized” (aka “I won’t vote for you because I disagree with you, not because I disagree with what you said”) got me thinking.

Right now we have a binary system for voting. Either a block includes a vote in affirmation of something or it doesn’t, which is no different from voting “No”.

A more stable structure, at least in my current line of reasoning, would not be binary, but instead ternary – “Yes”, “Maybe”, “No”. This would only apply to motions and grant proposals, I see no benefit of extending it to rate voting (parking or burn) at this time.

The “Yes” votes would still be the only ones that counted towards passing a motion, grant, or rate, but if there was a third option it could be used to voice a form of “I like what you’re proposing but I have reservations…”

That way, someone proposing a motion would be able to see that over the last X blocks, 15% of the votes have been “Yes”, 25% have been “Maybe”, and the rest have been empty (proxy for “No”)

To the protocol this difference would not mean anything. To the community, it would be a way to quantify how well received a motion or grant proposal is. For example:


Over the last 10,000 blocks:

2450  YES   (24.50%)
7550  NULL  (75.50%)


2450  YES   (24.50%)
3890  MAYBE (38.90%)
2000  NO    (20.00%)
1660  NULL  (16.60%)

In both cases the motion or proposal would not be passed until it reached the proper level of consensus, but in the second case the Nu shareholders can see the nuanced way for how other shareholders are voting. Motions or proposal discussions could then be tailored by the initiator to understand why there are so many MAYBE votes and take steps to refine the motion or the proposal to address those concerns.


It actually should, because with your proposed change you are able to differentiate between NULL and NO. So the 16.6% in your example should actually be subtracted from the probability mass, leading to an accept/reject distribution of 29.38% vs 70.62%. In this case the blockspan rule would need to be changed from blocks to votes.

Pretty interesting idea. In the ancient Greece the people who didn’t give a shit were called idiots and were allowed to leave early from the town centre meetings. It somehow feels more natural to me that a person who does not vote will be excluded from calculating the results instead of included as if they voted NO.

1 Like

I like the enhanced consensus a ternary voting system would allow. Our voting structures will likely need to evolve in other ways too as pseudo-political structures form over time around data feeds. In the event of multiple strong “parties” voting for narrowly-entrenched interests, we may need to abandon 50%+1 votes and instead implement a set voting timeframe (like 2000 blocks) at regular intervals (eg. once per month) and a first-past-the-post voting system for a ballot of Custodians and Motions. Just like real elections with candidates.

1 Like

I usually like nuances, but in this case I’m a bit more binary. Although Null, No and Yes can be considered ternary. The differentiation between Null and No is useful. Not sure about the addition of ‘maybe’. I still wouldn’t know what to do with the maybes anyway, so struggle to see the value of it. Even without the maybes you would still see the null and no votes on a proposal. Either way you will have to find out somehow why people are not voting, voting ‘no’ or voting ‘maybe’ for your proposal.


You could map the MAYBE to 0, the NO to -1 and the YES to +1 and check if the last 5000 votes sum up to > 0. Generally we could achieve arbitrary precision by just replacing the vote by a real number between 0 and 1 which represents the agreement of the shareholder with the decision process. However, I think that the voting should be as simple as possible, so a discrete set of two or three choices (+ NULL) is probably the best.

I agree. My intent is to provide granularity without getting into a situation where the paradox of choice leads us to an untentable system.

“On a scale of 0 to 1,098 – tell us how important this motion is to you…”

If “Yes, NO, NULL” is a solution that meets this need and a “YES, MAYBE, NO, NULL” system is overkill, I’ll gladly support the move to the former.

Its a very interesting question and related to the opinion mining done by Google and Yelp etc. using their websites. I remember Google began with a 5 star rating and then switched to a binary system. Yelp still uses 5 classes. There are probably psychological studies out there which try to measure how much information people are able to encode in their feelings about agreement or disagreement.

A few commentaries and lines of research (out of lots and lots of other valid options) that are useful to this discussion when talking about choice theory and pychometrics:

1 Like

Thanks, very interesting sources.

What we did not consider so far in our discussion here is that we’re not facing singular votes, but a sequence of votes which can be modulated by the staking client to some extend. So let’s say I have N 10k coin outputs and the average network weight over the 10k blocks is W, then I will generate about 10k * N/W blocks within this week. Right now all these blocks contain all my votes, but if there is a motion where I am not so sure, then I could only vote on it in every second block, or even make a special set of votes for each of the N coin outputs. Although this isn’t possible in the client right now (to the best of my knowledge), it could be implemented easily without altering the protocol. Of course this vote frequency modulation can already be modeled with datafeeds, just not on coin output level.

So I think in our case the YES/NO/NULL solution is the best way to go, since MAYBE can be modeled over the voting frequency.


I always prefer the simple solutions to the complex ones if the outcome is similar.
Your idea of modulating the voting frequency is great!

Here some statistics regarding the voting with different stages of non-participation to discard votes. The aim of this analysis is to simulate the situation where we have an explicit NO vote by using the existing data.

Let’s first consider the NBT/PPC motion. In the following graphs the red curve shows the voting based on CDD and the blue curve shows voting based on count. The x-axis is the block number and the y-axis corresponds to the percentage of the vote. Labels with black arrows show the block where a motion (indicated by 5 letter prefix) was granted, labels with blue arrows show newly created motions. The data was sampled at block 215104.

Its interesting that this motion almost passed around block 115000. We also clearly see that the count model is much more stable than the CDD model, which is why it makes sense to abandon it. The massive NSR selloff around block 190k particularly shows this.

If we now don’t count empty motion sets, we get these curves:

We see that the motion would have passed over a longer period of time. Furthermore the rates are more stable and the CDD model is much closer to the count model.

Now, as mentioned above there might be staking clients which only contain some ancient motions in their voting set, but don’t actively participate in the voting anymore. So let’s have a closer look at the non-empty votes: We consider a set of motion as valid, iff the set is non-empty and either contains a motion that has not passed yet or has at least one motion that passed within the last N blocks. So all votes which only contain motions that already passed N blocks ago will be discarded. If we now plot the count voting rate at block 215104 for different N we get:

Several things are interesting in this graph. First, if we would require at least one active motion in the voting set, then the motion would have 37.20%. Secondly, after many NSR switched hands around block 190k we can see that many new votes (with low CDD) come in and this influx can be observed at the same location here (note that the x axis in this graph is reversed compared to the other graphs).

Now, if we say that active shareholders will add a motion within N = 50,000 blocks, which corresponds to about 5 weeks, then we arrive at this voting:

So here the motion would have been passed even more clearly. Interestingly the curves are very similar to the graph that only discards empty vote sets, and there only appears to be a vertical shift, i.e. a constant down vote pressure, that makes the difference in these curves. After block 190k, and CDD reduction, this offset is much smaller.

Let’s now consider the currently highly discussed open-source motion. This motion behaves quite different than the older PPC motion, but here also the empty votes seem to have a significant weight:

In total discarding empty votes here increased the rate from 26.66% (at block 215104) to 30.6%. The additionoal filtering based on the expired motions only had a small effect for 50k blocks, increasing the rate only to 30.65%. A possible explanation is that new shareholders are more in favor with this motion than older shareholders.

I hope you enjoyed reading the plots and I am looking forward to reading what you think.

EDIT: sorry that I took the previous version down, I had to correct/add some elements.


Given the divide between users on the open source motion I think a system that allows users to express their opinion on votes through the blockchain would provide a great benefit. I like the direction of this idea a lot.

@creon - I forgot to ask earlier, but what did you use to create those graphs?

matplotlib, in particular the pyplot package. It produces great plots and you see more and more academic publications with graphs that most likely were made with matplotlib.

Just what I was looking for. Thank you!


since the YES/NO/NULL model just has to many disadvantages, I thought we could take a deeper look into the frequency based model. I implemented this (very, very simple) approach, which now lets you apply a simple weight p (0 <= p <= 1) to each motion. There is no weight in the protocol, so what the client simply does is to pick the motion with probability p and to leave it out of the voting with probability (1 - p). In the QT client this looks like this:

So I don’t know how long to wait for the possibility to make a pull request into the main repo … it still doesn’t even have a public issue tracker, so even if you would like this feature, then I don’t see how to make it “officially” available to you, except @Ben takes over the repo. I can also make a client available soon, but my client usually contains some highly experimental code, so its not the best code base for regular users.

Now, just as a little teaser: The frequency based approach in general allows for an auto-voting system that does not rely on data feeds. This can be established by performing a weighted linear combinations over the voting of the last N blocks and to combine this with the own voting, if any exists. The weights of the signers can automatically be trained by making use of their derivatives and your own voting preferences, such that over time you will adapt to other signers when you don’t have a motion in your list. The model would be a so called spiking neural network, a comparably well studied model from pattern recognition. I’ll plan to create some data over the week to show you what I mean.

Good night.


When to put 0.75 and when to put 0.36 for example?

Put .75 if you only want to 3/4 vote for the motion. This way you can partially vote for things.

I see.