Get array with address list from EnumerableSet.sol

I would like to manage an account list (ethereum addresses) with EnumerableSet.sol

https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/utils/structs/EnumerableSet.sol”;

I would like a function to get the array with the list of all accounts. Normally I just do …

    function getBlacklistedAddresses() public view returns(address[] memory) {
        return blacklistedAddresses;
    }

but how do I do that with the array in the struct of EnumerableSet.sol ?

1 Like

@abcoathup Any ideas ??

1 Like

Hi @sven.meyer,

As far as I know you have to enumerate the set.

Hello @sven.meyer

There is a way to retrieve the values as an array, but that will be a bytes32 array. The only difference, is that you’ll have to cast them from bytes32 to address when using them … but otherwise it works.

import "https://github.com/OpenZeppelin/openzeppelin-contracts/blob/v4.0.0/contracts/utils/structs/EnumerableSet.sol";

contract EnumerableSetArray {
    using EnumerableSet for EnumerableSet.AddressSet;
    EnumerableSet.AddressSet internal _set;
    
    function add(address value) public returns (bool) {
        return _set.add(value);
    }

    function remove(address value) public returns (bool) {
        return _set.remove(value);
    }
    
    function getArray() public returns (bytes32[] memory) {
        return _set._inner._values;
    }
}

Note: this array is supposed to be for internal use. I don’t think there is any issue with reading from it, but you should not write to it, as it might break the enumerable set.

1 Like

@Amxx thanks a lot for pointing that out !
I was close but thought I could return address[]
Can I cast the whole array to address[] or bytes20 before returning?

Anyway, it would be great if returning the whole address array would be supported by EnumerableSet.AddressSet. Wouldn’t that be one of the “standard use cases”

1 Like

EnumerableSet.AddressSet, and the other Bytes32Set and UintSet, are a wrapper around EnumerableSet.Set. This is to avoid issues that would be caused by code duplication. The downside is that the underlying storage in bytes32[] and AFAIK there is no simple way to cast that.

I really hope solidity introduces templates at some point. Until then, you may find an option in my SolStruct sideproject. This won’t solve your issue if you are trying to manipulate a structure that is part of an OZ contract, but it might be a solution if what the struct you are working on doesn’t interact with OZ.

1 Like

thanks for the follow-up.
I was actually thinking about just copying the OZ lib and replacing bytes32 with address, however your repo actually looks like how that would look like, might actually exactly do what I was looking for !

1 Like