Building a voting dapp

A question from @evan.id about building a voting dapp on slack:

Hey guys, if i want to build a blockstack app to count votes for example, where does the business logic to count votes really live?
For example, i want to build an app to let people create there own elections and let people vote in the election.
as I understand it, there’s a single page app, which displays decrypted data that the user stores in some service like dropbox (encrypted at rest).
But In order to know the state of the election, there needs to be some shared state to know who voted for what
Where should that shared state be stored in a blockstack application?

In an Ethereum dApp, that state is stored in some arbitrary contract, where each vote is recorded by an Ethereum transaction.

But in a blockstack app, would each users’s vote be stored in the storage method that they elect to use (blockstack, gaia)? If that’s true, then how does the application then access that data when the user is not authenticated?

Surely there needs to be a way to see who won an election without the entire user base being authenticated at the same time? (edited)

I just did some reading on multi-player storage. This clarified how users would expose public data to blockstack apps, but not where blockstack apps should store shared data relevant to the app. For example, if there are 10 members of my election app, where should the app store a reference to those 10 members so that it can count the votes they placed? Should this part be some centralized storage?
I did some searching and found a blockstack app called beacon that attempted to store shared state in atlas. is that the suggested model for such endeavors? (edited)

@jude writes:

the answer depends on what kind of election you’re doing. Do ballots need to be anonymous, or can they be publicly disclosed at a later date? How many voters per election, and how long do they last? Do you want an electoral history? Etc.
These questions aren’t specific to Gaia or Ethereum, but they have a significant effect on how they will be used?

@evan.id writes:

For the purposes of my voting app, it’s a high-stakes election. All votes are public record and verifiable (like a senate vote)
If you wanted to create an app to store senate votes on a bill, i’m not quite sure that I understand how Gaia could be used. If i have the ability to alter my data and change my vote, that won’t work. (edited)
So it appears Atlas would be the service to use? To store votes and elections as some kind of public record.

@jude writes:

Assuming the number of votes isn’t too big (100-ish), then each voter could cast their ballot, and then a “tally” process could scan the set of votes at a particular time, make a merkle tree out of them, and write the root to the blockchain (if you used Atlas, you could “batch” votes and bind each tally to the name of the election somewhat cheaply). This would make it possible for anyone to verify the vote tally at any subsequent point in time, and would make the votes nonrepudiable (edited)

The ballots themselves would be stored in multiplayer Gaia, so they could be crawled by the tallier. The merkle root anchored to the blockchain by Atlas represents the finalized count

@evan.id writes:

Interesting. I like that just the tally of the votes would be stored. The only concern I have with that approach is with the code that does the tally. Since that code would live in the client (i’m assuming), then i’m not sure how you could verify after the fact that the tally was done correctly. If the user can change their Gaia storage, and the app developer can update client code, is it possible to verify that a user did in fact vote “Y”, not “N”? If instead the votes themselves were stored in the blockchain, then any client could after the fact verify the outcome of the vote.

@jude writes:

That’s a valid but solvable concern. Since the number of voters is small, it’s reasonable to have each voter run the tally program and announce their vote tally themselves. The tally program would fetch and store the signed votes of each voter, and verify with it’s 99 other peers that they all have the same view. Then as long as fewer than 34/100 voters and their Gaia hubs and tally programs are malicious, you’d be able to audit the vote at any later point in time. You wouldn’t even need to write to Atlas in this case, since the 67 honest voters would be able to survive Byzantine faults in the dishonest minority.

To tolerate fail-stop Gaia hubs, you could have the 100 voters operate a shared Blockstack subdomain registrar, and give each voter a subdomain. Then, voters store their ballots to Gaia, but store the signed hash of the ballot in their respective subdomain records. To certify the vote, the subdomain registrar issues a NAME_UPDATE to anchor the state of all voters’ ballots to the blockchain. This preserves the results of the votes in an auditable way without requiring all Gaia hubs to continue holding state—only one host needs to archive the ballots for each vote (and it can be anyone, even non-voters, since the signed ballot hashes are already certified).

Thanks @larry! Was just about to do this.

Thanks for that very thoughtful response. I’m not going to lie - some of that went over my head. But here’s my attempt at parsing it…

In the first paragraph you mention an off-chain solution where fewer than 1/3 of the participants are bad actors. The program syncs with other peers in the election to come to a common understanding about the state of the election.

In the second paragraph you discuss a hybrid on/off chain solution where participants store their own signed ballot hashes in a subdomain registrar that is rooted in the blockchain, and the reference to the participants in the election is stored off-chain. But I suspect that even the reference to the participants could be stored on chain as well.

Is this understanding correct? I tend to gravitate toward the solution you provided in the second paragraph. It’s not hard to imagine a situation where more than 1/3 of a voting population conspire to cheat, especially when elections are small.

Is blockstack opinionated about how these various blockstack APIs are used in building dApps? We’ve discussed using subdomain-registrar in order to store the state of election ballots, which probably was outside the design scope of that service. Does blockstack care about that? What would you say about dApps that mix Ethereum smart contracts with the common blockstack services like identity and storage? Is that an encouraged design pattern?

Just trying to get a pulse on how you guys are thinking about design decisions like this. Thanks for the help and great work building Blockstack.

In the first paragraph you mention an off-chain solution where fewer than 1/3 of the participants are bad actors. The program syncs with other peers in the election to come to a common understanding about the state of the election.

That’s the gist of it. Each peer runs the program, and through a BFT agreement protocol, each correct peer can calculate the state of the election as long as 1/3 or fewer are faulty.

In the second paragraph you discuss a hybrid on/off chain solution where participants store their own signed ballot hashes in a subdomain registrar that is rooted in the blockchain, and the reference to the participants in the election is stored off-chain. But I suspect that even the reference to the participants could be stored on chain as well.

The ballot hashes and voter IDs go into the subdomain registrar (i.e. each voter is a subdomain). The hash of all those records goes into the blockchain via a NAME_UPDATE transaction, so the cost of an election is only one transaction.

The serialized set of ballot hashes and voter IDs are replicated to each Blockstack node as a zone file (via its Atlas network), so this information never disappears. See this document for details.

Is blockstack opinionated about how these various blockstack APIs are used in building dApps? We’ve discussed using subdomain-registrar in order to store the state of election ballots, which probably was outside the design scope of that service. Does blockstack care about that? What would you say about dApps that mix Ethereum smart contracts with the common blockstack services like identity and storage? Is that an encouraged design pattern?

In general, Blockstack does not care about what API(s) you use, and several teams are using Ethereum tokens in conjunction with Blockstack identity and storage :slight_smile: Blockstack dapps are implemented as Web apps–they can use anything that has a Javascript library (including web3.js). I’d encourage you to use whatever technology makes sense for the problem you’re trying to solve.

However, just to make sure I’m not leading you astray, if you’re asking this because you’re working on one of our bounty programs (like the call for social networks), I should warn you in advance that those bounties are only awarded to candidates that make use of Blockstack in the prescribed manner. For example, a recipient of the call for social networks bounty would have to use Blockstack for hosting and manipulating the social network :wink: