# Create extension for utility struct

**URL:** <https://forum.openzeppelin.com/t/create-extension-for-utility-struct/11472>\
**Category:** Review Wanted\
**Created:** [June 28, 2021, 9:38am UTC](https://forum.openzeppelin.com/t/create-extension-for-utility-struct/11472 "2021-06-28T09:38:35Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![dirathea](https://sea2.discourse-cdn.com/flex022/user_avatar/forum.openzeppelin.com/dirathea/32/7158_2.png) [@dirathea](https://forum.openzeppelin.com/u/dirathea)\
**Post date:** [June 28, 2021, 9:38am UTC](https://forum.openzeppelin.com/t/create-extension-for-utility-struct/11472/1 "2021-06-28T09:38:35Z")

</div>

Hi folks,

I’m currently developing my own smart contracts, and I saw the smart contract utility from openzeppelin there is an utility for EnumerableSet, but there is lack of type. I’m trying to recreate it for EnumerableSet for type String as follows

```auto
library EnumerableSetString {
   // Inspired from the original EnumerableSet
  struct Set {
    // Storage of set values
    string[] _values;

    mapping (string => uint256) _indexes;
  }

  // the rest function is very similar, just changed the parameter type accordingly
  function _add(Set storage set, string memory value) private returns (bool) {
    if (!_contains(set, value)) {
      set._values.push(value);
      // The value is stored at length-1, but we add 1 to all indexes
      // and use 0 as a sentinel value
      set._indexes[value] = set._values.length;
      return true;
    } else {
      return false;
    }
  }

  struct StringSet {
    Set _inner;
  }

  // Public method
  function add(StringSet storage set, string calldata value) internal returns (bool) {
    return _add(set._inner, value);
  }

  //The rest has functions like _remove, _contains, _length, _at
}

```

What do you folks think? Why this is not included by default on OpenZeppelin libs? Any suggestions, feedback, very much appreciated.

---

<div class="post-metadata">

**Author:** ![frangio](https://sea2.discourse-cdn.com/flex022/user_avatar/forum.openzeppelin.com/frangio/32/15251_2.png) [@frangio](https://forum.openzeppelin.com/u/frangio)\
**Post date:** [June 29, 2021, 7:48pm UTC](https://forum.openzeppelin.com/t/create-extension-for-utility-struct/11472/2 "2021-06-29T19:48:28Z")

</div>

We’ve included types for which we are aware of good use cases. Please share what you plan to do with this enumerable set!

You don’t need to separate between `Set` and `StringSet`. It’s built that way in OpenZeppelin Contracts because we needed to write it in a generic way for multiple types.

---

<div class="post-metadata">

**Author:** ![dirathea](https://sea2.discourse-cdn.com/flex022/user_avatar/forum.openzeppelin.com/dirathea/32/7158_2.png) [@dirathea](https://forum.openzeppelin.com/u/dirathea)\
**Post date:** [July 1, 2021, 2:18am UTC](https://forum.openzeppelin.com/t/create-extension-for-utility-struct/11472/3 "2021-07-01T02:18:47Z")

</div>

I want to create a ERC 721 NFT Smart Contract for my next project. It’s something like continuity of my NFT that created on opensea using their shared smart contract.

What I want to do is people that already hold token from my previous project on opensea could mint their own token on my next project on my site. But I need a way to verify it securely, and I’m thinking do it on the contract itself. So this enumerable string set will holds the “valid” token, then it will be removed one by one once the user mint it.

I haven’t really test this code, but I think something like

```auto
function mint(address to, string calldata validToken) public returns (uint256) {
    // Check valid token, This is the enumerable instance that holds all the valid token
    require(validTokens.contains(validToken));

    // Remove the token
    validTokens.remove(validToken);

    // ERC-721 normal flow to create new token.
    _tokenIds.increment();
    uint256 nextToken = _tokenIds.current();
    _mint(to, nextToken);
    return nextToken;
  }

```

what do you think @frangio ? I’m very open for any feedback for this approach.

---

<div class="post-metadata">

**Author:** ![frangio](https://sea2.discourse-cdn.com/flex022/user_avatar/forum.openzeppelin.com/frangio/32/15251_2.png) [@frangio](https://forum.openzeppelin.com/u/frangio)\
**Post date:** [July 1, 2021, 8:26pm UTC](https://forum.openzeppelin.com/t/create-extension-for-utility-struct/11472/4 "2021-07-01T20:26:54Z")

</div>

Using strings sounds a little weird. I encourage you to check out our workshop on NFT airdrops, I think it’s very much aligned with what you want to do! Recap and video are on our blog.

> **[Workshop Recap: Building an NFT Merkle-Drop](https://blog.openzeppelin.com/workshop-recap-building-an-nft-merkle-drop/)**
>
> Upgradeable contracts allow us to alter a smart contract to fix a bug, add additional features, or simply to change the rules enforced by it. Smart contract upgrades can be managed using OpenZeppel…

---

<div class="post-metadata">

**Author:** ![dirathea](https://sea2.discourse-cdn.com/flex022/user_avatar/forum.openzeppelin.com/dirathea/32/7158_2.png) [@dirathea](https://forum.openzeppelin.com/u/dirathea)\
**Post date:** [July 5, 2021, 6:46am UTC](https://forum.openzeppelin.com/t/create-extension-for-utility-struct/11472/5 "2021-07-05T06:46:45Z")

</div>

hi @frangio, thanks for your links. I think I could use that approach, even my use cases a little different. In my case, user need to be able to prove that they poses a pair of tokens from my previous project, I think I’ll do the verification process off chain to safe some gas, but I’ll do the merkletree verification on the contract to make sure everyone pair of token will will be converted (or minted) to be a single token.
