0

I am writing a token that inherits from Whitelist.sol. I would like to write a function that returns an array of addresses that are whitelisted.

It must be something along the lines of

function getWhitelistedUsers() public onlyOwner returns (address[]) {

    address[] memory whitelistedUsers = Roles[ROLE_WHITELISTED].bearer.keys();
    return whitelistedUsers;
}

but I am not sure I am on the right path. Can somebody help?

Raghav Sood
  • 4,040
  • 2
  • 11
  • 20
hans
  • 1

2 Answers2

1

Just to elaborate on Ismael's answer.

They provide a way for contracts to check a specific address/role (hasRole() ... returns(bool)) but no way to enumerate lists of role members from the state. The lists are not discoverable by other contracts. The authors don't think it's necessary.

The RBAC (role-based access control) contract emits events when an address/role is added or removed. At line 20 in RBAC.sol:

event RoleAdded(address indexed operator, string role);
event RoleRemoved(address indexed operator, string role);

Software clients can listen to these event logs and assemble their own reconstructed role lists as needed. As I write this answer, it occurs to me that these logs obfuscate the operator because it's indexed in both cases.

To accomplish what you want, I'd be tempted to remove indexed so the listener can clearly observe the addresses without knowing them in advance. That would give an interested observer everything needed to conveniently construct their own off-chain copy of the on-chain facts. They could then count them, sort them, search them, etc., without further help from the contract.

A case can be made for a "completely discoverable" state. You can accomplish it by creating (and maintaining) lists. You would need to indexes with a delete capability, as describe here. Are there well-solved and simple storage patterns for Solidity? and here
https://medium.com/@robhitchens/solidity-crud-part-2-ed8d8b4f74ec.

Hope it helps.

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

No, it is not possible, bearer is a mapping and keys are not stored.

struct Role {
  mapping (address => bool) bearer;
}

If you need to access keys for a mapping you need to explicitely store them in a separate structure.

Ismael
  • 30,570
  • 21
  • 53
  • 96