Solidity Gas Efficiency – Using Multiple Setter Functions vs a Single Generic One

enumfunctiongas-pricesolidity

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.

Best Answer

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.

Related Topic