[Ethereum] How to minimize gas consumption during contract creation

contract-deploymentcontract-developmentgas-estimategas-limitout-of-gas

I have trouble deploying a contract to the main network and I believe this is due to high gas consumption.
An earlier version of the contract worked on the main network. The current version works in my private testnet (created with geth --dev).
On the testnet these contract creations use about 2.4 million units of gas. I tried to deploy it on the main net with 2 million gas at first and got an out of gas exception (TA got mined though, contract creation just was not successful).

After that I tried it with 3 million and got this (not mined):

"{"jsonrpc":"2.0","error":{"code":-32010,"message":"Transaction cost exceeds current gas limit. Limit: 2200000, got: 3000000. Try decreasing supplied gas.","data":null},"id":1}[\n]"

I am completely stuck and have no idea how I can deploy my contract now. Mainly I have two questions:

  1. Why can I send a TA with 2.4 million gas to the testnet but not to the main-net. I know they are different chains, but shouldn't it use the same logic for TA-validation? How can I send TAs with 3mill gas limit to the main network?
  2. I don't understand why my contract requires this much gas. It's only 264 lines of code. It's three mappings, two structs, five enums, one event and a few relatively simple functions. How can I figure out which part of my contract is using up so much gas? Is there a tool for that?

Best Answer

The reason why geth refuses to send the transaction is because the block gas limit varies. On a private testnet, it can be anything, but by default it'll be 5.5 million. On the mainnet, it's currently only 2 million--so a 3 million gas transaction just wouldn't fit at all. This is because of the recent spam attacks on the network--the developers asked miners to reduce the limit, and they did. Hopefully, the miners will increase it back to the default after the incoming hardfork. (I say "hopefully" because it's the miners' decision, the devs can only suggest.)

The only things that use gas at creation time are what happens in the constructor, and the size of the compiled code itself. You might be able to reduce the size by turning on the optimizer, but it's quite possible it's already on.

I'm not that surprised at the figure it's giving, though. 264 LoC is actually a lot in Ethereum. I have a 400~ LoC contract that is 3~ million gas optimized.

There's three ways of reducing gas cost:

  1. Simplify the contract. This might be impossible, depending on what exactly you're doing.
  2. Split it into multiple contracts.
  3. Refactor it to use libraries. If you're using lots of structs and mappings, this may make your code remarkably more readable.

The simplest way may be just to wait. You're not the only one who is stuck with big contracts, so the miners have an incentive to raise the gas limit again, and soon.

Related Topic