Task: Create an event ProposalCreated which takes a single argument: a uint proposal ID. Emit this event whenever a new Proposal struct is created. Create an event VoteCast which takes two arguments: a uint proposal ID and an address for the voter's address. Emit this event any time a new vote is cast.
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
contract Voting {
struct Proposal {
address target;
bytes data;
uint yesCount;
uint noCount;
mapping(address => bool) hasVoted; // Track if an address has voted on this proposal
mapping(address => bool) voteChoice; // Track the vote (true = yes, false = no) of each voter
}
// Events
event ProposalCreated(uint256 indexed proposalId); // Event to be emitted when a proposal is created
event VoteCast(uint256 indexed proposalId, address indexed voteCaster); // Event to be emitted when a vote is cast
Proposal[] public proposals;
// Function to create a new proposal
function newProposal(address target, bytes memory data) external {
require(target != address(0), "Target address cannot be zero"); // Ensure target is valid
Proposal storage proposal = proposals.push(); // Add a new proposal to the array
proposal.target = target;
proposal.data = data;
uint proposalId = proposals.length - 1; // Get the ID of the new proposal
emit ProposalCreated(proposalId); // Emit the ProposalCreated event with the proposal ID
}
// Function to cast or change a vote on a proposal
function castVote(uint proposalId, bool support) external {
require(proposalId < proposals.length, "Invalid proposal ID");
Proposal storage proposal = proposals[proposalId];
// Check if the voter has already voted
if (proposal.hasVoted[msg.sender]) {
// If the voter wants to change their vote, update counts accordingly
bool previousVote = proposal.voteChoice[msg.sender];
if (previousVote && !support) {
proposal.yesCount -= 1;
proposal.noCount += 1;
} else if (!previousVote && support) {
proposal.noCount -= 1;
proposal.yesCount += 1;
}
} else {
// If the voter hasn't voted before, add their vote
proposal.hasVoted[msg.sender] = true;
if (support) {
proposal.yesCount += 1;
} else {
proposal.noCount += 1;
}
}
// Store the voter's choice (true = yes, false = no)
proposal.voteChoice[msg.sender] = support;
emit VoteCast(proposalId, msg.sender); // Emit the VoteCast event with the proposal ID and the voter's address
}
}