1

Here is an abstract/interface contract I created because I want to call this contract which will be deployed before my other contracts. It just holds the addresses of all the contracts I have deployed.

IAddressManager.sol

contract IAddressManager {
    function getTokenAddress() public constant returns (address) {}
    function setTokenAddress(address _tokenAddress) public {}
    function getEventAddress(uint8 _indexOfAddress) public constant returns (address) {}
    function setEventAddress(uint8 _indexOfAddress, address _newContractAddress) public {}
    function getSpecialAddress(uint8 _indexOfAddress) public constant returns (address) {}
    function setSpecialAddress(uint8 _indexOfAddress, address _newContractAddress) public {}
}

I omitted a bunch of stuff, but here is my basic contract code:

MyContract.sol

contract Oracle {  
    IAddressManager private addressManager;

    function Oracle(
        address _addressManager,
        bytes _eventName, 
        bytes32[] _eventResultNames, 
        uint256 _eventBettingEndBlock,
        uint256 _decisionEndBlock,
        uint8 _averageBlockTime,
        uint256 _arbitrationOptionMinutes) 
        public
        payable
    {
        require(_addressManager != address(0));
        require(msg.value >= minBaseReward);
        require(_eventName.length > 0);
        require(_eventResultNames.length > 1);
        require(_decisionEndBlock > _eventBettingEndBlock);
        require(_averageBlockTime > 0);
        require(_arbitrationOptionMinutes > 0);

        addressManager = IAddressManager(_addressManager);
        eventName = _eventName;

        for (uint i = 0; i < _eventResultNames.length; i++) {
            eventResults.push(Result({
                name: _eventResultNames[i],
                votedBalance: 0
            }));
        }

        eventBettingEndBlock = _eventBettingEndBlock;
        decisionEndBlock = _decisionEndBlock;

        uint256 arbitrationBlocks = getArbitrationOptionBlocks(_averageBlockTime, _arbitrationOptionMinutes);
        arbitrationOptionEndBlock = decisionEndBlock.add(arbitrationBlocks);
        assert(arbitrationOptionEndBlock > decisionEndBlock);

        OracleCreated(_eventName, _eventResultNames, _eventBettingEndBlock, _decisionEndBlock, 
            arbitrationOptionEndBlock, msg.value);
    }
}

MyContract would deploy fine before, but after adding the interface contract it runs out of gas. 1075835 gas without IAddressManager and 4712388 gas with it.

Why is it adding so much overhead when the contract code is very minimal?

Here is my test code:

beforeEach(async function() {
        let addressManager = await AddressManager.new();
        console.log(addressManager);
        console.log(addressManager.address);
        myContract = await MyContract.new(
            addressManager.address, 
            testParams._eventName, 
            testParams._eventResultNames,
            testParams._eventBettingEndBlock,
            testParams._decisionEndBlock,
            testParams._averageBlockTime,
            testParams._arbitrationOptionMinutes,
            { from: creator, value: baseReward, gas: 10000000 });
    });

EDIT 1

I was playing around with the code, and for some reason even passing the address _addressManager param in the constructor causes the Out of Gas error. Why is it doing this even if I don't try to create IAddressManager?

EDIT 2

Also tried to increase block gas limit to 10,000,000. No luck. It still always runs out of the gas and hits the limit.

EDIT 3

I went on Remix and did some tests to try to deploy the code on the Kovan testnet with Parity. So it looks like with the code the way it is, it costs ~100 Ether to deploy (WTF). I kept removing params and code to see what was causing this and it seems after everything, just removing the payable from the constructor seemed to fix the issue.

Anyone know why having this payable caused my contract deployment cost to skyrocket?

  • What's the length of eventResultNames that you are looping in the constructor? In the past, I have tried to initialize an array of size 100 with rather simple structs (say 1 address, 4 uint256) and that made the contract deployment run out of gas. – pabloruiz55 Oct 6 '17 at 18:38
  • @pabloruiz55 I thought this might be a potential issue too, but in my test deployment I only used 3 items. I have an issue open with the Solidity team about this. I am certain it is because of the payable keyword. – The Nomad Oct 6 '17 at 18:47

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.