1

I've been using this technique to create new contracts.

contract Factory {
bytes32[] Names;
address[] newContracts;

function createContract (bytes32 name) {
    address newContract = new Contract(name);
    newContracts.push(newContract);
} 

function getName (uint i) {
    Contract con = Contract(newContracts[i]);
    Names[i] = con.Name();
}
}

contract Contract {
bytes32 public Name;

function Contract (bytes32 name) {
    Name = name;
}
}

But This doesn't work for my current contract. It exceeds the gaslimit on ropsten if deployed together. How can I create contracts by using their contract address or abi? It must be possible to create larger contracts somehow right?

Edit: It's also so strange that the created contract is much bigger than the "Factory" contract. And the created contract can be deployed fine on its own, whereas the factory is not possible. Why? Does a factory take much more code?

Here is the code (I have very little comments): https://gist.github.com/anonymous/91dbd8614331b57c1d1bf371195dc9d3

1

You can try moving the logic (if any) out of the constructor into a separate function that would be manually called in a separate transaction. That might help saving gas costs on contract creation.

Have you turned on compiler optimization? That might help as well.

As @hextet suggests, you could also try moving some of the logic to a library to avoid part of the code being deployed each time.


You can move the logic of BetOnBitcoin constructor to a separate function to bring down the master's deployment cost to 3.25mm +- (with optimizer turned on).

function BetOnBitcoin() payable public{
      owner = msg.sender;

    }

function startBets(){

      oraclize_setProof(proofType_TLSNotary | proofStorage_IPFS);
      totalBetsBitcoinGoesUp = 0;
      totalBetsBitcoinGoesDown = 0;
      numberOfBettersBitcoinGoesUp = 0;
      numberOfBettersBitcoinGoesDown = 0;
      payOutIndexBitcoinUp = 0;
      payOutIndexBitcoinDown = 0;
      totalBets = 0;
      currentState = GameState.gettingBitcoinPrice;
      update();
    }
| improve this answer | |
  • Thanks! What do you mean compiler optimization. How would I go about doing that? – Alfred Wahlforss Dec 15 '17 at 16:01
  • You can turn on the compiler optimization to greatly reduce gas consumption on deployment. On Remix, it’s in the settings tab. – pabloruiz55 Dec 15 '17 at 16:05
  • I'm not using any duplicate code, therefore libraries wouldn't be able to help me right? – Alfred Wahlforss Dec 15 '17 at 16:19
  • Optimization doesn't help... – Alfred Wahlforss Dec 15 '17 at 16:24
  • If you share the code maybe I or someone else can give you further help. – pabloruiz55 Dec 15 '17 at 16:25
2

I ran into a similar issue with a contract that I wanted to deploy a few weeks ago. What I discovered was that I was trying to assign too much data during the deployment of the new contract. For example say I was setting 10 variables during deployment which caused the gaslimit error, I would make it only set 5 variables, and I would then have a seperate function that I call in a different transaction to set the remaining variables. By doing this I was able to get around the gaslimit, so that is one possible solution.

That being said, I would take a look at your code and see if you're duplicating anything that could be written as a library and deployed once, such that you avoid repaying the gas costs to deploy the same piece of code over and over again. You could also try to split your contract up into different roles, which would also be easier to manage and audit from a security standpoint.

| improve this answer | |
  • Hmm didn't work to change the constructor variables. – Alfred Wahlforss Dec 15 '17 at 16:07
1
  • This may not fully solve your use case because you are using a factory pattern. But it together with other techniques may help.

    When the gas was much lower (post DoS attack last year), one option was to split contracts into several smaller ones that can be deployed independently of each other, and then as part of the setup you will 'link' them together, like crowdsale.setToken(token.address) and token.setCrowdsale(crowdsale.address).

    With that idea you can join several contracts that work together as a larger contract than the current block gas limit will allow.

    The modern approach to do this more automatically is to use libraries.

  • The idea used in parity wallet was a good one, one base contract contains all the code and a stub contract contains the data and through delegatecall make calls to the base contract.

    This approach is very similar to how dynamic libraries work in modern operating systems. (And is somehow the idea behind ZeppelinOS)

    The problem with this approach is you need to be extra careful. Right now some of the work has to be done manually (deploying), and through EVM assembly (delegatecalls), and this steps are critical as the facts has demostrated.


library Cars {
    struct Car {
        uint wheels;
        uint fuel;
        bool breaks;
    }

    function startEngine(Car car, uint fuel) pure internal returns (bool) {
        car.fuel = fuel;
        return true;
    }

    function enableBrakes(Car car, bool enable) pure internal returns (bool) {
        car.breaks = enable;
        return enable;
    }
}

contract House {
    using Cars for Cars.Car;
    Cars.Car public myCar;

    function startCar(uint fuel) public {
        myCar.startEngine(fuel);
        myCar.enableBrakes(false);
    }
}
| improve this answer | |
  • Thanks! Can a library change the local variables of the contract? So that all functions are on the library but the contract stores the all the variables? That would probably save a lot of code. – Alfred Wahlforss Dec 15 '17 at 17:04
  • No, libraries functions do not have direct access data members, you have to pass them as parameters. A common approach is to define a struct inside the library and in your contract define a variable with that strctu, and pass the struct as first parameter. Then in your contract call using Library for Data somehow more tolerable. But it is far from perfect. – Ismael Dec 15 '17 at 17:14

Your Answer

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

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