4

I have two questions regarding contract creation and exceptions:

  1. If contract A creates contract B and then throws in the same function, is B also deleted?
  2. If contract A creates contract B, and B throws in its constructor, does the exception bubble up to A?

2 Answers 2

4

1. Yes

B will not be created if the transaction containing the creation of B has an exception. Example:

pragma solidity ^0.4.8;

contract A {
    B public b;
    function foo() {
        b = new B();
        throw;
    }

    function getXfromB() returns (uint) {
        return b.x();
    }
}

contract B {
    uint public x;

    function B() {
        x = 1;
    }
}

Using browser-solidity to quickly test, first comment out the throw. Then "Create" A, click foo, then click b to see its address and click getXfromB to see that you get 1. Uncomment the throw to see that B is not created: click b to see it's 0x0.

An exception in a call causes all changes (in that call) to be reverted, and there is nothing special about contract creation that would keep it from being reverted. For more information, see Does an entire transaction revert when throw occurs?

2. Yes

Solidity 0.4 was fixed so that if new B() fails, A will get an exception.

Failing contract creation through "new" throws

The same example in #1 can be leveraged for testing by moving the throw in foo to constructor B().

6
  • In case 2. the exception when I run foo in browser-solidity is out of gas, why is that? Commented Jan 25, 2017 at 9:23
  • 1
    Because the EVM essentially only has 1 exception: Out of Gas ethereum.stackexchange.com/questions/2307/…
    – eth
    Commented Jan 25, 2017 at 9:27
  • @eth technically, Invalid JUMPDEST is also a separate exception, and that's how throw works Commented Jan 25, 2017 at 17:55
  • @TjadenHess Agree the Yellow Paper labels 4 exceptions: Out of Gas, stack underflow, invalid JUMP, and invalid opcode. In the link, I try to communicate that the implementation of the latter three end up with the first (Out of Gas).
    – eth
    Commented Jan 25, 2017 at 21:28
  • I think it's more accurate to say that any exception causes all gas to be used up and state to be reverted; there's nothing special about the OOG exception Commented Jan 25, 2017 at 21:58
1
  1. If contract A creates contract B and then throws, is B also deleted?

A throw will only terminate it's function. It cannot delete it's contract or any child contracts. For example (from the solidity docs):

contract Ballot{

    function giveRightToVote(address voter) {
        if (msg.sender != chairperson || voters[voter].voted) {
            throw;
        }
        voters[voter].weight = 1;
    }
}

If the giveRightToVote() function is called and if msg.sender != chairperson || voters[voter].voted, then the giveRightToVote() function will completely stop running; nothing past the throw will be executed - in this case we see voters[voter].weight = 1 will not be executed.

However! The Ballot{} contract as a whole is still available on the blockchain for anyone else to call. And in fact giveRightToVote() could even still be called again, along with any other available functions within the contract.

If Ballot{} (Contract A) had created any Contract B. A throw in Ballot{} would not affect any of it's child contracts (Contract B).

  1. If contract A creates contract B, and B throws in its constructor, does the exception bubble up to A?

A constructor is a function, so the same is true here. If a constructor throws, the rest of the constructor function will not be executed. But again, even after the constructor is thrown, the contract will remain and any other function within contract B will be available for future calls. Contract A will not be affected.

3
  • The takeaway from this answer is that a contract that has already been deployed to the blockchain, cannot be deleted by exceptions. EDIT: Thanks Tjaden for mentioning the corrections to this answer.
    – eth
    Commented Jan 25, 2017 at 0:39
  • 1
    A throw is guaranteed to revert any modifications made to the blockchain, including any newly created contracts, to the state before the call. Thus, in situation 1, the contract creation would be reverted. In situation 2, solidity does detect the failure and then throws, essentially reverting back to situation 1. Commented Jan 25, 2017 at 4:31
  • The original question was edited since this answer was submitted. @TjadenHess is correct. Commented Jan 25, 2017 at 4:39

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.