0

I am facing one issue when interacting with my smart contract. Just to add, I have deployed by smart contract in bsc testnet.

It has two similar functions- enableQuestion & disableQuestion, whose basic functionality is to change the Status of a question. The code is very similar for both, the one difference is that the disableQuestion function is calling one extra modifier 'inStatus'. But similar functionality of 'inStatus' is implemented in enableQuestion as well.

Now when trying to execute these two functions, here are the gas consumptions. The gas required for disableQuestion is insanely high!

enableQuestion -> 0.00069382 BNB
disableQuestion -> 0.285 BNB

Here is the snippet of the code.

modifier inStatus(uint256 _qid, Status _status) {
    require(
        mapQuestions[_qid].status == _status,
        "Operation not valid, invalid question status."
    );
    _;
}

function enableQuestion(uint256 _qid) public onlyOwner validQuestion(_qid) {
    require(
        (mapQuestions[_qid].status == Status.New || mapQuestions[_qid].status == Status.Closed),
        "Operation not valid, invalid question status."
    );
    mapQuestions[_qid].status = Status.Open;
}

function disableQuestion(uint256 _qid) public onlyOwner validQuestion(_qid) inStatus(_qid, Status.Open) {
    mapQuestions[_qid].status = Status.Closed;
}

Can someone please help me understand why this is happening? Also, how can I calculate gas required for each function call ?

UPDATE:

Just saw one more behaviour. The high fee is coming when the condition is failing.

So if I call disableQuestion(1) without calling enableQuestion, the gas is high.
But if I call enableQuestion(1), and then call disableQuestion(1), gas is normal.

8
  • What's the solc version? What's mapQuestions? From the description is seems the function reverts when the state is invalid and that causes extra gas costs.
    – Ismael
    Jan 6, 2022 at 0:07
  • Its deployed in bsc testnet, solidity version is pragma solidity ^0.8.0; mapQuestions is mapping of uint256 and Question struct. mapping(uint256 => Question) public mapQuestions; struct Question { uint256 questionId; uint256 questionCategory; ... }
    – VikasGS
    Jan 6, 2022 at 10:42
  • Also, there seems no reversal as such. Code only checks for the condition, and if it fails, it throws an error.
    – VikasGS
    Jan 6, 2022 at 10:44
  • Can you provide the transactions hashes for failed and successful? My guess is that a failing require causes the changes in gas consumption.
    – Ismael
    Jan 6, 2022 at 15:01
  • I actually never initiated the transaction, as Metamask was showing very high gas fees (0.285 BNB) But when I actually tried, the gas consumed was not that high (the tx failed btw) failed tx (disableQuestion) passed tx (enableQuestion)
    – VikasGS
    Jan 6, 2022 at 18:03

2 Answers 2

0

I am new to smart contracts and blockchain but not to software engineering. Looking at your code would it best to have one function that accepts a boolean for the enable/disable state and then uses a deterministic state machine to only execute valid transitions?

2
  • Agree with your point, one function may suffice usually. But it was done to have clear understanding of what it actually does, as gas fees may vary between these.
    – VikasGS
    Jan 6, 2022 at 10:45
  • 1
    Okay, that makes perfect sense! Thanks. Jan 12, 2022 at 16:30
0

Seems Metamask was predicting very high gas fees. But when transaction was actually executed, it consumed way too less gas.

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.