17

I have got a problem: I have a contract factory that creates some temporary contracts. I want every contract to exist for about 5 days, afterwards, it self-destructs. However, I want to create a directory that stores the addresses of all temporary contracts and lists them for you. Registering the temporary contracts to the directory contract is no problem I just don't know how I can find out if a contract does still exist so that the destroyed contracts are not listed anymore.

Thank you in advance.

  • Do I understand correctly that you want to find a Solidity way to determine whether a contract has already self-destructed? – Xavier Leprêtre B9lab Sep 2 '16 at 13:53
  • yes, that's exactly what I want – Bot X Sep 2 '16 at 15:54
14

After a contract has called selfdestruct(), all values are set to 0. So if you have a contract like:

contract Mortal {
    address public owner;

    function Mortal() {
        owner = msg.sender;
    }

    function kill() {
        selfdestruct(owner);
    }

Then from another contract you can call:

function checkMortal(address mortal) {
    if (Mortal(mortal).owner() == 0) {
        // You know it is dead.
    } else {
        // You know it is alive.
    }
}

Update:

In newer versions of Solidity that target byzantium or later, this will likely fail. Solidity now verifies returndatasize to know if the call failed, so when owner() doesn't return anything, not even 0, it will revert the transaction. The best way to do this now is probably to use extcodesize within solidity assembly. This will only tell you it selfdestructed if you know it previously had a non-zero codesize.

  • Mortal takes no parameters...how is Mortal(mortal) possible then? – Jossie Calderon Jun 13 '17 at 9:15
  • Mortal(mortal) is not a constructor, it is an instantiation of Mortal at address mortal. – Xavier Leprêtre B9lab Jun 13 '17 at 13:31
  • The instantiation calls the constructor for Mortal. The constructor takes no parameters, however, so how can Mortal(mortal) not throw an error? – Jossie Calderon Jun 13 '17 at 19:17
  • For the enlightenment of passersby: it's not actually a constructor. See this question for the full explanation. – Jeff Coleman Jun 14 '17 at 3:34
1

Calling method owner() on an non-existing contract should fail (throw an exception) - not return 0 as suggested.

You can call if something has been deployed at a given address using:

function contractExists(address contract) public view returns (bool) {
    uint size;
    assembly {
        size := extcodesize(contract)
    }
    return size > 0;
}

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.