I am working on a college project to make an election dapp using smart contracts. I coded the smart contract(Election) and it worked fine until I included one more contract(ElectionFactory) to get multiple elections. I got the error when I executed the function createElection(on the Election factory contract)
error:
Gas estimation errored with the following message (see below). The transaction execution will likely fail. Do you want to force sending?
execution reverted
smart contract :
//SPDX-License-Identifier: UNLICENSED
pragma solidity >= 0.8.0<0.9.0;
contract ElectionFactory{
address[]public deployedElections;
uint public electionscount;
address public owner;
modifier ownerOnly{
require(msg.sender == owner);
_;
}
function createElection(string memory _elecname,uint128 _enddate)public ownerOnly{
// Election newElection = new Election(_elecname,_enddate);
Election newElection = new Election();
deployedElections.push(address(newElection));
newElection.startElection(_elecname,_enddate);
electionscount++;
}
function getDeployedElection(uint index)public view returns(address){ //less gas function
return deployedElections[index];
}
function getElectionCounts()public view returns(uint){ // less gas function
return electionscount;
}
// function removeElection(uint index)public{ //function not developed yet
// delete deployedElections[index];
// }
}
//contract for election
contract Election{
//candidatte name,numvotes
struct Candidate{
string name;
uint numVotes;
}
//voter name,authorised,whom(voting to),voted(or not)
struct Voter{
string name;
bool authorised;
uint whom;
bool voted;
}
//constructor and variables
uint128 enddate;
// constructor(string memory _elecname,uint _enddate){
// startElection(_elecname,_enddate);
// }
address public owner; //is the admin starts election
string public electionName; //the name of the election
bool public electionstatus = true;//know if election is close or not if cloded status=false
bool public electionStarted = false; //election started or not
mapping(address => Voter) public voters; // voters = i.voter[adres]
Candidate[] public candidates; //array of candidate
uint public totalVotes; //total votes voted
//modifiers to limit or require
modifier ownerOnly(){
require(msg.sender == owner);
_;
}
modifier ifnoElection(){
require(electionstatus==true);
require(electionStarted==false);
_;
}
//function to start election
function startElection(string memory _electionName,uint128 _enddate)ifnoElection public{
require(_enddate>block.timestamp);
owner = msg.sender;
electionName = _electionName;
electionStarted = true;
}
//adding candidate only admin candidate(name, number of votes)
function addCandidate(string memory _candidateName)ownerOnly public{
candidates.push(Candidate(_candidateName, 0));
}
//authorize voter admin only can authorize voter needs voter adress
function authorizeVoter(address _voterAddress) ownerOnly public{
voters[_voterAddress].authorised= true;
}
//function to get total candidates number
function getNumCandidates() public view returns(uint){
return candidates.length;
}
//function to vote requires the index of candidate to vote
function vote(uint candidateIndex)ifnoElection public{
require(!voters[msg.sender].voted);
require(voters[msg.sender].authorised);
voters[msg.sender].whom = candidateIndex;
voters[msg.sender].voted = true;
candidates[candidateIndex].numVotes++;
totalVotes++;
}
//to get total votes
function getTotalVotes()public view returns(uint) {
return totalVotes;
}
//get info of candidate
function candidateInfo(uint index) public view returns(Candidate memory){
return candidates[index];
}
// function closeElection()public {
// //remove();
// electionStarted = false;
// electionstatus = false;
// }
// function remove() public ownerOnly{
// address one = 0xc4d9eE2d363b465443D751F7D553919281D1bd0a;
// address two = 0x2f8434dA7347C7c5266eDcCf9C36D33aa7D59dD4;
// address three = 0x6435Fdf5B2888A81C08c6dF5e4AF3F2580744e0F;
// delete voters[one];
// delete voters[two];
// delete voters[three];
// uint n = candidates.length;
// for(uint i=0;i<n;i++){
// delete candidates[i];
// }
// // Reset the value to the default value.
// //delete playerTicket[_addr];
// }
}
if you are kind enough please suggest some resources for me to do this project with less gas price
the error is because of the modifier. add an error message "Invalid caller" for the revert reason, you will see why it is reverted
modifier ownerOnly{
require(msg.sender == owner,"Invalid caller");
_;
}
because the callee of the createElection
is not the one who created the ElectionFactory
contract, the callee is the ElectionFactory
contract. you can use tx.origin==owner
inside modifier but this has security flaws.