I am coding a simple voting system where a 'chairperson' is defined...Chairperson will add candidates but the voter are going to register themselves(no role of chairperson in adding of voters, Chairperson is only going to add candidates). Now In code I made an array of voters of type structs and make a function named "vote" which is going to be called only by voter. So, I add a check of that the voter must be in the voterList(array of voter) or else voter must register first.. But when I call the function it always reverting it...even The voters are already registered....(I am going to add code of the contract below)... [NOTE: THE PROBLEM IS IN ONE OF THE MODIFIER I CREATED NAMED "voterRules" IN THE CODE,I USED THIS MODIFIER IN THE VOTE FUNCTION...]
//SPDX-License-Identifier:UNLICENSED
pragma solidity ^0.8.0;
contract Ballot{
//VARIABLES
//Initialize an address of chairperson of voting system and set it private
address private chairperson;
//MODIFIERS
//To make chairperson as deployer
modifier isOwner(){
require(msg.sender == chairperson);
_;
}
//To make all the voters register by themselves
modifier isVoter(address voterAddress_){
require(voterAddress_ == msg.sender,"The voter must register by itself...");
_;
}
//To make rules for vote
modifier voterRules(){
require(msg.sender != chairperson,"Chairperson cannot vote!!");
for(uint m=0;m<voterList.length;m ){
// require(msg.sender == voterList[m]._voterAddress,"You must register yourself first...");
if( msg.sender != voterList[m]._voterAddress){
revert();
}
}
for(uint k=0;k<candidateList.length;k ){
require(voterToCandidate[msg.sender] != candidateList[k]._address,"You cannot vote twice...");
}
_;
}
//CONSTRUCTOR
//constructor to set deployer the chairperson
constructor(){
chairperson = msg.sender;
}
//STRUCTS
//Make a struct of candidate and give it properties: Name,Address,No. of votes
struct Candidate{
// string _name;
address _address;
uint256 _noOfVotes;
}
//Make a struct of voter and give it properties: Address,IsVoted
struct Voter{
address _voterAddress;
bool _isVoted;
}
//ARRAYS
//Make a array of candidates
Candidate[] public candidateList;
//Make an array of voters
Voter[] public voterList;
//MAPPINGS
//Mapping from address of Voter to stuct candidate
mapping(address=>address) private voterToCandidate;
//FUNCTIONS
//Make a function to add candidate in the mapping..
function addCandidate(address address_) public isOwner{
for(uint i=0;i<candidateList.length;i ){
require(address_ != candidateList[i]._address, "Same Candidate cannot be added twice");
}
Candidate memory candidate = Candidate(address_,0);
candidateList.push(candidate);
}
//Make a function to make voter to register himself..
function registerVoter(address voterAddress_) external isVoter(voterAddress_){
for(uint j=0;j<voterList.length;j ){
require(voterAddress_ != voterList[j]._voterAddress,"y");
}
voterList.push(Voter(voterAddress_,false));
}
//To make a function for voters to vote their desirable candidate and increase the count votes of the candidates
function vote(uint256 _candId) public voterRules() {
voterToCandidate[msg.sender] = candidateList[_candId]._address;
candidateList[_candId]._noOfVotes ;
}
}
CodePudding user response:
I believe you are pretty new to the solidity, here are a couple of things to keep in mind.
- We have to avoid loops as much as we can, to save gas.
- Use mappings instead of arrays.
- mapping can also maps to structs.
- use indentation for better code readability.
- Define state variables at the top.
and now to answer your question, I've made a couple of changes in the code that implements your intended logic as per my understanding. I am not explaining what I've done, You can use diffchecker.com to compare the code and think why I did what I did, it will give you a better understanding.
//SPDX-License-Identifier:UNLICENSED
pragma solidity ^0.8.0;
contract Ballot {
struct Candidate {
// string _name;
address _address;
uint256 _noOfVotes;
}
address private chairperson;
Candidate[] public candidateList;
mapping(address => bool) private isInVoterList;
mapping(address => address) private voterToCandidate;
modifier isOwner() {
require(msg.sender == chairperson);
_;
}
modifier isVoter(address voterAddress_) {
require(
voterAddress_ == msg.sender,
"The voter must register by itself..."
);
_;
}
modifier voterRules() {
require(msg.sender != chairperson, "Chairperson cannot vote!!");
require(isInVoterList[msg.sender], "You must register yourself first");
for (uint256 k = 0; k < candidateList.length; k ) {
require(
voterToCandidate[msg.sender] != candidateList[k]._address,
"You cannot vote twice..."
);
}
_;
}
constructor() {
chairperson = msg.sender;
}
function addCandidate(address address_) public isOwner {
for (uint256 i = 0; i < candidateList.length; i ) {
require(
address_ != candidateList[i]._address,
"Same Candidate cannot be added twice"
);
}
Candidate memory candidate = Candidate(address_, 0);
candidateList.push(candidate);
}
function registerVoter(address voterAddress_)
external
isVoter(voterAddress_)
{
require(
isInVoterList[voterAddress_] == false,
"You are already registerd voter"
);
isInVoterList[voterAddress_] = true;
}
function vote(uint256 _candId) public voterRules {
voterToCandidate[msg.sender] = candidateList[_candId]._address;
candidateList[_candId]._noOfVotes ;
}
}
suggesting watch
ps. dun forget to accept my answer.