3

It's possible to create a Factory-type Contract that can spit out other contracts:

contract Greeter {
  string greeting;
  address public creator;

  function Greeter(string _greeting) {
    creator = msg.sender;
    greeting = _greeting;
  }

  function greet() constant returns (string) {
    return greeting;
  }
}

contract GreeterFactory {
    function makeGreeter(string greeting) returns (address) {
        return new Greeter(greeting);
    }

    function verify(address child) returns (bool) {
      Greeter child = Greeter(child);
      // Do something amazing here...
    }
}

But how to verify that a Greeter at a given address is one that came from a trusted GreeterFactory? In other words, how to complete that verify() function on the parent Factory?

Eve could create a contract with a static creator property that imitates a known GreeterFactory fairly easily:

contract BadGreeter {
  address public creator;

  function BadGreeter() {
    creator = 0x1010101010; // Address of a known GreeterFactory contract
  }

  function greet() constant returns (string) {
    return "Trust me...";
  }
}

A user could easily look at the blockchain to grab the bytecode for a contract and see the difference between BadGreeter and Greeter. But how could we build it so a separate contract could do it (via a call to a verify(address) method of some sort that's trustless)?

2 Answers 2

3

Store the address of all created contracts in a mapping. To validate a contract - any contract - just check it against that array.

contract GreeterFactory {

    mapping (address => bool) created;

    function makeGreeter(string greeting) returns (address) {
        var g = new Greeter(greeting);
        created[g] = true;
        return g;
    }

    function verify(address greeter) returns (bool) {
        return created[greeter];
    }

}
2
  • Didn't see the other answer. So basically this is only good if you need to verify from within a contract. If the validation can be done before the actual tx then obviously do that instead. This costs extra gas and storage. Sorry, just wanted to be clear. Mar 21, 2016 at 10:24
  • In the function makeGreeter(string greeting) returns (address) is it possible to return more data than simply the address? For example, in the constructor of Greeter(string greeting) could you return (string greeting) to the Factory then save it in a mapping in the original GreeterFactory?
    – Physes
    Jun 1, 2016 at 16:39
1

I would say the best approach is for the factory contract to create a child, verify its length, store it in some variable, and then check code equivalance.

Checking code equality of two addresses in serpent:

def check_code_equality(a:address, b:address):
    asz = ~extcodesize(a)
    acode = string(asz)
    ~extcodecopy(a, acode, 0, asz)
    bsz = ~extcodesize(b)
    bcode = string(bsz)
    ~extcodecopy(b, bcode, 0, bsz)
    return sha3(acode:str) == sha3(bcode:str)

Your Answer

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

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