With a created account with a public census registered, any voter must follow this steps to perform a vote anonymously: 1. [✅ DONE] To perform a vote, the voter must generate a proof that proves that he or she is in the census anonymously, to be verified during the voting process. To generate this proof, the voter will need the census proof and census siblings, this information can be requested to the API using the `/censuses/{electionId}/proof/{address}` endpoint (as always). This request will response with the following interface: ```go type Census struct { CensusID types.HexBytes `json:"censusID,omitempty"` Type string `json:"type,omitempty"` Weight *types.BigInt `json:"weight,omitempty"` Size uint64 `json:"size,omitempty"` Valid bool `json:"valid,omitempty"` URI string `json:"uri,omitempty"` // proof stuff CensusRoot types.HexBytes `json:"censusRoot,omitempty"` CensusProof types.HexBytes `json:"censusProof,omitempty"` Key types.HexBytes `json:"key,omitempty"` Value types.HexBytes `json:"value,omitempty"` CensusSiblings []string `json:"censusSiblings,omitempty"` } ``` <small>All `types.HexBytes` params are BigInts encoded into a string.</small> 2. [⚠️ WIP] If he or she **has not a created account** in the Vochain (with a valid SIK registered), he or she must **create his or her Secret Identity Key** with a `RegisterSIKTx` tx **or create a new account** in the Vochain (providing a SIK during this process). The `RegisterSIKTx` Tx will be something similar to: ```protobuf message RegisterSIKTx { bytes electionId = 1; Proof censusProof = 2; bytes sik = 3; } ``` With following message `censusProof` Proof definition: ```protobuf message Proof { oneof payload { // Proof used for signed envelopes ProofGraviton graviton = 1; // Proof used for anonymous votes ProofIden3 iden3 = 2; // Proof used on EVM census based processes ProofEthereumStorage ethereumStorage = 3; // Proof used by oracles to update the census of EVM processes ProofEthereumAccount ethereumAccount = 4; // Proof Certification Authority ProofCA ca = 5; // Proof used for census using arbo ProofArbo arbo = 6; // zkSnark proof ProofZkSNARK zkSnark = 7; // Proof used in Minime token based census ProofMinime minimeStorage = 8; } } ``` Check all the protobuff definitions [here](https://github.com/vocdoni/dvote-protobuf/blob/master/src/vochain/vochain.proto). 3. [✅ DONE] To generate the proof, the voter also needs to prove that he or she has registered a valid sik into the vochain. This proof can be requested to the API using the `/siks/proof/{address}` endpoint. This endpoint will response with the same interface that the step 1 with some attributes ommited: ```go type Census struct { // [omitted useless attributes...] // // proof stuff CensusRoot types.HexBytes `json:"censusRoot,omitempty"` CensusProof types.HexBytes `json:"censusProof,omitempty"` Key types.HexBytes `json:"key,omitempty"` Value types.HexBytes `json:"value,omitempty"` CensusSiblings []string `json:"censusSiblings,omitempty"` } ``` <small>All `types.HexBytes` params are BigInts encoded into a string.</small> 4. (only SDK) He or she **must generate the vote proof** using SnarkJS and the information retrieved by the API combined with the information that the SDK already has: ```typescript export interface CircuitInputs { // public inputs electionId: string[]; // <-sdk(stored) nullifier: string; // <-sdk(generated) availableWeight: string; // <-api(step2) voteHash: string[]; // <-sdk(generated) sikRoot: string; // <-api(step3) censusRoot: string; // <-api(step2) // private inputs address: string; // <-sdk(stored) password: string; // <-sdk(const = "0") signature: string; // <-sdk(generated, payload="vocdoni-sik-payload") voteWeight: string; // <-sdk(const = availableWeight) sikSiblings: string[]; // <-api(step3) censusSiblings: string[]; // <-api(step2) } ``` Then send the vote (with the vote value and the generated proof) to the Vochain (this transaction could also change).