1

I am trying to deploy my contract by enabling the optimizer to see how much I can save from the gas costs.

I am using truffle for the deployment. In truffle I enable the optimizer by the following setting in truffle-config.js:

  compilers: {
    solc: {
      version: '^0.5.0',
      settings: {
        evmVersion: 'byzantium' // Default: "petersburg"
      },
      optimizer: {
        enabled: true,
        runs: 500
      }
    }
  }

To compile the contracts and deploy them again I execute:

truffle compile --all

and

truffle migrate --reset --network develop

However, both with optimizer enabled or disabled I get the exact same number gas used when deploying:

   > gas used:            2199134
   > gas price:           20 gwei
   > value sent:          0 ETH
   > total cost:          0.04398268 ETH

So I thought, maybe there's nothing to optimize. But interestingly, if I try the optimizer in Remix I see changes. I use the default compiler 0.5.12+commit.8809ece9 in Remix:

Without optimization in Remix:

 gas    2037733 gas 
 transaction cost   2037733 gas 
 hash   0xd4d34170c7c234cea900dcad62ac....

Turning optimizer on:

 gas    1531138 gas 
 transaction cost   1531138 gas 
 hash   0xb5f2bb985e0dfd29b1947c14fc949bab314...

I suppose there's something wrong with truffle or I can't command truffle to recompile with the optimizer. What could be the issue?

Edit:

I've tried adding a deliberate error to the truffle-config.js to see if truffle recognizes the new file and it works, it throws an error.

Removing build/ folder between compile and deploys had no effect.

I also checked bytecodes by enabling and disabling the optimizer and the they are exactly the same.

Very interestingly a day later, the total gas consumed for deployment changed. In this case, the optimizer was enabled initially. So I tried rebooting and disabling the optimizer but did not observe any change in bytecode or deployment costs.

   > gas used:            1857253
   > gas price:           20 gwei
   > value sent:          0 ETH
   > total cost:          0.03714506 ETH

Edit 2 Another thing I tested is if the compile --all command works, i.e. if truffle indeed force compiles even if the code does not change. To do that I've ran 6 compile&migrates. Each time I included an else block or removed it, or enabled or disabled the optimizer, or both. The optimizer runs 1500 times.

|                        | Test 1  | Test 2  | Test 3  | Test 4  | Test 5  | Test 6  |
|------------------------|---------|---------|---------|---------|---------|---------|
| Else block included?   | Yes     | Yes     | No      | No      | Yes     | No      |
| optimizer enabled?     | No      | Yes     | Yes     | No      | No      | Yes     |
| Deployment cost in ETH | 0,04766 | 0,04766 | 0,04709 | 0,04709 | 0,04766 | 0,04709 |

This shows compile --all is not the issue as Test 5-->Test 6 yields the same ETH cost: forcing to compile optimized by changing the contract code and enabling optimizer at the same time results same as just changing the contract code.

Edit 3

Tried changing the EVM version in truffle-config.js. The deployment costs do change. It's only enabling the optimizer that does not cause any change at all.

7
  • The title of your question says the bytecode doesn't change with and without optimization. The body of your question does not mention anything about the bytecode, and instead refers to deployment gas cost. Please fix this inconsistency in order to clarify your question. While you're at it, please check whether or not the bytecode changes as a result of enabling/disabling optimization. Commented Jan 20, 2020 at 15:28
  • Hi thanks for the comment. I've thought this would imply the bytecodes are the same but nevertheless checked both bytecodes and they are exactly the same.
    – kuzdogan
    Commented Jan 21, 2020 at 10:13
  • I would take the liberty to guess that truffle compile doesn't refer to the truffle-config.js file that you think it does, OR that your second call to truffle compile (i.e., when you compile with optimization after compiling without optimization) doesn't do anything because all binaries are already up to date. In order to rule out the first option, you can insert a deliberate error into your truffle-config.js file and check whether truffle compile still runs successfully. In order to rule out the second option, you can delete the entire build folder in between your compilations. Commented Jan 21, 2020 at 10:18
  • Make sure to save a copy of the first binary before deleting that folder, so you can compare it with the second binary. Commented Jan 21, 2020 at 10:19
  • My initial thought was that as well and adding a typo did throw an error. Also removing build had no effect. Saving bytecode outputs and adding this to the question description as well thanks for mentioning.
    – kuzdogan
    Commented Jan 21, 2020 at 10:36

1 Answer 1

9

Obviously it is really simple: The optimizer settings are in the wrong place. I used the example provided here but according to the documentation it needs to be under settings:{...} in the solc config.

So this:

  compilers: {
    solc: {
      version: '^0.5.0',
      settings: {
        evmVersion: 'byzantium' // Default: "petersburg"
      },
      optimizer: {
        enabled: true,
        runs: 1500
      }
    }
  }

Becomes this:

  compilers: {
    solc: {
      version: '^0.5.0',
      settings: {
        evmVersion: 'byzantium', // Default: "petersburg"
        optimizer: {
          enabled: true,
          runs: 1500
        }
      }
    }
  }

Will be requesting a fix in above StackExchange question. Hope this will save someone a couple of hours.

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.