diff --git a/voting-contract.sol b/voting-contract.sol
index 8b137891791fe96927ad78e64b0aad7bded08bdc..e9dcd213f8e37694b1f8b726cd3ebb080822919e 100644
--- a/voting-contract.sol
+++ b/voting-contract.sol
@@ -1 +1,171 @@
+import "@openzeppelin/contracts/access/Ownable.sol";
 
+pragma solidity ^0.8.0;
+
+contract Voting is Ownable{
+
+    enum WorkflowStatus {
+        RegisteringVoters,
+        ProposalsRegistrationStarted,
+        ProposalsRegistrationEnded,
+        VotingSessionStarted,
+        VotingSessionEnded,
+        VotesTallied
+    }
+
+    WorkflowStatus public status; 
+    uint public winningProposalId; 
+
+    struct Voter {
+        bool isRegistered;
+        bool hasVoted;
+        uint votedProposalId;
+    }
+
+    struct Proposal {
+        string description;
+        uint voteCount;
+    }
+
+    struct VoterProposal {
+        string description;
+        bool hasVoted;
+    }
+
+    mapping(address => VoterProposal) public voterProposals; 
+    mapping(address => Voter) public voters; 
+    mapping(address => address) public delegatedVotes; 
+    
+    Proposal[] public proposals; 
+
+    event VoterRegistered(address voterAddress);
+    
+    event WorkflowStatusChange(WorkflowStatus previousStatus, WorkflowStatus newStatus);
+    
+    event ProposalRegistered(uint proposalId);
+    
+    event Voted(address voter, uint proposalId);
+
+    constructor() Ownable(msg.sender) {
+        status = WorkflowStatus.RegisteringVoters;
+    }
+
+    function registerVoter(address _voter) public onlyOwner {
+        require(status == WorkflowStatus.RegisteringVoters, "Le vote n'est pas en cours d'inscription des votants.");
+        require(!voters[_voter].isRegistered, "Le votant est deja inscrit.");
+        voters[_voter].isRegistered = true;
+        emit VoterRegistered(_voter);
+    }
+
+    function startProposalsRegistration() public onlyOwner {
+        require(status == WorkflowStatus.RegisteringVoters, "Le vote n'est pas en cours d'inscription des votants.");
+        
+        status = WorkflowStatus.ProposalsRegistrationStarted;
+        emit WorkflowStatusChange(WorkflowStatus.RegisteringVoters, WorkflowStatus.ProposalsRegistrationStarted);
+    }
+
+    function endProposalsRegistration() public onlyOwner {
+        require(status == WorkflowStatus.ProposalsRegistrationStarted, "Le vote n'est pas en cours d'enregistrement des propositions.");
+        
+        status = WorkflowStatus.ProposalsRegistrationEnded;
+        emit WorkflowStatusChange(WorkflowStatus.ProposalsRegistrationStarted, WorkflowStatus.ProposalsRegistrationEnded);
+    }
+
+    function registerProposal(string memory _description) public {
+        require(status == WorkflowStatus.ProposalsRegistrationStarted, "Le vote n'est pas en cours d'enregistrement des propositions.");
+        require(voters[msg.sender].isRegistered, "Le votant n'est pas inscrit.");
+
+        Proposal memory newProposal = Proposal({
+            description: _description,
+            voteCount: 0
+        });
+
+        proposals.push(newProposal);
+        emit ProposalRegistered(proposals.length - 1);
+    }
+
+    function startVotingSession() public onlyOwner {
+        require(status == WorkflowStatus.ProposalsRegistrationEnded, "Le vote n'est pas en cours d'enregistrement des propositions.");
+        
+        status = WorkflowStatus.VotingSessionStarted;
+        emit WorkflowStatusChange(WorkflowStatus.ProposalsRegistrationEnded, WorkflowStatus.VotingSessionStarted);
+    }
+
+    function endVotingSession() public onlyOwner {
+        require(status == WorkflowStatus.VotingSessionStarted, "Le vote n'est pas en cours de vote.");
+        
+        status = WorkflowStatus.VotingSessionEnded;
+        emit WorkflowStatusChange(WorkflowStatus.VotingSessionStarted, WorkflowStatus.VotingSessionEnded);
+    }
+
+    function vote(uint _proposalId) public {
+        require(status == WorkflowStatus.VotingSessionStarted, "Le vote n'est pas en cours de vote.");
+        require(voters[msg.sender].isRegistered, "Le votant n'est pas inscrit.");
+        require(!voters[msg.sender].hasVoted, "Le votant a deja vote.");
+        require(_proposalId < proposals.length, "Proposition invalide.");
+
+        voters[msg.sender].hasVoted = true;
+        voters[msg.sender].votedProposalId = _proposalId;
+        proposals[_proposalId].voteCount++;
+        emit Voted(msg.sender, _proposalId);
+    }
+
+    function tallyVotes() public onlyOwner {
+        require(status == WorkflowStatus.VotingSessionEnded, "Le vote n'est pas en cours de vote.");
+        
+        uint winningVoteCount = 0;
+        for (uint i = 0; i < proposals.length; i++) {
+            if (proposals[i].voteCount > winningVoteCount) {
+                winningVoteCount = proposals[i].voteCount;
+                winningProposalId = i;
+            }
+        }
+
+        status = WorkflowStatus.VotesTallied;
+        emit WorkflowStatusChange(WorkflowStatus.VotingSessionEnded, WorkflowStatus.VotesTallied);
+    }
+
+    function getWinner() public view returns (string memory) {
+        require(status == WorkflowStatus.VotesTallied, "Le vote n'a pas encore ete comptabilise.");
+
+        return proposals[winningProposalId].description;
+    }
+
+    function revokeVoterRegistration(address _voter) public onlyOwner {
+        require(status == WorkflowStatus.RegisteringVoters, "Le vote n'est pas en cours d'inscription des votants.");
+        require(voters[_voter].isRegistered, "Le votant n'est pas inscrit.");
+
+        voters[_voter].isRegistered = false;
+    }
+
+    function registerOrUpdateProposal(string memory _description) public {
+        require(status == WorkflowStatus.ProposalsRegistrationStarted, "Le vote n'est pas en cours d'enregistrement des propositions.");
+        require(voters[msg.sender].isRegistered, "Le votant n'est pas inscrit.");
+
+        voterProposals[msg.sender].description = _description;
+        voterProposals[msg.sender].hasVoted = false;
+    }
+
+    function delegateVote(address _delegate) public {
+        require(status == WorkflowStatus.VotingSessionStarted, "Le vote n'est pas en cours de vote.");
+        require(voters[msg.sender].isRegistered, "Le votant n'est pas inscrit.");
+        require(voters[_delegate].isRegistered, "Le delegue n'est pas inscrit.");
+
+        require(msg.sender != _delegate, "Vous ne pouvez pas vous deleguer a vous-meme.");
+
+        delegatedVotes[msg.sender] = _delegate;
+    }
+
+    function voteByDelegation(uint _proposalId) public {
+        address delegate = delegatedVotes[msg.sender];
+        require(delegate != address(0), "Vous n'avez pas delegue votre vote.");
+        require(status == WorkflowStatus.VotingSessionStarted, "Le vote n'est pas en cours de vote.");
+        require(voters[delegate].hasVoted, "Le delegue n'a pas encore vote.");
+
+        voters[msg.sender].hasVoted = true;
+        voters[msg.sender].votedProposalId = _proposalId;
+        proposals[_proposalId].voteCount++;
+        emit Voted(msg.sender, _proposalId);
+    }
+
+}