Creating a contract from my contract costing 4.5 - 5 million gas

I have a contract with a method that deploys another contract. The contract it deploys is a contract that is very close to a basic ERC20 that inherits from OpenZep’s Burnable and Mintable ERC20’s, with a two very simple methods attached, with the constructor taking an array of addresses and writing that to storage.

However, when I deploy it using MyContract myContract = new MyContract(arrayOf2To20Addresses), it costs about 4.5 million gas.

What’s up with that?

:computer: Environment
dapptools with hevm version .34 (latest)

:1234: Code to reproduce

this is the code of the contract that is created:

pragma solidity ^0.5.0;

import "openzeppelin-contracts/contracts/token/ERC20/ERC20Burnable.sol";
import "openzeppelin-contracts/contracts/token/ERC20/ERC20Mintable.sol";

contract MyContract is ERC20Mintable, ERC20Burnable {
    using SafeMath for uint256;
    address[] public tokens;
    constructor(address[] memory _tokens) public {
        tokens = _tokens;
    }
    function testBurn(address account, uint amount) public {
        _burn(account, amount);
    }
    function getTokens() public view returns(address[] memory) {
        return tokens;
    }
}
1 Like

Hi @realisation,

I created MyContract via a factory on Ropsten and gas used by transaction was 1,408,124
https://ropsten.etherscan.io/tx/0xb888b410e456577c39ed3a62b10d1f5b2dd9738989bc3618d4d4d5d4b5ddf882

I am not sure why you are seeing the gas usage that you got. Are you able to share your factory contract and I can reproduce?

MyContract.sol

pragma solidity ^0.5.0;

import "@openzeppelin/contracts/token/ERC20/ERC20Burnable.sol";
import "@openzeppelin/contracts/token/ERC20/ERC20Mintable.sol";

contract MyContract is ERC20Mintable, ERC20Burnable {
    using SafeMath for uint256;
    address[] public tokens;
    constructor(address[] memory _tokens) public {
        tokens = _tokens;
    }
    function testBurn(address account, uint amount) public {
        _burn(account, amount);
    }
    function getTokens() public view returns(address[] memory) {
        return tokens;
    }
}

MyFactory.sol

pragma solidity ^0.5.0;

import "./MyContract.sol";

contract MyFactory {

    function newMyContract() public returns(address)
    {
        MyContract myContract = new MyContract(new address[](0));
        return address(myContract);
    }
}

The factory contract has nothing to do with it - I stripped the method down to nothing but the call to new MyContract and i’m getting 5 mil gas readouts

1 Like

although, there are a whole bunch of other methods and a small handful of storage variables in the factory contract. Would that make a difference even if the method that this new contract is being created from does nothing but creates that contract?

1 Like

Hi @realisation,

I wouldn’t have thought so, it should just be the function creating the new contract (in the factory) assuming it doesn’t do anything else.

You could try deploying the child contract from truffle and see what the gas used is, I did this below:

Deploying MyContract from truffle on Ropsten and gas used by transaction was 1,884,752
https://ropsten.etherscan.io/tx/0xa3afb4271b0c0dbc64ac4c502dd1fec103a2accbc48e256a00d6746f06ddb3ff

Deploying MyContract from MyFactory on Ropsten and gas used by transaction was 1,408,124
https://ropsten.etherscan.io/tx/0x12ec733db75601325d2e4b4a3dcf695771c1b54a5259226a0df8c1c2722af2e5

Interesting, why does it differ between them?

I tried deploying the contract without a factory on Ropsten with Remix and it quoted me 2242882 gas for transaction cost and 1626954 gas for execution cost.

1 Like

When you deploy a contract regularly, you need to:
a) send a tx with the contract bytecode
b) store that bytecode in the blockchain
Both of these actions cost Ether.

When you deploy a contract via a factory, the factory contract already has the contract bytecode stored, so you don’t need to send it over (you already paid for this when deploying the factory itself). So what you pay for is:
a) calling a function on your factory
b) storing the bytecode in the blockchain

This call is much cheaper because there’s less data involved.

2 Likes

Going back to the original issue, we still don’t know why @realisation’s factory was charging 5 million gas, right?

To be clear, was this the actual gas cost or just an estimate?

1 Like

That was the gas readout. It looks like I may have found a bug, which is being investigated currently.

1 Like

Hi @realisation,

Where was the potential bug? Feel free to add the GitHub Issue here.

The underlying gas semantics are correct but the readout may have a bug in it when running tests.

1 Like

Is there a way to access this byte code?

Context:
I want to build an API using Terminal for the factory deployed contract.