3

I'am trying to create a modifier that allows certain accounts to execute functions.

 address[] authorized; 
       function verify (address adrs) internal view returns (bool)
{
    bool exist;
    uint  j=authorized.length;
    uint i =0;
    exist = false;
    address[] memory adrss;
    while (i<j){
        uint x =0;
        if (adrss ==address[i]){
            bool = true;
        }
        i++;
    }
    return exist;
}



  modifie allowed (address adrs){
        require  (  verify(adrs)==true);
                    _; }

anyone how has an idea?

Rob Hitchens
  • 55,151
  • 11
  • 89
  • 145
MS B
  • 196
  • 2
  • 9
  • 1
    Hi there. I haven't tried it, but it's clear the above code doesn't compile. Is your question "How do I get this code to compile?" or, more generally, "What is the best way to implement an ACL?". Please be more specific with your question: https://ethereum.stackexchange.com/help/how-to-ask – Richard Horrocks Jul 04 '19 at 15:52

3 Answers3

5

You should avoid iterating the list of permitted accounts. It's an expensive approach that doesn't scale and it has a lot of moving parts.

Consider instead using a mapping. This is a namespace where all the uninitialized indexes return false, 0, empty, depending on type. For example:

mapping(address => bool) public whitelist; returns true or false for each address, and you can set/get without iterating.

pragma solidity 0.5.1;

contract SimpleWhitelist {

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

    event LogProtected(address sender);

    modifier onlyOwner {
        require(msg.sender == owner, "You are not the owner.");
        _;
    }

    modifier onlyWhitelist {
        require(whitelist[msg.sender], "You are not whitelisted.");
        _;
    }

    function setPermission(address user, bool isAllowed) public onlyOwner {
        whitelist[user] = isAllowed;
    }

    function protected() public onlyWhitelist {
        emit LogProtected(msg.sender);
    }    
}

There are more advanced ways to store the list of whitelisted addresses: Are there well-solved and simple storage patterns for Solidity? and de facto standard implementations of the Ownable concept but I wanted to keep this as simple as possible.

  1. Only the owner is allowed to grant/revoke permission.
  2. Only whitelisted addresses are allowed to run protected(). It will emit an event on success.

Hope it helps.

Rob Hitchens
  • 55,151
  • 11
  • 89
  • 145
2

You are making a fundamental mistake which makes it all seem much harder than it really is. Instead of an array, your should use a mapping(address => bool), let's call it whitelisted.

Add people in the whitelist like this: whitelisted[_address] = true;

then in your modifier, you can simply do this:

require(whitelisted[_address]);
blackscale
  • 383
  • 2
  • 8
  • 1
    No need to convert through uint160). if(addr1 == addr2) { ... should work if both are addresses. – Rob Hitchens Jul 04 '19 at 17:16
  • 1
    You are correct, that trick is useful for comparing short Strings cheaply, and I made some confusion. I edited out that part, as anyway it was slightly besides the OP's topic. – blackscale Jul 04 '19 at 20:14
2

I recommend that you look at the OpenZeppelin guide on Access Control, specifically the section on Role-Based Access Control as using Roles from OpenZeppelin appear to meet your needs. https://docs.openzeppelin.org/v2.3.0/access-control

For questions on use, you can also ask in the community forum https://forum.zeppelin.solutions/

abcoathup
  • 1,338
  • 5
  • 11