4

I have a smart contract with some constructor code that has a throw statement in there, if certain conditions are satisfied.

But even with that, seems like contract is deployed and I get a transaction receipt and a contract address back, though when I look at the generated contract, it does not have all the properties and data.

Is there a way to stop the "Contract Deploy" transaction to be committed if the constructor code throws?

Here is the sample smart contract code I got:

pragma solidity ^0.4.8;

contract MyCoin {

    function MyCoin(address _finalDestination, uint _contractGracePeriod, address _parentContract) 
    {
        if(_parentContract == address(0))
        {
            hupCount = 0; 
        }
        else
        {
            throw;
        }
    }
}
4
  • can you post a txid? of course there will be txid, but contract won't be generated
    – rstormsf
    Commented Aug 18, 2017 at 5:25
  • 1
    Contract creation does indeed fail if it reverts in the constructor. It does not construct the contract. You can verify it with eth.getCode. However, just like any other OOG transaction, you do still get a receipt. Commented Nov 16, 2017 at 20:29
  • @LibertyLocked is correct here. If the constructor fails, your contract will not be created but you will still see a transaction receipt. I would also suggested to use require() here instead of throw conditions as it is deprecated as of last updates. solidity.readthedocs.io/en/develop/…
    – Karen S
    Commented Jan 29, 2018 at 0:52
  • @LibertyLocked: you should put your comment into an answer!
    – ivicaa
    Commented Apr 4, 2018 at 4:51

1 Answer 1

1

Revert / OOG in constructor

If there is a REVERT or OOG (out-of-gas) in constructors, the transaction will not construct the contract. However you do still get a transaction receipt for the contract creation transaction you send (to address 0x00), and gas is paid.

This of course will also increment the nonce (transaction count) of the deployer. The next you deploy another contract the address of the contract will not be the same.

Consider the following example.

pragma solidity 0.4.21;

contract ConstructorTest {
    function ConstructorTest(address parent) public {
        assert(parent != 0);
    }
}

Creating this contract with 0 as parent will cause the transaction to OOG, because assert fails. In that case, all the gas you paid for the transaction will be consumed, paid to the miner of the block.

Similar case if you replace assert with require. It causes a REVERT, so you get remaining gas back.


Checking if contract has been deployed

Simply checking if you get the tx receipt is not enough, because in case of OOG or revert you still get the receipt.

I can think of 2 ways to check if contract has been successfully deployed.

  • Read your contract address, contractAddress, off the receipt with eth.getTransactionReceipt. Then use eth.getCode to check if the code is 0x

  • Check the status of the transaction receipt. If it's 0 then the tx is mined but failed.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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