0

I apologize if this has been asked already. It seems like a very basic question but I cannot find an answer to it. Every example of using a modifier to create a "ownerOnly" function uses the "owner = msg.sender" in the constructor, but what if I want to allow a few different addresses/people to modify a contract or execute a function. How do I write the modifier to do this? I tried this, but it didn't work:

modifier onlyMembers {
    require(msg.sender == owner || "0xdaa602d3e2aeea57ee753e40ac1639ed20e3174f" || "0x3147ca98dc9235e38c4cd3f82315332294e9234a");
    _;
}

I also tried using checksum addresses and created new, global address variables called "member1" and "member2" which point to those addresses like this:

contract Autos {

address owner;
address member1;
address member2;

constructor() public {
    owner = msg.sender;
    member1 = 0xDAA602D3E2Aeea57eE753E40AC1639eD20e3174F;
    member2 = 0x3147cA98dc9235e38c4cd3F82315332294e9234A;
}

modifier onlyOwner {
    require(msg.sender == owner || member1 || member2);
_;

}  

Remix tells me "Operator || not compatible with types bool and address", but I feel like there must be a way to "or" the addresses somehow.

1

You are almost on the right path!

The correct syntax would be

modifier onlyOwner() {
    require(msg.sender == owner || msg.sender == member1 || msg.sender == member2);
    _;
}

While that would work, it would get a bit repetitive, so you could opt for something like the following which would easily allow multiple members and a single owner owner.

    address public owner;
    mapping (address => bool) public members;


    modifier onlyMembers() {
        require(msg.sender == owner || members[msg.sender] == true);
        _;
    }

The above is very extendable, and would allow you to update the members mapping as needed (removing/adding members) and the onlyMembers() modifier would still work.

edit:

One thing to keep in mind about evaluating boolean values, when you are evaluate a single condition the following syntax works require(someValue); however when evaluating multiple boolean conditions, you will need to be explicit about the condition, see:

require(someValueOne == false && someValueTwo == true && someValueThree == false);

  • Thank you. I am guessing, as well, that while "require(someValue)" would work, even this would only work if I needed someValue to be true. In other words, if I wanted it to be false, I would have to write "require(someValue == false)"? – CreatedAMadman May 29 '18 at 6:18
  • you could write require(!somevalue) – Jaime May 29 '18 at 7:36
  • Yea Jaime is correct require(!someValue) would work, but if multiple require(someValueOne == false && someValueTwo == false); – hextet May 29 '18 at 17:13
-1

contract Autos {

address owner;
address[] members;
uint counter = 1;
mapping (address => bool) public owners;

constructor() public {
    owner = msg.sender;
    members = [0xca35b7d915458ef540ade6068dfe2f44e8fa733c,0x14723a09acff6d2a60dcdf7aa4aff308fddc160c];
    for (uint i=0; i lessthan members.length ; i++)
    {
     owners[members[i]]=true;
   }
}

function incCounter() onlyOwner {
       counter++;
   }
    function showCount() view returns(uint){
        return counter;
    }

modifier onlyOwner {
    require(owners[msg.sender]);
_;

}  
}

It will work fine.

Keep in mind that what ever the variable you want to use it should be stored in storage or memory allocated to a contract. It will be stored only if the transaction is executed.

This code will help you figure your own logic.

  • This is very unsafe, and if just one member becomes malicious they can overflow the members array, thereby creating the ability to alter other records. – hextet May 29 '18 at 17:15

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

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