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?

2

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.

  • Thanks for the advice, but wouldn't it be too expensive in terms of gas? – Sergei Tikhomirov Nov 18 '16 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. – Tjaden Hess Nov 18 '16 at 12:34
9

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

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"));

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.