0

I had to create contract. The description of task is: Voting Contract Create a contract, that: • Is Owned • Can be killed • Uses safe math operations • Has members (people that are member of the contract) • The owner is the first member • The owner can remove members • To add a new member, there needs to be a voting o If >50% of the members agree, the new member is added • For each member we hold: o His address o ETH donated to the contract o Timestamp of last donation o Value of last ETH donation • A member can be removed from the contract if he hasn’t donated to the contract in the last 1 hour • Use a library for all member related actions

The code is as follows:

pragma solidity ^0.4.24;


contract Owned {
    address public owner;

    modifier onlyOwner {
        require(msg.sender == owner, "Only owner!!");
        _;
    }

    constructor (address _owner) public {
        owner = _owner;
    }

}

contract VotingContract is Owned {

    /* --- Structures and variables --- */
    struct Member {
        address member;
        uint donatedETH; // ETH donated to the contract
        uint since; // Timestamp of last donation
        uint lastDonatedETH; // Value of last ETH donation
    }

    mapping (address => uint) public memberId;
    Member[] public members;

    address public owner;

    SafeMathHelper public math;

    // This is a type for a single proposal.
    struct Proposal
    {
        address memberAddress; // address
        //bool voted; // true -> yes, false -> no
    }
    //Proposal[] public proposals;

    /* --- Events --- */
    event MembershipAccepted(string desc, address member, bool isMember);
    event MembershipRemoved(string desc, address member);

    /* --- Modifiers --- */
    modifier onlyMembers {
        require(memberId[msg.sender] != 0);
        _;
    }



    constructor (address _owner) public payable{
        owner = _owner;
        uint id = 0;
        memberId[owner] = 0; // 
        members[id] = Member({member: _owner, donatedETH: msg.value, since: now, lastDonatedETH: msg.value});

    }

    /* --- Functions --- */
    function addMember (address _memberAddress)  
                onlyMembers 
                payable
                public 
                returns(bool) 
                {

        uint id = memberId[_memberAddress];
        if (id == 0) {
            memberId[_memberAddress] = members.length;
            id = members.length++;
        }

        bool votingOfMembers = Voting();
        if (votingOfMembers) {
            members[id] = Member({member: _memberAddress, donatedETH: msg.value, since: now, lastDonatedETH: msg.value});
            emit MembershipAccepted("Member is added", _memberAddress, true);
            return true;            
        } 
        else return false;

    }


    //  To add a new member, there needs to be a voting
    function Voting () public 
            onlyMembers 
            returns(bool) {
        // the member has put true/false to vote for the targetMember
        Proposal[] proposals;
        uint yesVotes = 0;
        uint noVotes = 0;
        uint numOfAllVotes = members.length;
        bool voteYes; // clicked on button YES -> true
        bool voteNo; // clicked on button NO -> true
        bool votedForMember = false;

        while(math.add(yesVotes, noVotes) <= numOfAllVotes){
        //while(yesVotes + noVotes <= numOfAllVotes){
            for (uint i = 0; i < numOfAllVotes; i++) {

                for (uint p = 0; p < proposals.length; p++)
                    {
                    if (proposals[p].memberAddress == msg.sender)
                        {
                            votedForMember = true;
                        }
                    } // votedForMember stays false if member is not voted

                if (!votedForMember ) {
                    // add voted address to proposal:    
                    proposals.push(Proposal({
                        memberAddress : msg.sender
                        //, voted: true
                        }));

                    if (voteYes == true) {
                        yesVotes++;
                    } else if (voteNo == true) {
                        noVotes++;
                    }            
                }
            }
        }

        // If >50% of the members agree, the new member is added
        if (math.div100(yesVotes, numOfAllVotes) < 0.5*100) {
            // no voted
            return false;
        } else {
            return true;
        }

    }


    //The owner can remove members
    function removeMember(address _memberAddress) 
            public
            onlyOwner
        {
            uint id =  memberId[_memberAddress]; // 

            if (id != 0) {
                //remove id from array
                //members[id] = Member({member: _owner, donatedETH: msg.value, since: now});  
                delete  memberId[_memberAddress];
                removeFromMembers(id);
                emit MembershipRemoved("Removed member: ", _memberAddress); 
            }
        }

    function removeFromMembers(uint index) public onlyOwner {
    // returns uint[]
    // if (index >= array.length) return;
        if (index < members.length) {
            for (uint i = index; i<members.length-1; i++){
                members[i] = members[i+1];
            }
            delete members[members.length-1];
            members.length--;
            //return array;
        }

    }

function killContract () public 
                onlyOwner 
                {
        selfdestruct(owner); //Can be killed
    }


}


contract SafeMathHelper {
    // Uses safe math operations
    function add(uint256 a, uint256 b) public pure returns (uint256) {
        uint256 c = a + b;
        assert(c >= a && c >= b);
        return c;
    }

    function mult(uint256 a, uint256 b) public pure returns (uint256) {
        uint256 c = a * b;
        assert(a == 0 || c / a == b || b == 0 || c / b == a);
        return c;
    }

    function div100(uint256 a, uint256 b) public pure returns (uint) {
        // assert(b > 0); // Solidity automatically throws when dividing by 0
        uint c = (a / b) * 100;
        // assert(a == b * c + a % b); // There is no case in which this doesn't hold
        return c;
    }

    function sub(uint256 a, uint256 b) public pure returns (uint256) {
        assert(b <= a);
        return a - b;
    }
}

When I try to deploy VotingContract I'm getting an issue: This contract does not implement all functions and thus cannot be created. I commented all functions of VotingContract one by one (or two of them) to check whether it will be deployed but with no success. No matter which function/functions are commented I was getting the same error.
Any ideas are highly appreciated! Thank you.

1

The issue is that you're never calling the parent constructor. Try this:

constructor(address _owner) Owned(_owner) public payable {
    // ...
}
  • Thank you very much. Now I succeeded to deployed but I've got error: VM error:invalid opcode. – Foretell Jul 9 '18 at 11:59
  • Well yes, your constructor is immediately writing past the end of a zero-length array. This is one of many bugs you'll find in this code. :-) – user19510 Jul 9 '18 at 17:06
  • Would you be so kind to point at the bugs as I'm learning now Solidity? Thank you. – Foretell Jul 10 '18 at 12:25

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.