0

Let's say I have an enum and set the default:

enum Status {
    INACTIVE,
    FAIL,
    SUCCESS,
    PENDING
}

Status public myStatus = Status.INACTIVE;

I'm wondering if one approach to updating myStatus is "better" than the other in terms of gas and just best practice:

Approach A

Have one generic setter function that accepts a value:

function setStatus(uint256 _status) external onlyOwner {
    require(_status <= uint256(Status.PENDING), "Status out of bounds");
    myStatus = Status(_status);
}

Approach B

Have individual setter functions:

function setStatusToInactive() external onlyOwner {
    myStatus = Status.INACTIVE;
}

function setStatusToFail() external onlyOwner {
    myStatus = Status.FAIL;
}

function setStatusToSuccess() external onlyOwner {
    myStatus = Status.SUCCESS;
}

function setStatusToPending() external onlyOwner {
    myStatus = Status.PENDING;
}

With B, you can strictly control the setters and have no need for require statements. Any front-end interacting with the contract will not need to be aware of the enum and instead just call the appropriate function.

With A, does it cost less gas to deploy? Does it have any effect? Should you not add "unnecessary" functions like in B? In a scenario where there are many values in the enum, B becomes unmanageable if you need a setter for every one.

1 Answer 1

0

You can do it with A and an enum.

function setStatus(Status status) external onlyOwner {
  myStatus = status;
  emit ... 
}

By casting the input as an enum you get a similar effect as your require and you avoid the convoluted type conversions. The internal enum creates an external uint8 because the list "fits" in a uint8. From a client-side perspective, they pass 0, 1, 2, etc. as a uint8 as you would expect.

While there are arguments for B around user-friendliness in some cases (enable/disable?), that's a subjective call. It will increase deployment cost to increase the contract size so I would avoid using it for long lists. General heuristic - always aim for simplicity.

Hope it helps.

1
  • 1
    Ah I didn't know that the client could pass a uint8 and the contract function would cast based on the parameter type (guessing that is specific to enum in solidity). Thanks for your help! Mar 23, 2022 at 18:18

Your Answer

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

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