6

When trying to compile the following code in browser-solidity:

pragma solidity ^0.4.4;

contract TestContract {
    enum TestEnum { ONE, TWO, THREE }
    mapping (TestEnum => uint) testMapping;
}

I get the following error:

Untitled:5:14: Error: Expected elementary type name for mapping key type
    mapping (TestEnum => uint) testMapping;

Solidity documentation does not seem to forbid using enum as mapping key type, stating that "_KeyType can be almost any type except for a mapping":

https://solidity.readthedocs.io/en/develop/types.html?highlight=mapping#mappings

How can I implement a mapping with a custom enum as the key type?

Closely related: Is it possible to have user-defined Struct as a _KeyType in a Mapping in Solidity? Is it possible to have a mapping with a hash as key?

1

5 Answers 5

3

That feature is not currently implemented. A simple workaround is to do

pragma solidity ^0.4.4;

 contract TestContract {
    enum TestEnum { ONE, TWO, THREE }
    mapping (bytes32 => uint) testMapping;

    function getValueOne() constant returns(uint) {
        return testMapping[sha3(TestEnum.ONE)];
    }

}

Just use the hash of the enum for the key instead of the actual enum item, and it will work fine.

2
  • Thanks for the advice, but wouldn't it be too expensive in terms of gas? Nov 18, 2016 at 11:04
  • 1
    Not really, try it out. SHA3 is actually very cheap, and it's how mappings work under the hood anyways. Were talking like < 100 gas. Nov 18, 2016 at 12:34
11

Rather than using the hash of the enum as the key, you could just explicitly cast the enum to uint. Because the actual uint size the compiler uses is just big enough to hold all enum values, it will be uint8 for TestEnum but you do not have to specify that. I mention that just to highlight that the key will be only 1 byte instead of 32 bytes.

(Ref: http://solidity.readthedocs.io/en/develop/types.html#enums)

For example:

pragma solidity ^0.4.4;

contract TestContract {
    enum TestEnum { ONE, TWO, THREE }
    mapping (uint => uint) testMapping;

    function getValueOne() constant returns(uint) {
        return testMapping[uint(TestEnum.ONE)];
    }
}
1
  • Does the key being just 1 byte matter? Won't the key still be padded to 32 bytes to fill a slot?
    – Pottedtree
    Jun 25, 2021 at 2:37
1

Enum or structure are not supported as mapping keys in solidity. it supports only elementary types, in the doc they say 'Almost' not all types. you could look at the solidity parser code :

ASTPointer<Mapping> Parser::parseMapping()
{
    ASTNodeFactory nodeFactory(*this);
    expectToken(Token::Mapping);
    expectToken(Token::LParen);
    ASTPointer<ElementaryTypeName> keyType;
    Token::Value token = m_scanner->currentToken();
    if (!Token::isElementaryTypeName(token))
        fatalParserError(string("Expected elementary type name for mapping key type"));
0

Yes, this feature is available since the Solidity version 0.6.3. Refer to this answer Enum as key in mapping now allowed?

0

Enum as keys in a mapping were added in Solidity v: 0.6.3

pragma solidity ^0.6.3;

contract TestContract {
    enum TestEnum { ONE, TWO, THREE }
    mapping (TestEnum => uint) testMapping;

    function getValueOne() public view returns(uint) {
        return testMapping[TestEnum.ONE];
    }
}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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