[Ethereum] How to estimate the contract code size? it is too big to deploy now


I think my contract is too big to deploy, because I got
Error encountered, bailing. Network state unknown. Review successful transactions manually. Error: oversized data when I am trying to deploy on ropsten network. (but it works fine on testrpc, because I set a very large number of gas limit)

So I want to estimate my code size to be deployed in truffle test. I know how to estimate gas to run a function in contract using estimateGas(), but I don't know how to estimate gas(or code size?).

Best Answer

How to estimate gas for deploying a smart contract

I'm using the Yellow Paper, Appendix G, page 25 as reference.

The cost of gas to deploy your contract can be calculated like this:

  • 21000 because all transactions pay this (Gtransaction)
  • 32000 because is a contract creation (Gcreate)

Your transaction will have input data, which will cost you in gas:

  • 4 for each byte with value zero in your input data (Gtxdatazero)
  • 68 for each non zero byte in your input data (Gtxdatanonzero)

Initialising variables and running the constructor, costs you:

  • 20000 for each SSTORE when the storage value is set to non-zero (Gsset)
  • 5000 for each SSTORE when the storage value is set to zero (Gsreset)
  • additional gas for each OPCODE your constructor is executing (see reference)

Finally, you have to pay to store your code, and that will cost you:

  • 200 for each byte of code you store on the state.

When you compile your code, you get your bytecode, and that's where you can find all the OPCODES your smart contract executes.

You will also get your running (or deployed) bytecode, which is the code that will be stored on the state. It's equal to the bytecode minus the initialisation and constructor code (that are not stored in the state).

How to know the code size using a truffle javascript test file

You can use the following code in a js file inside the test folder:

var YourContract = artifacts.require("YourContract");

contract('YourContract', function(accounts) {
  it("get the size of the contract", function() {
    return YourContract.deployed().then(function(instance) {
      var bytecode = instance.constructor._json.bytecode;
      var deployed = instance.constructor._json.deployedBytecode;
      var sizeOfB  = bytecode.length / 2;
      var sizeOfD  = deployed.length / 2;
      console.log("size of bytecode in bytes = ", sizeOfB);
      console.log("size of deployed in bytes = ", sizeOfD);
      console.log("initialisation and constructor code in bytes = ", sizeOfB - sizeOfD);

Afterwards, run truffle test.

Related Topic