4

If you create a contract with a function like:

contract MyContract {
  enum MyEnum { Foo, Bar }
  event ThingHappened(MyEnum indexed _e)
  function foo(MyEnum _e) {
    // Code, code code...
  }
}

Solidity compiles that enum variable type down an int8 (unless the enum has more than 8 options, in which case it walks up the int type scale), but that simply changes the signature of the foo function to be:

function foo(int8 _e)

and the event to be:

event ThingHappened(int8 indexed _e)

I'm not seeing a spelling out in the generated ABI JSON somewhere that spells out which int value goes with which enum value (e.g. 0 = Foo, 1 = Bar, etc.).

How best should contracts handle accepting an enum as an argument, or having an enum in an event, to share with the world what those integer values map to?

3

You can create some getters to return the string representations of your enum.

Example:

contract MyContract {
  enum MyEnum { Foo, Bar }

  event ThingHappened(string _e);

  function getMyEnumKeys() public constant returns (string, string) {
    return ("Foo", "Bar");
  }

  function getMyEnumKeyByValue (MyEnum myEnum) public constant returns (string) {
    if (MyEnum.Foo == myEnum) return "Foo";
    if (MyEnum.Bar == myEnum) return "Bar";
    return "";
  }

  function getMyEnumValueByKey (string myEnum) external constant returns (MyEnum) {
    if (sha3(myEnum) == sha3("Foo")) return MyEnum.Foo;
    if (sha3(myEnum) == sha3("Bar")) return MyEnum.Bar;
    revert();
  }

  function foo(string _e) {
    MyEnum myEnum = getMyEnumValueByKey(_e);
    // do something with myEnum
    ThingHappened(_e);
  }
}

However, I think the best solution would be to just have it in your public documentation that Foo is 0 and Bar is 1.

| improve this answer | |
0

Publish the source with the enum definition. That's enough for devs to determine the corresponding int (plus a reference in whatever docs you release).

ENS took that approach in the source code for auction status:

enum Mode { Open, Auction, Owned, Forbidden, Reveal, NotYetAvailable }
...
function state(bytes32 _hash) constant returns (Mode) {

They provide more explanation in the docs:

This will return a single integer between 0 and 5. The full solidity data structure for this can be viewed here in the Registrar contract. The numbers represent different ‘states’ a name is currently in.

  • 0 - Name is available and the auction hasn’t started
  • 1 - Name is available and the auction has been started
  • 2 - Name is taken and currently owned by someone
  • 3 - Name is forbidden
  • 4 - Name is currently in the ‘reveal’ stage of the auction
  • 5 - Name is not yet available due to the ‘soft launch’ of names.
| improve this answer | |
0

There's a better way. Let's say you have contract A and want to use his enum in contract B. Here's how:

contract A {
   enum MyItems { Example, NewOne }
}

contract B {
   function getItems() public {
      // Here the enum will be available with A.MyItems
      A.Myitems;
   }
}

Essentially you can access an enum by using the ContractName.EnumName when they are in the same file.

| improve this answer | |

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.