I'm trying to deploy a contract on the mainnet, but I've been getting some issues deploying with Truffle.

➜  ballot git:(master) ✗ truffle migrate --network mainnet --dry-run
Using network 'mainnet' (dry run).

Running migration: 1_initial_migration.js
  Deploying Migrations...
Error encountered, bailing. Network state unknown. Review successful transactions manually.
sender doesn't have enough funds to send tx. The upfront cost is: 670197500000000000 and the sender's account only has: 120000000000000000

According to this error, deploying the contract would cost 0.67 ETH (~US$750). I find this very hard to believe.

Does code complexity influence the deployment price? Not sure what else it would be.

  • It seems that Truffle is asking for a ridiculous gas price to pay for deploying the contract. I tried adjusting the gasPrice setting in truffle.js to something lower (21 Gwei), but nothing changes. Still unsure why that happens. – V. Kartoplya Jan 9 at 8:15
  • You may use remix for estimating the transaction cost for your contract. And even deploy the contract from remix. – Prashant Prabhakar Singh Jan 29 at 13:09
  • 2
    If Ethereum node estimates the gas cost to be the max cost of gas per block it usually means your code is faulty in some way and would cause Invalid jump (require(), throw, or some other form of an exception) – Mikko Ohtamaa Jan 30 at 12:57

The cost of your deployment is based on 5 things, with a 6th affecting the estimated cost of deployment:

  1. The flat fee of 32k gas. The CREATE op code, which is called during contract creation, costs a fixed 32k gas. This is of course on top of the 21k gas of a normal tx. Note: During contract creation from an EOA (non-contract address), the CREATE opcode isn't explicitly called. The return value of the tx is actually used to create the contract, but the fixed 32k fee is the same.

  2. The amount of bytecode in the compiled contract. More bytecode means more storage, and each byte costs 200 gas. This adds up very quickly. Note that inherited parent contracts are also included in the bytecode.

  3. The TX data. All the bytecode your sending as tx data costs 64 for non-zero bytes and 4 for zero bytes.

  4. The code actually run before creation of the contract, e.g. the constructor of the contract. If the constructor requires a lot of computation to generate the bytecode, then it'll be extra expensive.

  5. The gas price. The higher gas price you use, the higher it'll cost. See ethgasstation.info for good gas prices to use right now. At the time of writing, 2 gwei is a quick gas price to use.

  6. Gas limit. Let whatever tool you're using for deployment estimate this for you, and then bump it up some. It'll return the unused gas, but just make sure you supply at least how much gas it needs or it'll fail and you'll still pay for the gas.

Overall if you were deploying a contract with a simple constructor and 5k bytes of compiled bytecode, you'd be paying roughly:

CREATE 32k

TX 21k

CONTRACT CODE 5k*200

ESTIMATED NON-ZERO TX BYTES 5.5k*(.95*64)

ESTIMATED ZERO TX BYTES 5.5k*(.05*4)

CONSTRUCTOR 1k

This comes out to ~1.38 million gas, which is less than $5 USD right now. Gas prices were 20x what they are now a couple weeks ago, so you could have paid $100 for the same contract creation.

You can read more about the bytecode based costs in the yellow paper

If you need help optimizing contracts, I'd be willing to help, but not for free.

Edit: Added #3 between #2 and #4

You should test your deployment process on private network or test network throughly before trying mainnet. I am testing mine on Rinkeby because in Ropsten block gas limit is too low.

In my experience gasPrice setting in truffle.js is effective. I have successfully deployed my contracts using the following syntax:

    geth_mainnet: {
      host: "127.0.0.1",
      port: 8545, // geth-mainnet
      network_id: "1",
      gasPrice: 2000000000, // 2 GWei
      from: "0x...your-address-goes-here..."
    }

See 2'505'437 Gas * 2 Gwei = $6 and 5'435'035 Gas * 2 Gwei = $13.

Couple caveats:

  • Make sure your account has enough funds not only for your smartcontract deployment, but also for deployment of truffle's Migration contract and calls to that contract.
  • If you use low gasPrice, you better make sure mainnet is not too busy, check https://ethgasstation.info/. If your transaction does not get enough priority and fails to be mined in 50 blocks, truffle/web3 will timeout. Depending on how far you are in truffle-migrate process, your actual contract deployment might still be ongoing and finish successfully, but contract address will not be recorded under build/.

If your contract costs that much, then you must do a bunch of storage initialization. Storage, by far, costs the most to read/write.

The irony of solidity is that it cost less to redo things in memory so if you have some variables you can re-initialize and recalculate, it's probably better to do so in memory each time a contract method is called.

This is not the answer to the question, but I would like to add this to the previous answers.

When you commit your transaction, Ethereum client calculates, how much transaction would cost if transaction uses all provided gas up to gas limit.

So, if you have gas limit set to 6,700,000 and gas price set to 20 gwei, then client would require you to have at least 0.134 ETH on your wallet. I am unsure if it is possible to disable this check.

You can try lowering gas limit for your transactions or gas price, but this would cause longer confirmation time

Your Answer

 

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

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