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?
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().

| improve this answer | |
  • In case 2. the exception when I run foo in browser-solidity is out of gas, why is that? – Nicola Squartini Jan 25 '17 at 9:23
  • 1
    Because the EVM essentially only has 1 exception: Out of Gas ethereum.stackexchange.com/questions/2307/… – eth Jan 25 '17 at 9:27
  • @eth technically, Invalid JUMPDEST is also a separate exception, and that's how throw works – Tjaden Hess Jan 25 '17 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 Jan 25 '17 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 – Tjaden Hess Jan 25 '17 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.

| improve this answer | |
  • 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 Jan 25 '17 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. – Tjaden Hess Jan 25 '17 at 4:31
  • The original question was edited since this answer was submitted. @TjadenHess is correct. – CBobRobison Jan 25 '17 at 4:39

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.