mirror of
https://github.com/ProvableHQ/leo.git
synced 2024-12-23 18:21:38 +03:00
commit
93307b1446
2
examples/vote/.gitignore
vendored
Normal file
2
examples/vote/.gitignore
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
outputs/
|
||||
build/
|
94
examples/vote/README.md
Normal file
94
examples/vote/README.md
Normal file
@ -0,0 +1,94 @@
|
||||
# Leo Vote
|
||||
|
||||
## Summary
|
||||
|
||||
`vote.leo` is a general vote program.
|
||||
|
||||
Anyone can issue new proposals,
|
||||
proposers can issue tickets to the voters,
|
||||
and voters can vote without exposing their identity.
|
||||
|
||||
This example is inspired by the [aleo-vote](https://github.com/zkprivacy/aleo-vote) example written by the Aleo community.
|
||||
|
||||
## Noteworthy Features
|
||||
|
||||
Voter identity is concealed by privately passing a voter's ballot into a function.
|
||||
Proposal information and voting results are revealed using the public `mapping` datatype in Leo.
|
||||
|
||||
## 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 issue a new proposal 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
|
||||
|
||||
Proposers 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
|
||||
|
||||
A ticket owner can use their ticket record to vote `agree` / `disagree` with the specific proposal - `pid`.
|
||||
|
||||
Since the ticket record can be used as an input privately, the voter's privacy is protected.
|
||||
|
||||
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"
|
||||
}
|
21
examples/vote/run.sh
Executable file
21
examples/vote/run.sh
Executable file
@ -0,0 +1,21 @@
|
||||
# Build the Leo vote program.
|
||||
(
|
||||
leo build || exit
|
||||
)
|
||||
|
||||
# Run the `propose` program function
|
||||
(
|
||||
leo run propose || exit
|
||||
)
|
||||
|
||||
# Run the `new_ticket` program function
|
||||
(
|
||||
leo run new_ticket || exit
|
||||
)
|
||||
|
||||
# Run the `agree` or `disagree` program function
|
||||
(
|
||||
leo run agree || exit
|
||||
# leo run disagree || 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,
|
||||
info: ProposalInfo,
|
||||
}
|
||||
|
||||
// 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