mirror of
https://github.com/ProvableHQ/leo.git
synced 2024-12-23 18:21:38 +03:00
commit vote example
This commit is contained in:
parent
491bc2271d
commit
ad139ec82d
2
examples/vote/.gitignore
vendored
Normal file
2
examples/vote/.gitignore
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
outputs/
|
||||
build/
|
93
examples/vote/README.md
Normal file
93
examples/vote/README.md
Normal file
@ -0,0 +1,93 @@
|
||||
# Leo Vote
|
||||
|
||||
## Summary
|
||||
|
||||
`vote.leo` is a general vote program.
|
||||
|
||||
Anyone can propose new proposals, proposer can issue tickets to the voters, and the voter can vote without exposing privacy (with the help of Aleo's flexible privacy mechanism).
|
||||
|
||||
Proposal information and statistical voting results is public, while the correlation between the voter and the vote is private(protected by zk).
|
||||
|
||||
This example is inspired by the [aleo-vote](https://github.com/zkprivacy/aleo-vote) example written by the Aleo community.
|
||||
|
||||
## Noteworthy Features
|
||||
|
||||
mappings etc.
|
||||
|
||||
|
||||
|
||||
## How to Run
|
||||
|
||||
To compile this Leo program, run:
|
||||
```bash
|
||||
leo build
|
||||
```
|
||||
|
||||
Make changes to `vote/inputs/vote.in` before running each command.
|
||||
|
||||
### Propose
|
||||
|
||||
Anyone can propose new proposals publicly by calling `propose` function.
|
||||
|
||||
Run `propose`:
|
||||
|
||||
```
|
||||
leo run propose
|
||||
```
|
||||
|
||||
Output sample:
|
||||
|
||||
```
|
||||
{
|
||||
owner: aleo1kkk52quhnxgn2nfrcd9jqk7c9x27c23f2wvw7fyzcze56yahvcgszgttu2.private,
|
||||
gates: 0u64.private,
|
||||
id: 2805252584833208809872967597325381727971256629741137995614832105537063464740field.private,
|
||||
info: {
|
||||
title: 2077160157502449938194577302446444field.private,
|
||||
content: 1452374294790018907888397545906607852827800436field.private,
|
||||
proposer: aleo1kkk52quhnxgn2nfrcd9jqk7c9x27c23f2wvw7fyzcze56yahvcgszgttu2.private
|
||||
},
|
||||
_nonce: 1639660347839832220966145410710039205878572956621820215177036061076060242021group.public
|
||||
}
|
||||
```
|
||||
|
||||
### Create Ticket
|
||||
|
||||
Proposer can create new tickets for proposed proposals.
|
||||
|
||||
Ticket is a record with `owner` and `pid`, it can be used to vote for the specific proposal - `pid`, and can only be used(voted) by the ticket `owner`.
|
||||
|
||||
Run `new_ticket`:
|
||||
|
||||
```
|
||||
aleo run new_ticket
|
||||
```
|
||||
|
||||
Output sample:
|
||||
|
||||
```
|
||||
{
|
||||
owner: aleo1kkk52quhnxgn2nfrcd9jqk7c9x27c23f2wvw7fyzcze56yahvcgszgttu2.private,
|
||||
gates: 0u64.private,
|
||||
pid: 2264670486490520844857553240576860973319410481267184439818180411609250173817field.private,
|
||||
_nonce: 1637267040221574073903539416642641433705357302885235345311606754421919550724group.public
|
||||
}
|
||||
```
|
||||
|
||||
### Vote
|
||||
|
||||
Ticket owner can use the ticket to vote `agree` / `disagree` with the specific proposal - `pid`.
|
||||
|
||||
As the ticket record can be used as an input privately, the voter's privacy is protected by zk.
|
||||
|
||||
Run `agree`:
|
||||
|
||||
```
|
||||
leo run agree
|
||||
```
|
||||
|
||||
Run `disagree`:
|
||||
|
||||
```
|
||||
leo run disagree
|
||||
```
|
27
examples/vote/inputs/vote.in
Normal file
27
examples/vote/inputs/vote.in
Normal file
@ -0,0 +1,27 @@
|
||||
// The program input for vote/src/main.leo
|
||||
[propose]
|
||||
info: ProposalInfo = ProposalInfo {
|
||||
title: 2077160157502449938194577302446444field,
|
||||
content: 1452374294790018907888397545906607852827800436field,
|
||||
proposer: aleo1kkk52quhnxgn2nfrcd9jqk7c9x27c23f2wvw7fyzcze56yahvcgszgttu2,
|
||||
};
|
||||
|
||||
[new_ticket]
|
||||
pid: field = 2264670486490520844857553240576860973319410481267184439818180411609250173817field;
|
||||
voter: address = aleo1kkk52quhnxgn2nfrcd9jqk7c9x27c23f2wvw7fyzcze56yahvcgszgttu2;
|
||||
|
||||
[agree]
|
||||
ticket: Ticket = Ticket {
|
||||
owner: aleo1kkk52quhnxgn2nfrcd9jqk7c9x27c23f2wvw7fyzcze56yahvcgszgttu2,
|
||||
gates: 0u64,
|
||||
pid: 2264670486490520844857553240576860973319410481267184439818180411609250173817field,
|
||||
_nonce: 1637267040221574073903539416642641433705357302885235345311606754421919550724group
|
||||
};
|
||||
|
||||
[disagree]
|
||||
ticket: Ticket = Ticket {
|
||||
owner: aleo1kkk52quhnxgn2nfrcd9jqk7c9x27c23f2wvw7fyzcze56yahvcgszgttu2,
|
||||
gates: 0u64,
|
||||
pid: 2264670486490520844857553240576860973319410481267184439818180411609250173817field,
|
||||
_nonce: 1637267040221574073903539416642641433705357302885235345311606754421919550724group
|
||||
};
|
10
examples/vote/program.json
Normal file
10
examples/vote/program.json
Normal file
@ -0,0 +1,10 @@
|
||||
{
|
||||
"program": "vote.aleo",
|
||||
"version": "0.0.0",
|
||||
"description": "",
|
||||
"development": {
|
||||
"private_key": "APrivateKey1zkpBDEpwdFWqxe1NdB9fxZxiX9LahJ3CdqchSs7FGZVggNw",
|
||||
"address": "aleo1kkk52quhnxgn2nfrcd9jqk7c9x27c23f2wvw7fyzcze56yahvcgszgttu2"
|
||||
},
|
||||
"license": "MIT"
|
||||
}
|
9
examples/vote/run.sh
Executable file
9
examples/vote/run.sh
Executable file
@ -0,0 +1,9 @@
|
||||
# Build the Leo vote program.
|
||||
(
|
||||
leo build || exit
|
||||
)
|
||||
|
||||
# Run the `propose` program function
|
||||
(
|
||||
leo run propose || exit
|
||||
)
|
96
examples/vote/src/main.leo
Normal file
96
examples/vote/src/main.leo
Normal file
@ -0,0 +1,96 @@
|
||||
// The 'vote.leo' program.
|
||||
|
||||
// Proposal details
|
||||
circuit ProposalInfo {
|
||||
title: field,
|
||||
content: field,
|
||||
proposer: address,
|
||||
}
|
||||
|
||||
// Proposal record records proposal info publicly
|
||||
record Proposal {
|
||||
owner: address,
|
||||
gates: u64,
|
||||
id: field, // todo: make public
|
||||
info: ProposalInfo, // todo make public
|
||||
}
|
||||
|
||||
// Save proposal info in public storage.
|
||||
mapping proposals: field => ProposalInfo;
|
||||
|
||||
// Privacy tickets to vote
|
||||
record Ticket {
|
||||
owner: address,
|
||||
gates: u64,
|
||||
pid: field,
|
||||
}
|
||||
|
||||
// Count the total tickets issued for each proposal
|
||||
mapping tickets: field => u64;
|
||||
|
||||
mapping agree_votes: field => u64;
|
||||
|
||||
mapping disagree_votes: field => u64;
|
||||
|
||||
// Propose a new proposal to vote on.
|
||||
@program
|
||||
function propose(public info: ProposalInfo) -> Proposal {
|
||||
// Authenticate proposer.
|
||||
console.assert_eq(self.caller, info.proposer);
|
||||
|
||||
// Generate a new proposal id.
|
||||
let id: field = BHP256::hash(info.title);
|
||||
|
||||
// Finalize the proposal id.
|
||||
finalize(id);
|
||||
|
||||
// Return a new record for the proposal.
|
||||
return Proposal {
|
||||
owner: self.caller,
|
||||
gates: 0u64,
|
||||
id,
|
||||
info,
|
||||
};
|
||||
}
|
||||
// Create a new proposal in the "tickets" mapping.
|
||||
finalize propose(public id: field) {
|
||||
increment(tickets, id, 0u64);
|
||||
}
|
||||
|
||||
// Create a new ticket to vote with.
|
||||
@program
|
||||
function new_ticket(
|
||||
public pid: field,
|
||||
public voter: address,
|
||||
) -> Ticket {
|
||||
// Finalize the proposal id for the ticket.
|
||||
finalize(pid);
|
||||
|
||||
return Ticket {
|
||||
owner: voter,
|
||||
gates: 0u64,
|
||||
pid,
|
||||
};
|
||||
}
|
||||
// Create a new ticket on a proposal in the "tickets" mapping.
|
||||
finalize new_ticket(public pid: field) {
|
||||
increment(tickets, pid, 1u64);
|
||||
}
|
||||
|
||||
// Vote to agree with a proposal.
|
||||
@program
|
||||
function agree(ticket: Ticket) {// Privately cast the vote.
|
||||
finalize(ticket.pid);
|
||||
}
|
||||
finalize agree(public pid: field) {// Publicly increment the number of agree votes.
|
||||
increment(agree_votes, pid, 1u64);
|
||||
}
|
||||
|
||||
// Vote to disagree with a proposal.
|
||||
@program
|
||||
function disagree(ticket: Ticket) {// Privately cast the vote.
|
||||
finalize(ticket.pid);
|
||||
}
|
||||
finalize disagree(pid: field) {// Publicly increment the number of disagree votes.
|
||||
increment(disagree_votes, pid, 1u64);
|
||||
}
|
Loading…
Reference in New Issue
Block a user