From df2cb3475f5ad36f13fcd4dea82be34761cc70c4 Mon Sep 17 00:00:00 2001 From: Roman Date: Sun, 24 Mar 2024 10:19:06 +0200 Subject: [PATCH 1/2] deprecate off-chain voting, refactor paths --- internal/service/api/handlers/get_voting.go | 2 + internal/service/api/handlers/register.go | 225 --------------- internal/service/api/handlers/vote.go | 261 ++++++++++++------ .../service/api/handlers/vote_deprecated.go | 122 ++++++++ internal/service/api/requests/register.go | 33 --- internal/service/api/requests/vote.go | 25 +- .../service/api/requests/vote_deprecated.go | 29 ++ internal/service/router.go | 3 +- 8 files changed, 341 insertions(+), 359 deletions(-) delete mode 100644 internal/service/api/handlers/register.go create mode 100644 internal/service/api/handlers/vote_deprecated.go delete mode 100644 internal/service/api/requests/register.go create mode 100644 internal/service/api/requests/vote_deprecated.go diff --git a/internal/service/api/handlers/get_voting.go b/internal/service/api/handlers/get_voting.go index a2bfa2d..4b261b8 100644 --- a/internal/service/api/handlers/get_voting.go +++ b/internal/service/api/handlers/get_voting.go @@ -120,6 +120,8 @@ func GetVoting(w http.ResponseWriter, r *http.Request) { }) } response.Data.Attributes.Votes = &votesToAdd + + // TODO check on-chain status via nullifier } ape.Render(w, response) diff --git a/internal/service/api/handlers/register.go b/internal/service/api/handlers/register.go deleted file mode 100644 index 391aaab..0000000 --- a/internal/service/api/handlers/register.go +++ /dev/null @@ -1,225 +0,0 @@ -package handlers - -import ( - "bytes" - "encoding/hex" - "fmt" - "github.com/debabky/voting-svc/internal/data" - "math/big" - "net/http" - "strings" - - "github.com/debabky/voting-svc/internal/contracts" - "github.com/debabky/voting-svc/internal/service/api/requests" - "github.com/debabky/voting-svc/resources" - "github.com/ethereum/go-ethereum/accounts/abi/bind" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/core/types" - "github.com/ethereum/go-ethereum/crypto" - "gitlab.com/distributed_lab/ape" - "gitlab.com/distributed_lab/ape/problems" - "gitlab.com/distributed_lab/logan/v3/errors" -) - -func Register(w http.ResponseWriter, r *http.Request) { - req, err := requests.NewRegisterRequest(r) - if err != nil { - Log(r).WithError(err).Error("failed to get request") - ape.RenderErr(w, problems.BadRequest(err)...) - return - } - - pubKey, s, n, a, b, c, err := getRegistrationData(req) - if err != nil { - Log(r).WithError(err).Error("failed to get registration data") - ape.RenderErr(w, problems.InternalError()) - return - } - - NetworkConfig(r).LockNonce() - defer NetworkConfig(r).UnlockNonce() - - // FIXME rework for voting contract - tx, err := RegistrationContract(r).Register( - &bind.TransactOpts{ - NoSend: true, - From: crypto.PubkeyToAddress(NetworkConfig(r).PrivateKey.PublicKey), - Signer: func(addr common.Address, tx *types.Transaction) (*types.Transaction, error) { - return types.SignTx( - tx, types.NewCancunSigner(NetworkConfig(r).ChainID), NetworkConfig(r).PrivateKey, - ) - }, - }, - pubKey, s, n, - contracts.VerifierHelperProofPoints{ - A: a, - B: b, - C: c, - }, - big.NewInt(req.Data.Timestamp), - ) - if err != nil { - Log(r).WithError(err).Error("failed to check transaction validity") - ape.RenderErr(w, problems.InternalError()) - return - } - - if err := MasterQ(r).Transaction(func(db data.MasterQ) error { - if err := db.RegistrationsQ().Insert(data.Registration{ - // TODO - }); err != nil { - return errors.Wrap(err, "failed to insert registration") - } - - tx, err = RegistrationContract(r).Register( - &bind.TransactOpts{ - From: crypto.PubkeyToAddress(NetworkConfig(r).PrivateKey.PublicKey), - Nonce: new(big.Int).SetUint64(NetworkConfig(r).Nonce()), - Signer: func(addr common.Address, tx *types.Transaction) (*types.Transaction, error) { - return types.SignTx( - tx, types.NewCancunSigner(NetworkConfig(r).ChainID), NetworkConfig(r).PrivateKey, - ) - }, - }, - pubKey, s, n, - contracts.VerifierHelperProofPoints{ - A: a, - B: b, - C: c, - }, - big.NewInt(req.Data.Timestamp), - ) - if err != nil { - if strings.Contains(err.Error(), "nonce") { - if err := NetworkConfig(r).ResetNonce(EthClient(r)); err != nil { - ape.RenderErr(w, problems.InternalError()) - return errors.Wrap(err, "failed to reset nonce") - } - - tx, err = RegistrationContract(r).Register( - &bind.TransactOpts{ - From: crypto.PubkeyToAddress(NetworkConfig(r).PrivateKey.PublicKey), - Nonce: new(big.Int).SetUint64(NetworkConfig(r).Nonce()), - Signer: func(addr common.Address, tx *types.Transaction) (*types.Transaction, error) { - return types.SignTx( - tx, types.NewCancunSigner(NetworkConfig(r).ChainID), NetworkConfig(r).PrivateKey, - ) - }, - }, - pubKey, s, n, - contracts.VerifierHelperProofPoints{ - A: a, - B: b, - C: c, - }, - big.NewInt(req.Data.Timestamp), - ) - if err != nil { - ape.RenderErr(w, problems.InternalError()) - return errors.Wrap(err, "failed to send registration tx") - } - } else { - ape.RenderErr(w, problems.InternalError()) - return errors.Wrap(err, "failed to send transaction") - } - } - return nil - }); err != nil { - Log(r).WithError(err).Error("failed to perform SQL transaction") - return - } - - NetworkConfig(r).IncrementNonce() - - ape.Render(w, resources.Tx{ - Key: resources.Key{ - ID: tx.Hash().String(), - Type: resources.TXS, - }, - Attributes: resources.TxAttributes{ - TxHash: tx.Hash().String(), - }, - }) -} - -func getRegistrationData(req requests.RegisterRequest) ( - [32]byte, []byte, []byte, [2]*big.Int, [2][2]*big.Int, [2]*big.Int, error, -) { - pubKey, err := hex.DecodeString(req.Data.InternalPublicKey) - if err != nil { - return [32]byte{}, nil, nil, [2]*big.Int{}, [2][2]*big.Int{}, [2]*big.Int{}, errors.Wrap(err, "failed to decode hex") - } - pubKeyArr := [32]byte{} - copy(pubKeyArr[:], pubKey) - - s, err := hex.DecodeString(req.Data.Signature.S) - if err != nil { - return [32]byte{}, nil, nil, [2]*big.Int{}, [2][2]*big.Int{}, [2]*big.Int{}, errors.Wrap(err, "failed to decode hex") - } - - n, err := hex.DecodeString(req.Data.Signature.N) - if err != nil { - return [32]byte{}, nil, nil, [2]*big.Int{}, [2][2]*big.Int{}, [2]*big.Int{}, errors.Wrap(err, "failed to decode hex") - } - - a, b, c, err := getProofPoints(req) - if err != nil { - return [32]byte{}, nil, nil, [2]*big.Int{}, [2][2]*big.Int{}, [2]*big.Int{}, errors.Wrap(err, "failed to get proof points") - } - - return pubKeyArr, s, n, a, b, c, nil -} - -func getProofPoints(req requests.RegisterRequest) ([2]*big.Int, [2][2]*big.Int, [2]*big.Int, error) { - a, err := stringsToArrayBigInt(req.Data.Proof.Proof.A) - if err != nil { - return [2]*big.Int{}, [2][2]*big.Int{}, [2]*big.Int{}, errors.Wrap(err, "failed to convert stings to big ints") - } - resB := [2][2]*big.Int{} - for i, b := range req.Data.Proof.Proof.B { - bi, err := stringsToArrayBigInt(b) - if err != nil { - return [2]*big.Int{}, [2][2]*big.Int{}, [2]*big.Int{}, errors.Wrap(err, "failed to convert stings to big ints") - } - biArr := [2]*big.Int{} - copy(biArr[:], bi) - resB[i] = biArr - } - c, err := stringsToArrayBigInt(req.Data.Proof.Proof.C) - if err != nil { - return [2]*big.Int{}, [2][2]*big.Int{}, [2]*big.Int{}, errors.Wrap(err, "failed to convert stings to big ints") - } - - resA := [2]*big.Int{} - copy(resA[:], a) - - resC := [2]*big.Int{} - copy(resC[:], c) - - return resA, resB, resC, nil -} - -func stringsToArrayBigInt(publicSignals []string) ([]*big.Int, error) { - p := make([]*big.Int, 0, len(publicSignals)) - for _, s := range publicSignals { - sb, err := stringToBigInt(s) - if err != nil { - return nil, err - } - p = append(p, sb) - } - return p, nil -} - -func stringToBigInt(s string) (*big.Int, error) { - base := 10 - if bytes.HasPrefix([]byte(s), []byte("0x")) { - base = 16 - s = strings.TrimPrefix(s, "0x") - } - n, ok := new(big.Int).SetString(s, base) - if !ok { - return nil, fmt.Errorf("can not parse string to *big.Int: %s", s) - } - return n, nil -} diff --git a/internal/service/api/handlers/vote.go b/internal/service/api/handlers/vote.go index 3fb3cd8..3aec079 100644 --- a/internal/service/api/handlers/vote.go +++ b/internal/service/api/handlers/vote.go @@ -1,12 +1,21 @@ package handlers import ( + "bytes" + "encoding/hex" "fmt" + "github.com/debabky/voting-svc/internal/data" + "math/big" "net/http" - "time" + "strings" - "github.com/debabky/voting-svc/internal/data" + "github.com/debabky/voting-svc/internal/contracts" "github.com/debabky/voting-svc/internal/service/api/requests" + "github.com/debabky/voting-svc/resources" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/crypto" "gitlab.com/distributed_lab/ape" "gitlab.com/distributed_lab/ape/problems" "gitlab.com/distributed_lab/logan/v3/errors" @@ -15,120 +24,202 @@ import ( func Vote(w http.ResponseWriter, r *http.Request) { req, err := requests.NewVoteRequest(r) if err != nil { - Log(r).WithError(err).Error("failed to get vote request") + Log(r).WithError(err).Error("failed to get request") ape.RenderErr(w, problems.BadRequest(err)...) return } - voting, err := MasterQ(r).VotingsQ().New(). - FilterBy("id", TokenClaims(r).VotingID). - Get() + pubKey, s, n, a, b, c, err := getRegistrationData(req) if err != nil { - Log(r).WithError(err).Error("failed to get voting") + Log(r).WithError(err).Error("failed to get registration data") ape.RenderErr(w, problems.InternalError()) return } - if voting == nil { - Log(r).Error("voting not found") - ape.RenderErr(w, problems.BadRequest(errors.New("voting not found"))...) - return - } - - if voting.ActiveUntil.Before(time.Now().UTC()) { - Log(r).Error("voting ended") - ape.RenderErr(w, problems.BadRequest(errors.New("voting ended"))...) - return - } - // if there are no votes or multiple votes for non-ranked voting - if len(req.Data.Attributes.Votes) < 1 || (voting.Type != data.RankedVoting && len(req.Data.Attributes.Votes) != 1) { - Log(r).Error("insufficient number of votes") - ape.RenderErr(w, problems.BadRequest(errors.New("insufficient number of votes"))...) - return - } + NetworkConfig(r).LockNonce() + defer NetworkConfig(r).UnlockNonce() - registration, err := MasterQ(r).RegistrationsQ().New(). - FilterBy("voting_id", TokenClaims(r).VotingID). - FilterBy("nullifier", TokenClaims(r).Nullifier). - Get() + // FIXME rework for voting contract + tx, err := RegistrationContract(r).Register( + &bind.TransactOpts{ + NoSend: true, + From: crypto.PubkeyToAddress(NetworkConfig(r).PrivateKey.PublicKey), + Signer: func(addr common.Address, tx *types.Transaction) (*types.Transaction, error) { + return types.SignTx( + tx, types.NewCancunSigner(NetworkConfig(r).ChainID), NetworkConfig(r).PrivateKey, + ) + }, + }, + pubKey, s, n, + contracts.VerifierHelperProofPoints{ + A: a, + B: b, + C: c, + }, + big.NewInt(req.Data.Timestamp), + ) if err != nil { - Log(r).WithError(err).Error("failed to get registration") + Log(r).WithError(err).Error("failed to check transaction validity") ape.RenderErr(w, problems.InternalError()) return } - if registration == nil { - Log(r).Error("registration not found") - ape.RenderErr(w, problems.BadRequest(errors.New("registration not found"))...) + + if err := MasterQ(r).Transaction(func(db data.MasterQ) error { + if err := db.RegistrationsQ().Insert(data.Registration{ + // TODO + }); err != nil { + return errors.Wrap(err, "failed to insert registration") + } + + tx, err = RegistrationContract(r).Register( + &bind.TransactOpts{ + From: crypto.PubkeyToAddress(NetworkConfig(r).PrivateKey.PublicKey), + Nonce: new(big.Int).SetUint64(NetworkConfig(r).Nonce()), + Signer: func(addr common.Address, tx *types.Transaction) (*types.Transaction, error) { + return types.SignTx( + tx, types.NewCancunSigner(NetworkConfig(r).ChainID), NetworkConfig(r).PrivateKey, + ) + }, + }, + pubKey, s, n, + contracts.VerifierHelperProofPoints{ + A: a, + B: b, + C: c, + }, + big.NewInt(req.Data.Timestamp), + ) + if err != nil { + if strings.Contains(err.Error(), "nonce") { + if err := NetworkConfig(r).ResetNonce(EthClient(r)); err != nil { + ape.RenderErr(w, problems.InternalError()) + return errors.Wrap(err, "failed to reset nonce") + } + + tx, err = RegistrationContract(r).Register( + &bind.TransactOpts{ + From: crypto.PubkeyToAddress(NetworkConfig(r).PrivateKey.PublicKey), + Nonce: new(big.Int).SetUint64(NetworkConfig(r).Nonce()), + Signer: func(addr common.Address, tx *types.Transaction) (*types.Transaction, error) { + return types.SignTx( + tx, types.NewCancunSigner(NetworkConfig(r).ChainID), NetworkConfig(r).PrivateKey, + ) + }, + }, + pubKey, s, n, + contracts.VerifierHelperProofPoints{ + A: a, + B: b, + C: c, + }, + big.NewInt(req.Data.Timestamp), + ) + if err != nil { + ape.RenderErr(w, problems.InternalError()) + return errors.Wrap(err, "failed to send registration tx") + } + } else { + ape.RenderErr(w, problems.InternalError()) + return errors.Wrap(err, "failed to send transaction") + } + } + return nil + }); err != nil { + Log(r).WithError(err).Error("failed to perform SQL transaction") return } - votesCount, err := MasterQ(r).VotesQ().New(). - FilterBy("voting_id", TokenClaims(r).VotingID). - FilterBy("nullifier", TokenClaims(r).Nullifier). - Count() + NetworkConfig(r).IncrementNonce() + + ape.Render(w, resources.Tx{ + Key: resources.Key{ + ID: tx.Hash().String(), + Type: resources.TXS, + }, + Attributes: resources.TxAttributes{ + TxHash: tx.Hash().String(), + }, + }) +} + +func getRegistrationData(req requests.VoteRequest) ( + [32]byte, []byte, []byte, [2]*big.Int, [2][2]*big.Int, [2]*big.Int, error, +) { + pubKey, err := hex.DecodeString(req.Data.InternalPublicKey) if err != nil { - Log(r).WithError(err).Error("failed to get votes") - ape.RenderErr(w, problems.InternalError()) - return + return [32]byte{}, nil, nil, [2]*big.Int{}, [2][2]*big.Int{}, [2]*big.Int{}, errors.Wrap(err, "failed to decode hex") } - if votesCount > 0 { - Log(r).Error("nullifier has already been used") - ape.RenderErr(w, problems.BadRequest(errors.New("nullifier has already been used"))...) - return + pubKeyArr := [32]byte{} + copy(pubKeyArr[:], pubKey) + + s, err := hex.DecodeString(req.Data.Signature.S) + if err != nil { + return [32]byte{}, nil, nil, [2]*big.Int{}, [2][2]*big.Int{}, [2]*big.Int{}, errors.Wrap(err, "failed to decode hex") } - switch voting.Type { - case data.RankedVoting: - if err := addRankedVotes(r, voting, req.Data.Attributes.Votes); err != nil { - Log(r).WithError(err).Error("failed to add ranked votes") - ape.RenderErr(w, problems.InternalError()) - return - } - default: - Log(r).Error(fmt.Sprintf("%d is not supported voting type", voting.Type)) - ape.RenderErr(w, problems.InternalError()) - return + n, err := hex.DecodeString(req.Data.Signature.N) + if err != nil { + return [32]byte{}, nil, nil, [2]*big.Int{}, [2][2]*big.Int{}, [2]*big.Int{}, errors.Wrap(err, "failed to decode hex") } -} -func addRankedVotes(r *http.Request, voting *data.Voting, votes []requests.Vote) error { - passedOptions := make([]string, 0) - for _, vote := range votes { - passedOptions = append(passedOptions, vote.VotingOption) + a, b, c, err := getProofPoints(req) + if err != nil { + return [32]byte{}, nil, nil, [2]*big.Int{}, [2][2]*big.Int{}, [2]*big.Int{}, errors.Wrap(err, "failed to get proof points") } - options, err := MasterQ(r).VotingOptionsQ(). - FilterBy("voting_id", voting.ID.String()). - FilterBy("name", passedOptions). - Select() + return pubKeyArr, s, n, a, b, c, nil +} + +func getProofPoints(req requests.VoteRequest) ([2]*big.Int, [2][2]*big.Int, [2]*big.Int, error) { + a, err := stringsToArrayBigInt(req.Data.Proof.Proof.A) if err != nil { - return errors.Wrap(err, "failed to get voting options") + return [2]*big.Int{}, [2][2]*big.Int{}, [2]*big.Int{}, errors.Wrap(err, "failed to convert stings to big ints") } - if len(options) == 0 { - return errors.New("voting options not found") + resB := [2][2]*big.Int{} + for i, b := range req.Data.Proof.Proof.B { + bi, err := stringsToArrayBigInt(b) + if err != nil { + return [2]*big.Int{}, [2][2]*big.Int{}, [2]*big.Int{}, errors.Wrap(err, "failed to convert stings to big ints") + } + biArr := [2]*big.Int{} + copy(biArr[:], bi) + resB[i] = biArr } - - if len(options) != len(votes) { - return errors.New("votes number is not equal to options number") + c, err := stringsToArrayBigInt(req.Data.Proof.Proof.C) + if err != nil { + return [2]*big.Int{}, [2][2]*big.Int{}, [2]*big.Int{}, errors.Wrap(err, "failed to convert stings to big ints") } - if err := MasterQ(r).Transaction(func(db data.MasterQ) error { - for i, passedOption := range passedOptions { - rank := int64(i + 1) - - if err := db.VotesQ().Insert(data.Vote{ - VotingID: TokenClaims(r).VotingID, - VotingOption: passedOption, - Nullifier: TokenClaims(r).Nullifier, - Rank: &rank, - }); err != nil { - return errors.Wrap(err, "failed to insert vote to the database") - } + resA := [2]*big.Int{} + copy(resA[:], a) + + resC := [2]*big.Int{} + copy(resC[:], c) + + return resA, resB, resC, nil +} + +func stringsToArrayBigInt(publicSignals []string) ([]*big.Int, error) { + p := make([]*big.Int, 0, len(publicSignals)) + for _, s := range publicSignals { + sb, err := stringToBigInt(s) + if err != nil { + return nil, err } - return nil - }); err != nil { - return errors.Wrap(err, "failed to perform SQL transaction") + p = append(p, sb) } + return p, nil +} - return nil +func stringToBigInt(s string) (*big.Int, error) { + base := 10 + if bytes.HasPrefix([]byte(s), []byte("0x")) { + base = 16 + s = strings.TrimPrefix(s, "0x") + } + n, ok := new(big.Int).SetString(s, base) + if !ok { + return nil, fmt.Errorf("can not parse string to *big.Int: %s", s) + } + return n, nil } diff --git a/internal/service/api/handlers/vote_deprecated.go b/internal/service/api/handlers/vote_deprecated.go new file mode 100644 index 0000000..3d53b56 --- /dev/null +++ b/internal/service/api/handlers/vote_deprecated.go @@ -0,0 +1,122 @@ +package handlers + +//func VoteDeprecated(w http.ResponseWriter, r *http.Request) { +// req, err := requests.NewVoteRequest(r) +// if err != nil { +// Log(r).WithError(err).Error("failed to get vote request") +// ape.RenderErr(w, problems.BadRequest(err)...) +// return +// } +// +// voting, err := MasterQ(r).VotingsQ().New(). +// FilterBy("id", TokenClaims(r).VotingID). +// Get() +// if err != nil { +// Log(r).WithError(err).Error("failed to get voting") +// ape.RenderErr(w, problems.InternalError()) +// return +// } +// if voting == nil { +// Log(r).Error("voting not found") +// ape.RenderErr(w, problems.BadRequest(errors.New("voting not found"))...) +// return +// } +// +// if voting.ActiveUntil.Before(time.Now().UTC()) { +// Log(r).Error("voting ended") +// ape.RenderErr(w, problems.BadRequest(errors.New("voting ended"))...) +// return +// } +// +// // if there are no votes or multiple votes for non-ranked voting +// if len(req.Data.Attributes.Votes) < 1 || (voting.Type != data.RankedVoting && len(req.Data.Attributes.Votes) != 1) { +// Log(r).Error("insufficient number of votes") +// ape.RenderErr(w, problems.BadRequest(errors.New("insufficient number of votes"))...) +// return +// } +// +// registration, err := MasterQ(r).RegistrationsQ().New(). +// FilterBy("voting_id", TokenClaims(r).VotingID). +// FilterBy("nullifier", TokenClaims(r).Nullifier). +// Get() +// if err != nil { +// Log(r).WithError(err).Error("failed to get registration") +// ape.RenderErr(w, problems.InternalError()) +// return +// } +// if registration == nil { +// Log(r).Error("registration not found") +// ape.RenderErr(w, problems.BadRequest(errors.New("registration not found"))...) +// return +// } +// +// votesCount, err := MasterQ(r).VotesQ().New(). +// FilterBy("voting_id", TokenClaims(r).VotingID). +// FilterBy("nullifier", TokenClaims(r).Nullifier). +// Count() +// if err != nil { +// Log(r).WithError(err).Error("failed to get votes") +// ape.RenderErr(w, problems.InternalError()) +// return +// } +// if votesCount > 0 { +// Log(r).Error("nullifier has already been used") +// ape.RenderErr(w, problems.BadRequest(errors.New("nullifier has already been used"))...) +// return +// } +// +// switch voting.Type { +// case data.RankedVoting: +// if err := addRankedVotes(r, voting, req.Data.Attributes.Votes); err != nil { +// Log(r).WithError(err).Error("failed to add ranked votes") +// ape.RenderErr(w, problems.InternalError()) +// return +// } +// default: +// Log(r).Error(fmt.Sprintf("%d is not supported voting type", voting.Type)) +// ape.RenderErr(w, problems.InternalError()) +// return +// } +//} + +//func addRankedVotes(r *http.Request, voting *data.Voting, votes []requests.Vote) error { +// passedOptions := make([]string, 0) +// for _, vote := range votes { +// passedOptions = append(passedOptions, vote.VotingOption) +// } +// +// options, err := MasterQ(r).VotingOptionsQ(). +// FilterBy("voting_id", voting.ID.String()). +// FilterBy("name", passedOptions). +// Select() +// if err != nil { +// return errors.Wrap(err, "failed to get voting options") +// } +// if len(options) == 0 { +// return errors.New("voting options not found") +// } +// +// if len(options) != len(votes) { +// return errors.New("votes number is not equal to options number") +// } +// +// if err := MasterQ(r).Transaction(func(db data.MasterQ) error { +// for i, passedOption := range passedOptions { +// rank := int64(i + 1) +// +// if err := db.VotesQ().Insert(data.Vote{ +// VotingID: TokenClaims(r).VotingID, +// VotingOption: passedOption, +// Nullifier: TokenClaims(r).Nullifier, +// Rank: &rank, +// }); err != nil { +// return errors.Wrap(err, "failed to insert vote to the database") +// } +// } +// return nil +// }); err != nil { +// return errors.Wrap(err, "failed to perform SQL transaction") +// } +// +// return nil +//} diff --git a/internal/service/api/requests/register.go b/internal/service/api/requests/register.go deleted file mode 100644 index f08d324..0000000 --- a/internal/service/api/requests/register.go +++ /dev/null @@ -1,33 +0,0 @@ -package requests - -import ( - "encoding/json" - snark "github.com/iden3/go-rapidsnark/types" - "gitlab.com/distributed_lab/logan/v3/errors" - "net/http" -) - -type RegisterRequestData struct { - InternalPublicKey string `json:"internal_public_key"` - Signature struct { - S string `json:"s"` - N string `json:"n"` - } `json:"signature"` - Proof snark.ZKProof `json:"proof"` - Timestamp int64 `json:"timestamp"` -} - -type RegisterRequest struct { - Data RegisterRequestData `json:"data"` -} - -func NewRegisterRequest(r *http.Request) (RegisterRequest, error) { - var request RegisterRequest - - err := json.NewDecoder(r.Body).Decode(&request) - if err != nil { - return request, errors.Wrap(err, "failed to unmarshal") - } - - return request, nil -} diff --git a/internal/service/api/requests/vote.go b/internal/service/api/requests/vote.go index 2773724..e211ecc 100644 --- a/internal/service/api/requests/vote.go +++ b/internal/service/api/requests/vote.go @@ -2,26 +2,23 @@ package requests import ( "encoding/json" - "net/http" - + snark "github.com/iden3/go-rapidsnark/types" "gitlab.com/distributed_lab/logan/v3/errors" + "net/http" ) -type Vote struct { - VotingOption string `json:"voting_option"` - Rank *int64 `json:"rank"` -} - -type VoteRequestVotes struct { - Votes []Vote `json:"votes"` -} - -type VoteRequestAttributes struct { - Attributes VoteRequestVotes `json:"attributes"` +type VoteRequestData struct { + InternalPublicKey string `json:"internal_public_key"` + Signature struct { + S string `json:"s"` + N string `json:"n"` + } `json:"signature"` + Proof snark.ZKProof `json:"proof"` + Timestamp int64 `json:"timestamp"` } type VoteRequest struct { - Data VoteRequestAttributes `json:"data"` + Data VoteRequestData `json:"data"` } func NewVoteRequest(r *http.Request) (VoteRequest, error) { diff --git a/internal/service/api/requests/vote_deprecated.go b/internal/service/api/requests/vote_deprecated.go new file mode 100644 index 0000000..6bfb861 --- /dev/null +++ b/internal/service/api/requests/vote_deprecated.go @@ -0,0 +1,29 @@ +package requests + +//type Vote struct { +// VotingOption string `json:"voting_option"` +// Rank *int64 `json:"rank"` +//} +// +//type VoteRequestVotes struct { +// Votes []Vote `json:"votes"` +//} +// +//type VoteRequestAttributes struct { +// Attributes VoteRequestVotes `json:"attributes"` +//} +// +//type VoteRequest struct { +//Data VoteRequestAttributes `json:"data"` +//} +// +//func NewVoteRequest(r *http.Request) (VoteRequest, error) { +// var request VoteRequest +// +// err := json.NewDecoder(r.Body).Decode(&request) +// if err != nil { +// return request, errors.Wrap(err, "failed to unmarshal") +// } +// +// return request, nil +//} diff --git a/internal/service/router.go b/internal/service/router.go index 4c70aed..8d4656a 100644 --- a/internal/service/router.go +++ b/internal/service/router.go @@ -55,8 +55,7 @@ func (s *service) router() chi.Router { r.Route("/voting", func(r chi.Router) { r.With(handlers.AuthMiddleware(jwtIssuer, s.log, jwt.AccessTokenType)).Get("/{id}", handlers.GetVoting) r.Get("/list", handlers.GetVotings) - r.Post("/register", handlers.Register) - r.With(handlers.AuthMiddleware(jwtIssuer, s.log, jwt.AccessTokenType)).Post("/vote", handlers.Vote) + r.Post("/vote", handlers.Vote) }) r.Get("/auth-data/{id}", handlers.GetAuthData) }) From 4eb8d76d3bcdd2981b69e61457c33ae1033e9ad4 Mon Sep 17 00:00:00 2001 From: Roman Date: Sun, 24 Mar 2024 14:37:22 +0200 Subject: [PATCH 2/2] refactoring --- .../spec/components/schemas/VotingOption.yaml | 1 - .../components/schemas/VotingOptionKey.yaml | 1 - internal/assets/migrations/001_initial.sql | 10 +- internal/contracts/registration.go | 572 ------------------ internal/contracts/voting.go | 566 +++++++++++++++++ internal/data/registrations.go | 8 +- internal/data/verification_requests.go | 2 +- internal/data/votes.go | 12 +- internal/data/voting_options.go | 12 +- internal/data/votings.go | 3 +- internal/service/api/handlers/ctx.go | 10 +- .../service/api/handlers/get_auth_data.go | 4 +- internal/service/api/handlers/get_voting.go | 2 +- internal/service/api/handlers/get_votings.go | 2 +- internal/service/api/handlers/vote.go | 57 +- internal/service/api/requests/get_voting.go | 9 +- internal/service/api/requests/vote.go | 10 +- internal/service/router.go | 15 +- resources/model_voting_option_attributes.go | 14 +- 19 files changed, 636 insertions(+), 674 deletions(-) delete mode 100644 internal/contracts/registration.go create mode 100644 internal/contracts/voting.go diff --git a/docs/spec/components/schemas/VotingOption.yaml b/docs/spec/components/schemas/VotingOption.yaml index 9395e14..9b0ca7e 100644 --- a/docs/spec/components/schemas/VotingOption.yaml +++ b/docs/spec/components/schemas/VotingOption.yaml @@ -16,7 +16,6 @@ allOf: format: int64 voting_id: type: string - format: uuid.UUID name: type: string description: diff --git a/docs/spec/components/schemas/VotingOptionKey.yaml b/docs/spec/components/schemas/VotingOptionKey.yaml index fbb56ed..c62a3ac 100644 --- a/docs/spec/components/schemas/VotingOptionKey.yaml +++ b/docs/spec/components/schemas/VotingOptionKey.yaml @@ -5,7 +5,6 @@ required: properties: id: type: string - format: uuid.UUID type: type: string enum: diff --git a/internal/assets/migrations/001_initial.sql b/internal/assets/migrations/001_initial.sql index 7e84d06..d174b8f 100644 --- a/internal/assets/migrations/001_initial.sql +++ b/internal/assets/migrations/001_initial.sql @@ -1,7 +1,7 @@ -- +migrate Up create table votings( - id uuid primary key default gen_random_uuid(), + id text primary key default gen_random_uuid(), name text not null, description text not null, voting_type integer not null, @@ -12,25 +12,25 @@ create table votings( create table voting_options( id integer not null, name text not null, - voting_id uuid not null, + voting_id text not null, description text, primary key (id, name, voting_id) ); create table verification_requests( id uuid not null primary key, - voting_id uuid not null, + voting_id text not null, nullifier text not null ); create table registrations( - voting_id uuid not null, + voting_id text not null, nullifier text not null, primary key (voting_id, nullifier) ); create table votes( - voting_id uuid not null, + voting_id text not null, voting_option text not null, nullifier text not null, rank integer, diff --git a/internal/contracts/registration.go b/internal/contracts/registration.go deleted file mode 100644 index 8e2296a..0000000 --- a/internal/contracts/registration.go +++ /dev/null @@ -1,572 +0,0 @@ -// Code generated - DO NOT EDIT. -// This file is a generated binding and any manual changes will be lost. - -package contracts - -import ( - "errors" - "math/big" - "strings" - - ethereum "github.com/ethereum/go-ethereum" - "github.com/ethereum/go-ethereum/accounts/abi" - "github.com/ethereum/go-ethereum/accounts/abi/bind" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/core/types" - "github.com/ethereum/go-ethereum/event" -) - -// Reference imports to suppress errors if they are not otherwise used. -var ( - _ = errors.New - _ = big.NewInt - _ = strings.NewReader - _ = ethereum.NotFound - _ = bind.Bind - _ = common.Big1 - _ = types.BloomLookup - _ = event.NewSubscription - _ = abi.ConvertType -) - -// SparseMerkleTreeNode is an auto generated low-level Go binding around an user-defined struct. -type SparseMerkleTreeNode struct { - NodeType uint8 - ChildLeft uint64 - ChildRight uint64 - NodeHash [32]byte - Key [32]byte - Value [32]byte -} - -// SparseMerkleTreeProof is an auto generated low-level Go binding around an user-defined struct. -type SparseMerkleTreeProof struct { - Root [32]byte - Siblings [][32]byte - Existence bool - Key [32]byte - Value [32]byte - AuxExistence bool - AuxKey [32]byte - AuxValue [32]byte -} - -// VerifierHelperProofPoints is an auto generated low-level Go binding around an user-defined struct. -type VerifierHelperProofPoints struct { - A [2]*big.Int - B [2][2]*big.Int - C [2]*big.Int -} - -// RegistrationMetaData contains all meta data concerning the Registration contract. -var RegistrationMetaData = &bind.MetaData{ - ABI: "[{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"version\",\"type\":\"uint8\"}],\"name\":\"Initialized\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"E\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"treeHeight_\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"verifier_\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"icaoMasterTreeMerkleRoot_\",\"type\":\"bytes32\"}],\"name\":\"__Registration_init\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"key_\",\"type\":\"bytes32\"}],\"name\":\"getNodeByKey\",\"outputs\":[{\"components\":[{\"internalType\":\"enumSparseMerkleTree.NodeType\",\"name\":\"nodeType\",\"type\":\"uint8\"},{\"internalType\":\"uint64\",\"name\":\"childLeft\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"childRight\",\"type\":\"uint64\"},{\"internalType\":\"bytes32\",\"name\":\"nodeHash\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"key\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"value\",\"type\":\"bytes32\"}],\"internalType\":\"structSparseMerkleTree.Node\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"key_\",\"type\":\"bytes32\"}],\"name\":\"getProof\",\"outputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"root\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32[]\",\"name\":\"siblings\",\"type\":\"bytes32[]\"},{\"internalType\":\"bool\",\"name\":\"existence\",\"type\":\"bool\"},{\"internalType\":\"bytes32\",\"name\":\"key\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"value\",\"type\":\"bytes32\"},{\"internalType\":\"bool\",\"name\":\"auxExistence\",\"type\":\"bool\"},{\"internalType\":\"bytes32\",\"name\":\"auxKey\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"auxValue\",\"type\":\"bytes32\"}],\"internalType\":\"structSparseMerkleTree.Proof\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRoot\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"icaoMasterTreeMerkleRoot\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"userInternalPublicKey_\",\"type\":\"bytes32\"},{\"internalType\":\"bytes\",\"name\":\"s_\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"n_\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"uint256[2]\",\"name\":\"a\",\"type\":\"uint256[2]\"},{\"internalType\":\"uint256[2][2]\",\"name\":\"b\",\"type\":\"uint256[2][2]\"},{\"internalType\":\"uint256[2]\",\"name\":\"c\",\"type\":\"uint256[2]\"}],\"internalType\":\"structVerifierHelper.ProofPoints\",\"name\":\"zkPoints_\",\"type\":\"tuple\"},{\"internalType\":\"uint256\",\"name\":\"proofTimestamp_\",\"type\":\"uint256\"}],\"name\":\"register\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"verifier\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", -} - -// RegistrationABI is the input ABI used to generate the binding from. -// Deprecated: Use RegistrationMetaData.ABI instead. -var RegistrationABI = RegistrationMetaData.ABI - -// Registration is an auto generated Go binding around an Ethereum contract. -type Registration struct { - RegistrationCaller // Read-only binding to the contract - RegistrationTransactor // Write-only binding to the contract - RegistrationFilterer // Log filterer for contract events -} - -// RegistrationCaller is an auto generated read-only Go binding around an Ethereum contract. -type RegistrationCaller struct { - contract *bind.BoundContract // Generic contract wrapper for the low level calls -} - -// RegistrationTransactor is an auto generated write-only Go binding around an Ethereum contract. -type RegistrationTransactor struct { - contract *bind.BoundContract // Generic contract wrapper for the low level calls -} - -// RegistrationFilterer is an auto generated log filtering Go binding around an Ethereum contract events. -type RegistrationFilterer struct { - contract *bind.BoundContract // Generic contract wrapper for the low level calls -} - -// RegistrationSession is an auto generated Go binding around an Ethereum contract, -// with pre-set call and transact options. -type RegistrationSession struct { - Contract *Registration // Generic contract binding to set the session for - CallOpts bind.CallOpts // Call options to use throughout this session - TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session -} - -// RegistrationCallerSession is an auto generated read-only Go binding around an Ethereum contract, -// with pre-set call options. -type RegistrationCallerSession struct { - Contract *RegistrationCaller // Generic contract caller binding to set the session for - CallOpts bind.CallOpts // Call options to use throughout this session -} - -// RegistrationTransactorSession is an auto generated write-only Go binding around an Ethereum contract, -// with pre-set transact options. -type RegistrationTransactorSession struct { - Contract *RegistrationTransactor // Generic contract transactor binding to set the session for - TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session -} - -// RegistrationRaw is an auto generated low-level Go binding around an Ethereum contract. -type RegistrationRaw struct { - Contract *Registration // Generic contract binding to access the raw methods on -} - -// RegistrationCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. -type RegistrationCallerRaw struct { - Contract *RegistrationCaller // Generic read-only contract binding to access the raw methods on -} - -// RegistrationTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. -type RegistrationTransactorRaw struct { - Contract *RegistrationTransactor // Generic write-only contract binding to access the raw methods on -} - -// NewRegistration creates a new instance of Registration, bound to a specific deployed contract. -func NewRegistration(address common.Address, backend bind.ContractBackend) (*Registration, error) { - contract, err := bindRegistration(address, backend, backend, backend) - if err != nil { - return nil, err - } - return &Registration{RegistrationCaller: RegistrationCaller{contract: contract}, RegistrationTransactor: RegistrationTransactor{contract: contract}, RegistrationFilterer: RegistrationFilterer{contract: contract}}, nil -} - -// NewRegistrationCaller creates a new read-only instance of Registration, bound to a specific deployed contract. -func NewRegistrationCaller(address common.Address, caller bind.ContractCaller) (*RegistrationCaller, error) { - contract, err := bindRegistration(address, caller, nil, nil) - if err != nil { - return nil, err - } - return &RegistrationCaller{contract: contract}, nil -} - -// NewRegistrationTransactor creates a new write-only instance of Registration, bound to a specific deployed contract. -func NewRegistrationTransactor(address common.Address, transactor bind.ContractTransactor) (*RegistrationTransactor, error) { - contract, err := bindRegistration(address, nil, transactor, nil) - if err != nil { - return nil, err - } - return &RegistrationTransactor{contract: contract}, nil -} - -// NewRegistrationFilterer creates a new log filterer instance of Registration, bound to a specific deployed contract. -func NewRegistrationFilterer(address common.Address, filterer bind.ContractFilterer) (*RegistrationFilterer, error) { - contract, err := bindRegistration(address, nil, nil, filterer) - if err != nil { - return nil, err - } - return &RegistrationFilterer{contract: contract}, nil -} - -// bindRegistration binds a generic wrapper to an already deployed contract. -func bindRegistration(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { - parsed, err := RegistrationMetaData.GetAbi() - if err != nil { - return nil, err - } - return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil -} - -// Call invokes the (constant) contract method with params as input values and -// sets the output to result. The result type might be a single field for simple -// returns, a slice of interfaces for anonymous returns and a struct for named -// returns. -func (_Registration *RegistrationRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { - return _Registration.Contract.RegistrationCaller.contract.Call(opts, result, method, params...) -} - -// Transfer initiates a plain transaction to move funds to the contract, calling -// its default method if one is available. -func (_Registration *RegistrationRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { - return _Registration.Contract.RegistrationTransactor.contract.Transfer(opts) -} - -// Transact invokes the (paid) contract method with params as input values. -func (_Registration *RegistrationRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { - return _Registration.Contract.RegistrationTransactor.contract.Transact(opts, method, params...) -} - -// Call invokes the (constant) contract method with params as input values and -// sets the output to result. The result type might be a single field for simple -// returns, a slice of interfaces for anonymous returns and a struct for named -// returns. -func (_Registration *RegistrationCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { - return _Registration.Contract.contract.Call(opts, result, method, params...) -} - -// Transfer initiates a plain transaction to move funds to the contract, calling -// its default method if one is available. -func (_Registration *RegistrationTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { - return _Registration.Contract.contract.Transfer(opts) -} - -// Transact invokes the (paid) contract method with params as input values. -func (_Registration *RegistrationTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { - return _Registration.Contract.contract.Transact(opts, method, params...) -} - -// E is a free data retrieval call binding the contract method 0x92bbf6e8. -// -// Solidity: function E() view returns(uint256) -func (_Registration *RegistrationCaller) E(opts *bind.CallOpts) (*big.Int, error) { - var out []interface{} - err := _Registration.contract.Call(opts, &out, "E") - - if err != nil { - return *new(*big.Int), err - } - - out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) - - return out0, err - -} - -// E is a free data retrieval call binding the contract method 0x92bbf6e8. -// -// Solidity: function E() view returns(uint256) -func (_Registration *RegistrationSession) E() (*big.Int, error) { - return _Registration.Contract.E(&_Registration.CallOpts) -} - -// E is a free data retrieval call binding the contract method 0x92bbf6e8. -// -// Solidity: function E() view returns(uint256) -func (_Registration *RegistrationCallerSession) E() (*big.Int, error) { - return _Registration.Contract.E(&_Registration.CallOpts) -} - -// GetNodeByKey is a free data retrieval call binding the contract method 0x083a8580. -// -// Solidity: function getNodeByKey(bytes32 key_) view returns((uint8,uint64,uint64,bytes32,bytes32,bytes32)) -func (_Registration *RegistrationCaller) GetNodeByKey(opts *bind.CallOpts, key_ [32]byte) (SparseMerkleTreeNode, error) { - var out []interface{} - err := _Registration.contract.Call(opts, &out, "getNodeByKey", key_) - - if err != nil { - return *new(SparseMerkleTreeNode), err - } - - out0 := *abi.ConvertType(out[0], new(SparseMerkleTreeNode)).(*SparseMerkleTreeNode) - - return out0, err - -} - -// GetNodeByKey is a free data retrieval call binding the contract method 0x083a8580. -// -// Solidity: function getNodeByKey(bytes32 key_) view returns((uint8,uint64,uint64,bytes32,bytes32,bytes32)) -func (_Registration *RegistrationSession) GetNodeByKey(key_ [32]byte) (SparseMerkleTreeNode, error) { - return _Registration.Contract.GetNodeByKey(&_Registration.CallOpts, key_) -} - -// GetNodeByKey is a free data retrieval call binding the contract method 0x083a8580. -// -// Solidity: function getNodeByKey(bytes32 key_) view returns((uint8,uint64,uint64,bytes32,bytes32,bytes32)) -func (_Registration *RegistrationCallerSession) GetNodeByKey(key_ [32]byte) (SparseMerkleTreeNode, error) { - return _Registration.Contract.GetNodeByKey(&_Registration.CallOpts, key_) -} - -// GetProof is a free data retrieval call binding the contract method 0x1b80bb3a. -// -// Solidity: function getProof(bytes32 key_) view returns((bytes32,bytes32[],bool,bytes32,bytes32,bool,bytes32,bytes32)) -func (_Registration *RegistrationCaller) GetProof(opts *bind.CallOpts, key_ [32]byte) (SparseMerkleTreeProof, error) { - var out []interface{} - err := _Registration.contract.Call(opts, &out, "getProof", key_) - - if err != nil { - return *new(SparseMerkleTreeProof), err - } - - out0 := *abi.ConvertType(out[0], new(SparseMerkleTreeProof)).(*SparseMerkleTreeProof) - - return out0, err - -} - -// GetProof is a free data retrieval call binding the contract method 0x1b80bb3a. -// -// Solidity: function getProof(bytes32 key_) view returns((bytes32,bytes32[],bool,bytes32,bytes32,bool,bytes32,bytes32)) -func (_Registration *RegistrationSession) GetProof(key_ [32]byte) (SparseMerkleTreeProof, error) { - return _Registration.Contract.GetProof(&_Registration.CallOpts, key_) -} - -// GetProof is a free data retrieval call binding the contract method 0x1b80bb3a. -// -// Solidity: function getProof(bytes32 key_) view returns((bytes32,bytes32[],bool,bytes32,bytes32,bool,bytes32,bytes32)) -func (_Registration *RegistrationCallerSession) GetProof(key_ [32]byte) (SparseMerkleTreeProof, error) { - return _Registration.Contract.GetProof(&_Registration.CallOpts, key_) -} - -// GetRoot is a free data retrieval call binding the contract method 0x5ca1e165. -// -// Solidity: function getRoot() view returns(bytes32) -func (_Registration *RegistrationCaller) GetRoot(opts *bind.CallOpts) ([32]byte, error) { - var out []interface{} - err := _Registration.contract.Call(opts, &out, "getRoot") - - if err != nil { - return *new([32]byte), err - } - - out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) - - return out0, err - -} - -// GetRoot is a free data retrieval call binding the contract method 0x5ca1e165. -// -// Solidity: function getRoot() view returns(bytes32) -func (_Registration *RegistrationSession) GetRoot() ([32]byte, error) { - return _Registration.Contract.GetRoot(&_Registration.CallOpts) -} - -// GetRoot is a free data retrieval call binding the contract method 0x5ca1e165. -// -// Solidity: function getRoot() view returns(bytes32) -func (_Registration *RegistrationCallerSession) GetRoot() ([32]byte, error) { - return _Registration.Contract.GetRoot(&_Registration.CallOpts) -} - -// IcaoMasterTreeMerkleRoot is a free data retrieval call binding the contract method 0x28093985. -// -// Solidity: function icaoMasterTreeMerkleRoot() view returns(bytes32) -func (_Registration *RegistrationCaller) IcaoMasterTreeMerkleRoot(opts *bind.CallOpts) ([32]byte, error) { - var out []interface{} - err := _Registration.contract.Call(opts, &out, "icaoMasterTreeMerkleRoot") - - if err != nil { - return *new([32]byte), err - } - - out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) - - return out0, err - -} - -// IcaoMasterTreeMerkleRoot is a free data retrieval call binding the contract method 0x28093985. -// -// Solidity: function icaoMasterTreeMerkleRoot() view returns(bytes32) -func (_Registration *RegistrationSession) IcaoMasterTreeMerkleRoot() ([32]byte, error) { - return _Registration.Contract.IcaoMasterTreeMerkleRoot(&_Registration.CallOpts) -} - -// IcaoMasterTreeMerkleRoot is a free data retrieval call binding the contract method 0x28093985. -// -// Solidity: function icaoMasterTreeMerkleRoot() view returns(bytes32) -func (_Registration *RegistrationCallerSession) IcaoMasterTreeMerkleRoot() ([32]byte, error) { - return _Registration.Contract.IcaoMasterTreeMerkleRoot(&_Registration.CallOpts) -} - -// Verifier is a free data retrieval call binding the contract method 0x2b7ac3f3. -// -// Solidity: function verifier() view returns(address) -func (_Registration *RegistrationCaller) Verifier(opts *bind.CallOpts) (common.Address, error) { - var out []interface{} - err := _Registration.contract.Call(opts, &out, "verifier") - - if err != nil { - return *new(common.Address), err - } - - out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) - - return out0, err - -} - -// Verifier is a free data retrieval call binding the contract method 0x2b7ac3f3. -// -// Solidity: function verifier() view returns(address) -func (_Registration *RegistrationSession) Verifier() (common.Address, error) { - return _Registration.Contract.Verifier(&_Registration.CallOpts) -} - -// Verifier is a free data retrieval call binding the contract method 0x2b7ac3f3. -// -// Solidity: function verifier() view returns(address) -func (_Registration *RegistrationCallerSession) Verifier() (common.Address, error) { - return _Registration.Contract.Verifier(&_Registration.CallOpts) -} - -// RegistrationInit is a paid mutator transaction binding the contract method 0x759bf7e1. -// -// Solidity: function __Registration_init(uint256 treeHeight_, address verifier_, bytes32 icaoMasterTreeMerkleRoot_) returns() -func (_Registration *RegistrationTransactor) RegistrationInit(opts *bind.TransactOpts, treeHeight_ *big.Int, verifier_ common.Address, icaoMasterTreeMerkleRoot_ [32]byte) (*types.Transaction, error) { - return _Registration.contract.Transact(opts, "__Registration_init", treeHeight_, verifier_, icaoMasterTreeMerkleRoot_) -} - -// RegistrationInit is a paid mutator transaction binding the contract method 0x759bf7e1. -// -// Solidity: function __Registration_init(uint256 treeHeight_, address verifier_, bytes32 icaoMasterTreeMerkleRoot_) returns() -func (_Registration *RegistrationSession) RegistrationInit(treeHeight_ *big.Int, verifier_ common.Address, icaoMasterTreeMerkleRoot_ [32]byte) (*types.Transaction, error) { - return _Registration.Contract.RegistrationInit(&_Registration.TransactOpts, treeHeight_, verifier_, icaoMasterTreeMerkleRoot_) -} - -// RegistrationInit is a paid mutator transaction binding the contract method 0x759bf7e1. -// -// Solidity: function __Registration_init(uint256 treeHeight_, address verifier_, bytes32 icaoMasterTreeMerkleRoot_) returns() -func (_Registration *RegistrationTransactorSession) RegistrationInit(treeHeight_ *big.Int, verifier_ common.Address, icaoMasterTreeMerkleRoot_ [32]byte) (*types.Transaction, error) { - return _Registration.Contract.RegistrationInit(&_Registration.TransactOpts, treeHeight_, verifier_, icaoMasterTreeMerkleRoot_) -} - -// Register is a paid mutator transaction binding the contract method 0xd8d64da1. -// -// Solidity: function register(bytes32 userInternalPublicKey_, bytes s_, bytes n_, (uint256[2],uint256[2][2],uint256[2]) zkPoints_, uint256 proofTimestamp_) returns() -func (_Registration *RegistrationTransactor) Register(opts *bind.TransactOpts, userInternalPublicKey_ [32]byte, s_ []byte, n_ []byte, zkPoints_ VerifierHelperProofPoints, proofTimestamp_ *big.Int) (*types.Transaction, error) { - return _Registration.contract.Transact(opts, "register", userInternalPublicKey_, s_, n_, zkPoints_, proofTimestamp_) -} - -// Register is a paid mutator transaction binding the contract method 0xd8d64da1. -// -// Solidity: function register(bytes32 userInternalPublicKey_, bytes s_, bytes n_, (uint256[2],uint256[2][2],uint256[2]) zkPoints_, uint256 proofTimestamp_) returns() -func (_Registration *RegistrationSession) Register(userInternalPublicKey_ [32]byte, s_ []byte, n_ []byte, zkPoints_ VerifierHelperProofPoints, proofTimestamp_ *big.Int) (*types.Transaction, error) { - return _Registration.Contract.Register(&_Registration.TransactOpts, userInternalPublicKey_, s_, n_, zkPoints_, proofTimestamp_) -} - -// Register is a paid mutator transaction binding the contract method 0xd8d64da1. -// -// Solidity: function register(bytes32 userInternalPublicKey_, bytes s_, bytes n_, (uint256[2],uint256[2][2],uint256[2]) zkPoints_, uint256 proofTimestamp_) returns() -func (_Registration *RegistrationTransactorSession) Register(userInternalPublicKey_ [32]byte, s_ []byte, n_ []byte, zkPoints_ VerifierHelperProofPoints, proofTimestamp_ *big.Int) (*types.Transaction, error) { - return _Registration.Contract.Register(&_Registration.TransactOpts, userInternalPublicKey_, s_, n_, zkPoints_, proofTimestamp_) -} - -// RegistrationInitializedIterator is returned from FilterInitialized and is used to iterate over the raw logs and unpacked data for Initialized events raised by the Registration contract. -type RegistrationInitializedIterator struct { - Event *RegistrationInitialized // Event containing the contract specifics and raw log - - contract *bind.BoundContract // Generic contract to use for unpacking event data - event string // Event name to use for unpacking event data - - logs chan types.Log // Log channel receiving the found contract events - sub ethereum.Subscription // Subscription for errors, completion and termination - done bool // Whether the subscription completed delivering logs - fail error // Occurred error to stop iteration -} - -// Next advances the iterator to the subsequent event, returning whether there -// are any more events found. In case of a retrieval or parsing error, false is -// returned and Error() can be queried for the exact failure. -func (it *RegistrationInitializedIterator) Next() bool { - // If the iterator failed, stop iterating - if it.fail != nil { - return false - } - // If the iterator completed, deliver directly whatever's available - if it.done { - select { - case log := <-it.logs: - it.Event = new(RegistrationInitialized) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - default: - return false - } - } - // Iterator still in progress, wait for either a data or an error event - select { - case log := <-it.logs: - it.Event = new(RegistrationInitialized) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - case err := <-it.sub.Err(): - it.done = true - it.fail = err - return it.Next() - } -} - -// Error returns any retrieval or parsing error occurred during filtering. -func (it *RegistrationInitializedIterator) Error() error { - return it.fail -} - -// Close terminates the iteration process, releasing any pending underlying -// resources. -func (it *RegistrationInitializedIterator) Close() error { - it.sub.Unsubscribe() - return nil -} - -// RegistrationInitialized represents a Initialized event raised by the Registration contract. -type RegistrationInitialized struct { - Version uint8 - Raw types.Log // Blockchain specific contextual infos -} - -// FilterInitialized is a free log retrieval operation binding the contract event 0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498. -// -// Solidity: event Initialized(uint8 version) -func (_Registration *RegistrationFilterer) FilterInitialized(opts *bind.FilterOpts) (*RegistrationInitializedIterator, error) { - - logs, sub, err := _Registration.contract.FilterLogs(opts, "Initialized") - if err != nil { - return nil, err - } - return &RegistrationInitializedIterator{contract: _Registration.contract, event: "Initialized", logs: logs, sub: sub}, nil -} - -// WatchInitialized is a free log subscription operation binding the contract event 0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498. -// -// Solidity: event Initialized(uint8 version) -func (_Registration *RegistrationFilterer) WatchInitialized(opts *bind.WatchOpts, sink chan<- *RegistrationInitialized) (event.Subscription, error) { - - logs, sub, err := _Registration.contract.WatchLogs(opts, "Initialized") - if err != nil { - return nil, err - } - return event.NewSubscription(func(quit <-chan struct{}) error { - defer sub.Unsubscribe() - for { - select { - case log := <-logs: - // New log arrived, parse the event and forward to the user - event := new(RegistrationInitialized) - if err := _Registration.contract.UnpackLog(event, "Initialized", log); err != nil { - return err - } - event.Raw = log - - select { - case sink <- event: - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - } - }), nil -} - -// ParseInitialized is a log parse operation binding the contract event 0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498. -// -// Solidity: event Initialized(uint8 version) -func (_Registration *RegistrationFilterer) ParseInitialized(log types.Log) (*RegistrationInitialized, error) { - event := new(RegistrationInitialized) - if err := _Registration.contract.UnpackLog(event, "Initialized", log); err != nil { - return nil, err - } - event.Raw = log - return event, nil -} diff --git a/internal/contracts/voting.go b/internal/contracts/voting.go new file mode 100644 index 0000000..db67b02 --- /dev/null +++ b/internal/contracts/voting.go @@ -0,0 +1,566 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package contracts + +import ( + "errors" + "math/big" + "strings" + + ethereum "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/event" +) + +// Reference imports to suppress errors if they are not otherwise used. +var ( + _ = errors.New + _ = big.NewInt + _ = strings.NewReader + _ = ethereum.NotFound + _ = bind.Bind + _ = common.Big1 + _ = types.BloomLookup + _ = event.NewSubscription + _ = abi.ConvertType +) + +// VerifierHelperProofPoints is an auto generated low-level Go binding around an user-defined struct. +type VerifierHelperProofPoints struct { + A [2]*big.Int + B [2][2]*big.Int + C [2]*big.Int +} + +// VotingVotingParams is an auto generated low-level Go binding around an user-defined struct. +type VotingVotingParams struct { + StartTimestamp *big.Int + Duration *big.Int + Candidates []*big.Int +} + +// VotingVotingPublicConfig is an auto generated low-level Go binding around an user-defined struct. +type VotingVotingPublicConfig struct { + StartTimestamp *big.Int + EndTimestamp *big.Int + Status uint8 + Candidates []*big.Int + VotesPerCandidates []*big.Int +} + +// VotingMetaData contains all meta data concerning the Voting contract. +var VotingMetaData = &bind.MetaData{ + ABI: "[{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"version\",\"type\":\"uint8\"}],\"name\":\"Initialized\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"registrationMerkleRoot_\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"verifier_\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"startTimestamp\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"duration\",\"type\":\"uint256\"},{\"internalType\":\"uint256[]\",\"name\":\"candidates\",\"type\":\"uint256[]\"}],\"internalType\":\"structVoting.VotingParams\",\"name\":\"config_\",\"type\":\"tuple\"}],\"name\":\"__Voting_init\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"blindedNullifiers\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getVotingInfo\",\"outputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"startTimestamp\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"endTimestamp\",\"type\":\"uint256\"},{\"internalType\":\"enumVoting.VotingStatus\",\"name\":\"status\",\"type\":\"uint8\"},{\"internalType\":\"uint256[]\",\"name\":\"candidates\",\"type\":\"uint256[]\"},{\"internalType\":\"uint256[]\",\"name\":\"votesPerCandidates\",\"type\":\"uint256[]\"}],\"internalType\":\"structVoting.VotingPublicConfig\",\"name\":\"info_\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"registrationMerkleRoot\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"registrationTimestamp\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"verifier\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256[5]\",\"name\":\"candidates_\",\"type\":\"uint256[5]\"},{\"components\":[{\"internalType\":\"uint256[2]\",\"name\":\"a\",\"type\":\"uint256[2]\"},{\"internalType\":\"uint256[2][2]\",\"name\":\"b\",\"type\":\"uint256[2][2]\"},{\"internalType\":\"uint256[2]\",\"name\":\"c\",\"type\":\"uint256[2]\"}],\"internalType\":\"structVerifierHelper.ProofPoints\",\"name\":\"zkPoints_\",\"type\":\"tuple\"},{\"internalType\":\"uint256\",\"name\":\"nullifierHash_\",\"type\":\"uint256\"}],\"name\":\"vote\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"votesForCandidates\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", +} + +// VotingABI is the input ABI used to generate the binding from. +// Deprecated: Use VotingMetaData.ABI instead. +var VotingABI = VotingMetaData.ABI + +// Voting is an auto generated Go binding around an Ethereum contract. +type Voting struct { + VotingCaller // Read-only binding to the contract + VotingTransactor // Write-only binding to the contract + VotingFilterer // Log filterer for contract events +} + +// VotingCaller is an auto generated read-only Go binding around an Ethereum contract. +type VotingCaller struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// VotingTransactor is an auto generated write-only Go binding around an Ethereum contract. +type VotingTransactor struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// VotingFilterer is an auto generated log filtering Go binding around an Ethereum contract events. +type VotingFilterer struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// VotingSession is an auto generated Go binding around an Ethereum contract, +// with pre-set call and transact options. +type VotingSession struct { + Contract *Voting // Generic contract binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// VotingCallerSession is an auto generated read-only Go binding around an Ethereum contract, +// with pre-set call options. +type VotingCallerSession struct { + Contract *VotingCaller // Generic contract caller binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session +} + +// VotingTransactorSession is an auto generated write-only Go binding around an Ethereum contract, +// with pre-set transact options. +type VotingTransactorSession struct { + Contract *VotingTransactor // Generic contract transactor binding to set the session for + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// VotingRaw is an auto generated low-level Go binding around an Ethereum contract. +type VotingRaw struct { + Contract *Voting // Generic contract binding to access the raw methods on +} + +// VotingCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. +type VotingCallerRaw struct { + Contract *VotingCaller // Generic read-only contract binding to access the raw methods on +} + +// VotingTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. +type VotingTransactorRaw struct { + Contract *VotingTransactor // Generic write-only contract binding to access the raw methods on +} + +// NewVoting creates a new instance of Voting, bound to a specific deployed contract. +func NewVoting(address common.Address, backend bind.ContractBackend) (*Voting, error) { + contract, err := bindVoting(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &Voting{VotingCaller: VotingCaller{contract: contract}, VotingTransactor: VotingTransactor{contract: contract}, VotingFilterer: VotingFilterer{contract: contract}}, nil +} + +// NewVotingCaller creates a new read-only instance of Voting, bound to a specific deployed contract. +func NewVotingCaller(address common.Address, caller bind.ContractCaller) (*VotingCaller, error) { + contract, err := bindVoting(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &VotingCaller{contract: contract}, nil +} + +// NewVotingTransactor creates a new write-only instance of Voting, bound to a specific deployed contract. +func NewVotingTransactor(address common.Address, transactor bind.ContractTransactor) (*VotingTransactor, error) { + contract, err := bindVoting(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &VotingTransactor{contract: contract}, nil +} + +// NewVotingFilterer creates a new log filterer instance of Voting, bound to a specific deployed contract. +func NewVotingFilterer(address common.Address, filterer bind.ContractFilterer) (*VotingFilterer, error) { + contract, err := bindVoting(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &VotingFilterer{contract: contract}, nil +} + +// bindVoting binds a generic wrapper to an already deployed contract. +func bindVoting(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := VotingMetaData.GetAbi() + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_Voting *VotingRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _Voting.Contract.VotingCaller.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_Voting *VotingRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _Voting.Contract.VotingTransactor.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_Voting *VotingRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _Voting.Contract.VotingTransactor.contract.Transact(opts, method, params...) +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_Voting *VotingCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _Voting.Contract.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_Voting *VotingTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _Voting.Contract.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_Voting *VotingTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _Voting.Contract.contract.Transact(opts, method, params...) +} + +// BlindedNullifiers is a free data retrieval call binding the contract method 0x24526b1b. +// +// Solidity: function blindedNullifiers(uint256 ) view returns(bool) +func (_Voting *VotingCaller) BlindedNullifiers(opts *bind.CallOpts, arg0 *big.Int) (bool, error) { + var out []interface{} + err := _Voting.contract.Call(opts, &out, "blindedNullifiers", arg0) + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +// BlindedNullifiers is a free data retrieval call binding the contract method 0x24526b1b. +// +// Solidity: function blindedNullifiers(uint256 ) view returns(bool) +func (_Voting *VotingSession) BlindedNullifiers(arg0 *big.Int) (bool, error) { + return _Voting.Contract.BlindedNullifiers(&_Voting.CallOpts, arg0) +} + +// BlindedNullifiers is a free data retrieval call binding the contract method 0x24526b1b. +// +// Solidity: function blindedNullifiers(uint256 ) view returns(bool) +func (_Voting *VotingCallerSession) BlindedNullifiers(arg0 *big.Int) (bool, error) { + return _Voting.Contract.BlindedNullifiers(&_Voting.CallOpts, arg0) +} + +// GetVotingInfo is a free data retrieval call binding the contract method 0x359af4b2. +// +// Solidity: function getVotingInfo() view returns((uint256,uint256,uint8,uint256[],uint256[]) info_) +func (_Voting *VotingCaller) GetVotingInfo(opts *bind.CallOpts) (VotingVotingPublicConfig, error) { + var out []interface{} + err := _Voting.contract.Call(opts, &out, "getVotingInfo") + + if err != nil { + return *new(VotingVotingPublicConfig), err + } + + out0 := *abi.ConvertType(out[0], new(VotingVotingPublicConfig)).(*VotingVotingPublicConfig) + + return out0, err + +} + +// GetVotingInfo is a free data retrieval call binding the contract method 0x359af4b2. +// +// Solidity: function getVotingInfo() view returns((uint256,uint256,uint8,uint256[],uint256[]) info_) +func (_Voting *VotingSession) GetVotingInfo() (VotingVotingPublicConfig, error) { + return _Voting.Contract.GetVotingInfo(&_Voting.CallOpts) +} + +// GetVotingInfo is a free data retrieval call binding the contract method 0x359af4b2. +// +// Solidity: function getVotingInfo() view returns((uint256,uint256,uint8,uint256[],uint256[]) info_) +func (_Voting *VotingCallerSession) GetVotingInfo() (VotingVotingPublicConfig, error) { + return _Voting.Contract.GetVotingInfo(&_Voting.CallOpts) +} + +// RegistrationMerkleRoot is a free data retrieval call binding the contract method 0xfa1b3180. +// +// Solidity: function registrationMerkleRoot() view returns(bytes32) +func (_Voting *VotingCaller) RegistrationMerkleRoot(opts *bind.CallOpts) ([32]byte, error) { + var out []interface{} + err := _Voting.contract.Call(opts, &out, "registrationMerkleRoot") + + if err != nil { + return *new([32]byte), err + } + + out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) + + return out0, err + +} + +// RegistrationMerkleRoot is a free data retrieval call binding the contract method 0xfa1b3180. +// +// Solidity: function registrationMerkleRoot() view returns(bytes32) +func (_Voting *VotingSession) RegistrationMerkleRoot() ([32]byte, error) { + return _Voting.Contract.RegistrationMerkleRoot(&_Voting.CallOpts) +} + +// RegistrationMerkleRoot is a free data retrieval call binding the contract method 0xfa1b3180. +// +// Solidity: function registrationMerkleRoot() view returns(bytes32) +func (_Voting *VotingCallerSession) RegistrationMerkleRoot() ([32]byte, error) { + return _Voting.Contract.RegistrationMerkleRoot(&_Voting.CallOpts) +} + +// RegistrationTimestamp is a free data retrieval call binding the contract method 0x1e801262. +// +// Solidity: function registrationTimestamp() view returns(uint256) +func (_Voting *VotingCaller) RegistrationTimestamp(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _Voting.contract.Call(opts, &out, "registrationTimestamp") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// RegistrationTimestamp is a free data retrieval call binding the contract method 0x1e801262. +// +// Solidity: function registrationTimestamp() view returns(uint256) +func (_Voting *VotingSession) RegistrationTimestamp() (*big.Int, error) { + return _Voting.Contract.RegistrationTimestamp(&_Voting.CallOpts) +} + +// RegistrationTimestamp is a free data retrieval call binding the contract method 0x1e801262. +// +// Solidity: function registrationTimestamp() view returns(uint256) +func (_Voting *VotingCallerSession) RegistrationTimestamp() (*big.Int, error) { + return _Voting.Contract.RegistrationTimestamp(&_Voting.CallOpts) +} + +// Verifier is a free data retrieval call binding the contract method 0x2b7ac3f3. +// +// Solidity: function verifier() view returns(address) +func (_Voting *VotingCaller) Verifier(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _Voting.contract.Call(opts, &out, "verifier") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +// Verifier is a free data retrieval call binding the contract method 0x2b7ac3f3. +// +// Solidity: function verifier() view returns(address) +func (_Voting *VotingSession) Verifier() (common.Address, error) { + return _Voting.Contract.Verifier(&_Voting.CallOpts) +} + +// Verifier is a free data retrieval call binding the contract method 0x2b7ac3f3. +// +// Solidity: function verifier() view returns(address) +func (_Voting *VotingCallerSession) Verifier() (common.Address, error) { + return _Voting.Contract.Verifier(&_Voting.CallOpts) +} + +// VotesForCandidates is a free data retrieval call binding the contract method 0x055ef41c. +// +// Solidity: function votesForCandidates(uint256 ) view returns(uint256) +func (_Voting *VotingCaller) VotesForCandidates(opts *bind.CallOpts, arg0 *big.Int) (*big.Int, error) { + var out []interface{} + err := _Voting.contract.Call(opts, &out, "votesForCandidates", arg0) + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// VotesForCandidates is a free data retrieval call binding the contract method 0x055ef41c. +// +// Solidity: function votesForCandidates(uint256 ) view returns(uint256) +func (_Voting *VotingSession) VotesForCandidates(arg0 *big.Int) (*big.Int, error) { + return _Voting.Contract.VotesForCandidates(&_Voting.CallOpts, arg0) +} + +// VotesForCandidates is a free data retrieval call binding the contract method 0x055ef41c. +// +// Solidity: function votesForCandidates(uint256 ) view returns(uint256) +func (_Voting *VotingCallerSession) VotesForCandidates(arg0 *big.Int) (*big.Int, error) { + return _Voting.Contract.VotesForCandidates(&_Voting.CallOpts, arg0) +} + +// VotingInit is a paid mutator transaction binding the contract method 0x36cd7f05. +// +// Solidity: function __Voting_init(bytes32 registrationMerkleRoot_, address verifier_, (uint256,uint256,uint256[]) config_) returns() +func (_Voting *VotingTransactor) VotingInit(opts *bind.TransactOpts, registrationMerkleRoot_ [32]byte, verifier_ common.Address, config_ VotingVotingParams) (*types.Transaction, error) { + return _Voting.contract.Transact(opts, "__Voting_init", registrationMerkleRoot_, verifier_, config_) +} + +// VotingInit is a paid mutator transaction binding the contract method 0x36cd7f05. +// +// Solidity: function __Voting_init(bytes32 registrationMerkleRoot_, address verifier_, (uint256,uint256,uint256[]) config_) returns() +func (_Voting *VotingSession) VotingInit(registrationMerkleRoot_ [32]byte, verifier_ common.Address, config_ VotingVotingParams) (*types.Transaction, error) { + return _Voting.Contract.VotingInit(&_Voting.TransactOpts, registrationMerkleRoot_, verifier_, config_) +} + +// VotingInit is a paid mutator transaction binding the contract method 0x36cd7f05. +// +// Solidity: function __Voting_init(bytes32 registrationMerkleRoot_, address verifier_, (uint256,uint256,uint256[]) config_) returns() +func (_Voting *VotingTransactorSession) VotingInit(registrationMerkleRoot_ [32]byte, verifier_ common.Address, config_ VotingVotingParams) (*types.Transaction, error) { + return _Voting.Contract.VotingInit(&_Voting.TransactOpts, registrationMerkleRoot_, verifier_, config_) +} + +// Vote is a paid mutator transaction binding the contract method 0x68a866f0. +// +// Solidity: function vote(uint256[5] candidates_, (uint256[2],uint256[2][2],uint256[2]) zkPoints_, uint256 nullifierHash_) returns() +func (_Voting *VotingTransactor) Vote(opts *bind.TransactOpts, candidates_ [5]*big.Int, zkPoints_ VerifierHelperProofPoints, nullifierHash_ *big.Int) (*types.Transaction, error) { + return _Voting.contract.Transact(opts, "vote", candidates_, zkPoints_, nullifierHash_) +} + +// Vote is a paid mutator transaction binding the contract method 0x68a866f0. +// +// Solidity: function vote(uint256[5] candidates_, (uint256[2],uint256[2][2],uint256[2]) zkPoints_, uint256 nullifierHash_) returns() +func (_Voting *VotingSession) Vote(candidates_ [5]*big.Int, zkPoints_ VerifierHelperProofPoints, nullifierHash_ *big.Int) (*types.Transaction, error) { + return _Voting.Contract.Vote(&_Voting.TransactOpts, candidates_, zkPoints_, nullifierHash_) +} + +// Vote is a paid mutator transaction binding the contract method 0x68a866f0. +// +// Solidity: function vote(uint256[5] candidates_, (uint256[2],uint256[2][2],uint256[2]) zkPoints_, uint256 nullifierHash_) returns() +func (_Voting *VotingTransactorSession) Vote(candidates_ [5]*big.Int, zkPoints_ VerifierHelperProofPoints, nullifierHash_ *big.Int) (*types.Transaction, error) { + return _Voting.Contract.Vote(&_Voting.TransactOpts, candidates_, zkPoints_, nullifierHash_) +} + +// VotingInitializedIterator is returned from FilterInitialized and is used to iterate over the raw logs and unpacked data for Initialized events raised by the Voting contract. +type VotingInitializedIterator struct { + Event *VotingInitialized // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *VotingInitializedIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(VotingInitialized) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(VotingInitialized) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *VotingInitializedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *VotingInitializedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// VotingInitialized represents a Initialized event raised by the Voting contract. +type VotingInitialized struct { + Version uint8 + Raw types.Log // Blockchain specific contextual infos +} + +// FilterInitialized is a free log retrieval operation binding the contract event 0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498. +// +// Solidity: event Initialized(uint8 version) +func (_Voting *VotingFilterer) FilterInitialized(opts *bind.FilterOpts) (*VotingInitializedIterator, error) { + + logs, sub, err := _Voting.contract.FilterLogs(opts, "Initialized") + if err != nil { + return nil, err + } + return &VotingInitializedIterator{contract: _Voting.contract, event: "Initialized", logs: logs, sub: sub}, nil +} + +// WatchInitialized is a free log subscription operation binding the contract event 0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498. +// +// Solidity: event Initialized(uint8 version) +func (_Voting *VotingFilterer) WatchInitialized(opts *bind.WatchOpts, sink chan<- *VotingInitialized) (event.Subscription, error) { + + logs, sub, err := _Voting.contract.WatchLogs(opts, "Initialized") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(VotingInitialized) + if err := _Voting.contract.UnpackLog(event, "Initialized", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseInitialized is a log parse operation binding the contract event 0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498. +// +// Solidity: event Initialized(uint8 version) +func (_Voting *VotingFilterer) ParseInitialized(log types.Log) (*VotingInitialized, error) { + event := new(VotingInitialized) + if err := _Voting.contract.UnpackLog(event, "Initialized", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} diff --git a/internal/data/registrations.go b/internal/data/registrations.go index a8e13f0..a1b4205 100644 --- a/internal/data/registrations.go +++ b/internal/data/registrations.go @@ -1,9 +1,5 @@ package data -import ( - "github.com/google/uuid" -) - type RegistrationsQ interface { New() RegistrationsQ Insert(value Registration) error @@ -12,6 +8,6 @@ type RegistrationsQ interface { } type Registration struct { - VotingID uuid.UUID `db:"voting_id" structs:"voting_id"` - Nullifier string `db:"nullifier" structs:"nullifier"` + VotingID string `db:"voting_id" structs:"voting_id"` + Nullifier string `db:"nullifier" structs:"nullifier"` } diff --git a/internal/data/verification_requests.go b/internal/data/verification_requests.go index 5e80268..a0644ab 100644 --- a/internal/data/verification_requests.go +++ b/internal/data/verification_requests.go @@ -13,6 +13,6 @@ type VerificationRequestsQ interface { type VerificationRequest struct { ID uuid.UUID `db:"id" structs:"id"` - VotingID uuid.UUID `db:"voting_id" structs:"voting_id"` + VotingID string `db:"voting_id" structs:"voting_id"` Nullifier string `db:"nullifier" structs:"nullifier"` } diff --git a/internal/data/votes.go b/internal/data/votes.go index 5dd9d26..99b04d4 100644 --- a/internal/data/votes.go +++ b/internal/data/votes.go @@ -1,9 +1,5 @@ package data -import ( - "github.com/google/uuid" -) - type VotesQ interface { New() VotesQ Insert(vote Vote) error @@ -13,8 +9,8 @@ type VotesQ interface { } type Vote struct { - VotingID uuid.UUID `db:"voting_id" structs:"voting_id"` - VotingOption string `db:"voting_option" structs:"voting_option"` - Rank *int64 `db:"rank" structs:"rank"` - Nullifier string `db:"nullifier" structs:"nullifier"` + VotingID string `db:"voting_id" structs:"voting_id"` + VotingOption string `db:"voting_option" structs:"voting_option"` + Rank *int64 `db:"rank" structs:"rank"` + Nullifier string `db:"nullifier" structs:"nullifier"` } diff --git a/internal/data/voting_options.go b/internal/data/voting_options.go index 5852d66..0830179 100644 --- a/internal/data/voting_options.go +++ b/internal/data/voting_options.go @@ -1,9 +1,5 @@ package data -import ( - "github.com/google/uuid" -) - type VotingOptionsQ interface { New() VotingOptionsQ FilterBy(column string, value any) VotingOptionsQ @@ -11,8 +7,8 @@ type VotingOptionsQ interface { } type VotingOption struct { - ID int64 `db:"id" structs:"id"` - Name string `db:"name" structs:"name"` - VotingID uuid.UUID `db:"voting_id" structs:"voting_id"` - Description *string `db:"description" structs:"description"` + ID int64 `db:"id" structs:"id"` + Name string `db:"name" structs:"name"` + VotingID string `db:"voting_id" structs:"voting_id"` + Description *string `db:"description" structs:"description"` } diff --git a/internal/data/votings.go b/internal/data/votings.go index c28bcc1..c59db66 100644 --- a/internal/data/votings.go +++ b/internal/data/votings.go @@ -1,7 +1,6 @@ package data import ( - "github.com/google/uuid" "time" ) @@ -13,7 +12,7 @@ type VotingsQ interface { } type Voting struct { - ID uuid.UUID `db:"id" structs:"-"` + ID string `db:"id" structs:"-"` Name string `db:"name" structs:"name"` Description string `db:"description" structs:"description"` Type VotingType `db:"voting_type" structs:"voting_type"` diff --git a/internal/service/api/handlers/ctx.go b/internal/service/api/handlers/ctx.go index 6cdeff6..f11d5ad 100644 --- a/internal/service/api/handlers/ctx.go +++ b/internal/service/api/handlers/ctx.go @@ -22,7 +22,7 @@ const ( tokenClaimsCtxKey cookiesCtxKey networkConfigCtxKey - registrationContractCtxKey + votingContractCtxKey ethClientCtxKey ) @@ -86,14 +86,14 @@ func Cookies(r *http.Request) *cookies.Cookies { return r.Context().Value(cookiesCtxKey).(*cookies.Cookies) } -func CtxRegistrationContract(contract *contracts.Registration) func(context.Context) context.Context { +func CtxVotingContract(contract *contracts.Voting) func(context.Context) context.Context { return func(ctx context.Context) context.Context { - return context.WithValue(ctx, registrationContractCtxKey, contract) + return context.WithValue(ctx, votingContractCtxKey, contract) } } -func RegistrationContract(r *http.Request) *contracts.Registration { - return r.Context().Value(registrationContractCtxKey).(*contracts.Registration) +func VotingContract(r *http.Request) *contracts.Voting { + return r.Context().Value(votingContractCtxKey).(*contracts.Voting) } func CtxEthClient(client *ethclient.Client) func(context.Context) context.Context { diff --git a/internal/service/api/handlers/get_auth_data.go b/internal/service/api/handlers/get_auth_data.go index 4b7d5d3..7ec885b 100644 --- a/internal/service/api/handlers/get_auth_data.go +++ b/internal/service/api/handlers/get_auth_data.go @@ -33,7 +33,7 @@ func GetAuthData(w http.ResponseWriter, r *http.Request) { } access, err := JWTIssuer(r).IssueJWT( - verificationRequest.VotingID.String(), verificationRequest.Nullifier, jwt.AccessTokenType, + verificationRequest.VotingID, verificationRequest.Nullifier, jwt.AccessTokenType, ) if err != nil { Log(r).WithError(err).Error("failed to issuer JWT token") @@ -42,7 +42,7 @@ func GetAuthData(w http.ResponseWriter, r *http.Request) { } refresh, err := JWTIssuer(r).IssueJWT( - verificationRequest.VotingID.String(), verificationRequest.Nullifier, jwt.RefreshTokenType, + verificationRequest.VotingID, verificationRequest.Nullifier, jwt.RefreshTokenType, ) if err != nil { Log(r).WithError(err).Error("failed to issuer JWT token") diff --git a/internal/service/api/handlers/get_voting.go b/internal/service/api/handlers/get_voting.go index 4b261b8..30cd768 100644 --- a/internal/service/api/handlers/get_voting.go +++ b/internal/service/api/handlers/get_voting.go @@ -36,7 +36,7 @@ func GetVoting(w http.ResponseWriter, r *http.Request) { response := resources.VotingResponse{ Data: resources.Voting{ Key: resources.Key{ - ID: voting.ID.String(), + ID: voting.ID, Type: resources.VOTINGS, }, Attributes: resources.VotingAttributes{ diff --git a/internal/service/api/handlers/get_votings.go b/internal/service/api/handlers/get_votings.go index b9627c1..17d17e7 100644 --- a/internal/service/api/handlers/get_votings.go +++ b/internal/service/api/handlers/get_votings.go @@ -20,7 +20,7 @@ func GetVotings(w http.ResponseWriter, r *http.Request) { for i, voting := range votings { responseData[i] = resources.Voting{ Key: resources.Key{ - ID: voting.ID.String(), + ID: voting.ID, Type: resources.VOTINGS, }, Attributes: resources.VotingAttributes{ diff --git a/internal/service/api/handlers/vote.go b/internal/service/api/handlers/vote.go index 3aec079..8d729c8 100644 --- a/internal/service/api/handlers/vote.go +++ b/internal/service/api/handlers/vote.go @@ -29,7 +29,7 @@ func Vote(w http.ResponseWriter, r *http.Request) { return } - pubKey, s, n, a, b, c, err := getRegistrationData(req) + nullififer, candidates, a, b, c, err := getVotingData(req) if err != nil { Log(r).WithError(err).Error("failed to get registration data") ape.RenderErr(w, problems.InternalError()) @@ -39,8 +39,7 @@ func Vote(w http.ResponseWriter, r *http.Request) { NetworkConfig(r).LockNonce() defer NetworkConfig(r).UnlockNonce() - // FIXME rework for voting contract - tx, err := RegistrationContract(r).Register( + tx, err := VotingContract(r).Vote( &bind.TransactOpts{ NoSend: true, From: crypto.PubkeyToAddress(NetworkConfig(r).PrivateKey.PublicKey), @@ -50,13 +49,13 @@ func Vote(w http.ResponseWriter, r *http.Request) { ) }, }, - pubKey, s, n, + candidates, contracts.VerifierHelperProofPoints{ A: a, B: b, C: c, }, - big.NewInt(req.Data.Timestamp), + nullififer, ) if err != nil { Log(r).WithError(err).Error("failed to check transaction validity") @@ -66,12 +65,13 @@ func Vote(w http.ResponseWriter, r *http.Request) { if err := MasterQ(r).Transaction(func(db data.MasterQ) error { if err := db.RegistrationsQ().Insert(data.Registration{ - // TODO + VotingID: NetworkConfig(r).VotingAddress.String(), + Nullifier: nullififer.String(), }); err != nil { return errors.Wrap(err, "failed to insert registration") } - tx, err = RegistrationContract(r).Register( + tx, err = VotingContract(r).Vote( &bind.TransactOpts{ From: crypto.PubkeyToAddress(NetworkConfig(r).PrivateKey.PublicKey), Nonce: new(big.Int).SetUint64(NetworkConfig(r).Nonce()), @@ -81,13 +81,13 @@ func Vote(w http.ResponseWriter, r *http.Request) { ) }, }, - pubKey, s, n, + candidates, contracts.VerifierHelperProofPoints{ A: a, B: b, C: c, }, - big.NewInt(req.Data.Timestamp), + nullififer, ) if err != nil { if strings.Contains(err.Error(), "nonce") { @@ -96,7 +96,7 @@ func Vote(w http.ResponseWriter, r *http.Request) { return errors.Wrap(err, "failed to reset nonce") } - tx, err = RegistrationContract(r).Register( + tx, err = VotingContract(r).Vote( &bind.TransactOpts{ From: crypto.PubkeyToAddress(NetworkConfig(r).PrivateKey.PublicKey), Nonce: new(big.Int).SetUint64(NetworkConfig(r).Nonce()), @@ -106,13 +106,13 @@ func Vote(w http.ResponseWriter, r *http.Request) { ) }, }, - pubKey, s, n, + candidates, contracts.VerifierHelperProofPoints{ A: a, B: b, C: c, }, - big.NewInt(req.Data.Timestamp), + nullififer, ) if err != nil { ape.RenderErr(w, problems.InternalError()) @@ -142,32 +142,25 @@ func Vote(w http.ResponseWriter, r *http.Request) { }) } -func getRegistrationData(req requests.VoteRequest) ( - [32]byte, []byte, []byte, [2]*big.Int, [2][2]*big.Int, [2]*big.Int, error, +func getVotingData(req requests.VoteRequest) ( + *big.Int, [5]*big.Int, [2]*big.Int, [2][2]*big.Int, [2]*big.Int, error, ) { - pubKey, err := hex.DecodeString(req.Data.InternalPublicKey) + nullifier, err := hex.DecodeString(req.Data.Nullifier) if err != nil { - return [32]byte{}, nil, nil, [2]*big.Int{}, [2][2]*big.Int{}, [2]*big.Int{}, errors.Wrap(err, "failed to decode hex") + return nil, [5]*big.Int{}, [2]*big.Int{}, [2][2]*big.Int{}, [2]*big.Int{}, errors.Wrap(err, "failed to decode hex") } - pubKeyArr := [32]byte{} - copy(pubKeyArr[:], pubKey) - s, err := hex.DecodeString(req.Data.Signature.S) - if err != nil { - return [32]byte{}, nil, nil, [2]*big.Int{}, [2][2]*big.Int{}, [2]*big.Int{}, errors.Wrap(err, "failed to decode hex") - } - - n, err := hex.DecodeString(req.Data.Signature.N) + a, b, c, err := getProofPoints(req) if err != nil { - return [32]byte{}, nil, nil, [2]*big.Int{}, [2][2]*big.Int{}, [2]*big.Int{}, errors.Wrap(err, "failed to decode hex") + return nil, [5]*big.Int{}, [2]*big.Int{}, [2][2]*big.Int{}, [2]*big.Int{}, errors.Wrap(err, "failed to get proof points") } - a, b, c, err := getProofPoints(req) - if err != nil { - return [32]byte{}, nil, nil, [2]*big.Int{}, [2][2]*big.Int{}, [2]*big.Int{}, errors.Wrap(err, "failed to get proof points") + candidates := [5]*big.Int{} + for i, candidate := range req.Data.Candidates { + candidates[i] = big.NewInt(candidate) } - return pubKeyArr, s, n, a, b, c, nil + return new(big.Int).SetBytes(nullifier), candidates, a, b, c, nil } func getProofPoints(req requests.VoteRequest) ([2]*big.Int, [2][2]*big.Int, [2]*big.Int, error) { @@ -199,9 +192,9 @@ func getProofPoints(req requests.VoteRequest) ([2]*big.Int, [2][2]*big.Int, [2]* return resA, resB, resC, nil } -func stringsToArrayBigInt(publicSignals []string) ([]*big.Int, error) { - p := make([]*big.Int, 0, len(publicSignals)) - for _, s := range publicSignals { +func stringsToArrayBigInt(strs []string) ([]*big.Int, error) { + p := make([]*big.Int, 0, len(strs)) + for _, s := range strs { sb, err := stringToBigInt(s) if err != nil { return nil, err diff --git a/internal/service/api/requests/get_voting.go b/internal/service/api/requests/get_voting.go index 9c2d94d..856acd8 100644 --- a/internal/service/api/requests/get_voting.go +++ b/internal/service/api/requests/get_voting.go @@ -4,13 +4,12 @@ import ( "net/http" "github.com/go-chi/chi" - "github.com/google/uuid" "gitlab.com/distributed_lab/logan/v3/errors" "gitlab.com/distributed_lab/urlval" ) type GetVotingRequest struct { - ID uuid.UUID + ID string IncludeOptions bool `include:"options"` Nullifier *string `url:"nullifier"` } @@ -19,11 +18,7 @@ func NewGetVotingRequest(r *http.Request) (GetVotingRequest, error) { var request GetVotingRequest rawID := chi.URLParam(r, "id") - id, err := uuid.Parse(rawID) - if err != nil { - return GetVotingRequest{}, errors.Wrap(err, "failed to parse UUID") - } - request.ID = id + request.ID = rawID if err := urlval.Decode(r.URL.Query(), &request); err != nil { return GetVotingRequest{}, errors.Wrap(err, "failed to decode url") diff --git a/internal/service/api/requests/vote.go b/internal/service/api/requests/vote.go index e211ecc..17f0e5f 100644 --- a/internal/service/api/requests/vote.go +++ b/internal/service/api/requests/vote.go @@ -8,13 +8,9 @@ import ( ) type VoteRequestData struct { - InternalPublicKey string `json:"internal_public_key"` - Signature struct { - S string `json:"s"` - N string `json:"n"` - } `json:"signature"` - Proof snark.ZKProof `json:"proof"` - Timestamp int64 `json:"timestamp"` + Candidates []int64 `json:"candidates"` + Proof snark.ZKProof `json:"proof"` + Nullifier string `json:"nullifier"` } type VoteRequest struct { diff --git a/internal/service/router.go b/internal/service/router.go index 8d4656a..88c0626 100644 --- a/internal/service/router.go +++ b/internal/service/router.go @@ -26,18 +26,19 @@ func (s *service) router() chi.Router { panic(errors.Wrap(err, "failed to dial connect")) } - registrationContract, err := contracts.NewRegistration(s.cfg.NetworkConfig().VotingAddress, ethClient) + registrationContract, err := contracts.NewVoting(s.cfg.NetworkConfig().VotingAddress, ethClient) if err != nil { panic(errors.Wrap(err, "failed to init new registration contract")) } r.Use( cors.Handler(cors.Options{ - AllowedOrigins: []string{"*"}, - AllowedMethods: []string{"GET", "POST"}, - AllowedHeaders: []string{"Content-Type", "Authorization"}, - AllowCredentials: false, - MaxAge: 300, + AllowedOrigins: []string{"*"}, + AllowedMethods: []string{"GET", "POST"}, + AllowedHeaders: []string{"Content-Type", "Authorization"}, + AllowCredentials: true, + MaxAge: 300, + OptionsPassthrough: true, }), ape.RecoverMiddleware(s.log), ape.LoganMiddleware(s.log), @@ -48,7 +49,7 @@ func (s *service) router() chi.Router { handlers.CtxCookies(cookies.NewCookies(s.cfg.CookiesConfig())), handlers.CtxNetworkConfig(s.cfg.NetworkConfig()), handlers.CtxEthClient(ethClient), - handlers.CtxRegistrationContract(registrationContract), + handlers.CtxVotingContract(registrationContract), ), ) r.Route("/integrations/voting-svc", func(r chi.Router) { diff --git a/resources/model_voting_option_attributes.go b/resources/model_voting_option_attributes.go index d55ea42..d3f2da4 100644 --- a/resources/model_voting_option_attributes.go +++ b/resources/model_voting_option_attributes.go @@ -4,13 +4,11 @@ package resources -import "github.com/google/uuid" - type VotingOptionAttributes struct { - Description *string `json:"description,omitempty"` - Id int64 `json:"id"` - Name string `json:"name"` - Points *int64 `json:"points,omitempty"` - Votes *int64 `json:"votes,omitempty"` - VotingId uuid.UUID `json:"voting_id"` + Description *string `json:"description,omitempty"` + Id int64 `json:"id"` + Name string `json:"name"` + Points *int64 `json:"points,omitempty"` + Votes *int64 `json:"votes,omitempty"` + VotingId string `json:"voting_id"` }