18

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.

Bot X
  • 245
  • 2
  • 6

2 Answers2

15

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.

natewelch_
  • 12,021
  • 1
  • 29
  • 43
3

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;
}
stejin
  • 31
  • 1