Is it possible to access the length of an enum in solidity? E.g.

pragma solidity >=0.4.16 <0.6.0;

contract test {
    enum ActionChoices { GoLeft, GoRight, GoStraight, SitStill }

    function move(uint8 _actionChoice) public {
        require (_actionChoice < ActionChoices.length);

  • 1
    Add Last and then use _actionChoice < ActionChoices.Last. Sep 1 '19 at 11:28
  • I like the idea but looking for something that is less of a hack ;)
    – Senju
    Sep 1 '19 at 18:50
  • 1
    It's not a hack. It's used in pretty much every typed-language (C, C++, Java, etc). And Solidity is under that category. Sep 1 '19 at 19:16
  • If I add Last to the enum it is actually another enum I technically would be able to use as an ActionChoice, right? That should not be possible.
    – Senju
    Sep 2 '19 at 14:01
  • Yeah well, you could use any other value as well, when called from the off-chain (i.e., via a web3 script). In fact, you could even do it from the on-chain (i.e., from a contract), but that would require you to explicitly cast the integer value to ActionChoices, so you're kinda protected there. But like I said, from an off-chain script, there is no way to prevent that, besides checking in the contract that it is equal to one of your enum values (or, if you don't explicitly give them values, by checking that it is smaller the Last, as I have suggested). Sep 2 '19 at 14:13

enum is an integer, so the integer value of the last item plus 1 is the length.

You can also make the function argument typesafe.

function move (ActionChoices choice) ...

That will constrain the range of allowable inputs so you don't need the require.

Hope it helps

  • what if I add another enum later on, how do I know which is the last?
    – Senju
    Sep 1 '19 at 20:10
  • 1
    You can't add "later on". They are hard-coded into your "finished" smart contract and immutable bytecode. Sep 1 '19 at 20:39
  • Well. Let's say I upload another version of this contract later on I add one more enum in it. If in the function the specific "item plus 1" is not the last element anymore, it will not be the last element anymore - so I gotta remember to not only change the enum but also the function. Just trying to write clean code. I guess a helper function like getLastEnum would help. Any other idea? Otherwise your answer is a correct solution I was looking for.
    – Senju
    Sep 2 '19 at 14:00
  • Not from an off-chain script, AFAIK (i.e., you could call it via web3 with any integer value; without some sort of assertion in the contract's function, it will not be prevented). Sep 2 '19 at 14:16
  • @RobHitchens-B9lab if the enum is set to an out of range value (without any type of prior validation) the transaction reverts and uses the full gas limit. ethereum.stackexchange.com/questions/80350/…
    – Nick
    Mar 5 '20 at 11:44

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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