2

I want to let any instance of a specific contract call a function, but no instances of any other contracts. Is such a thing possible? Maybe checking the hash of the bytecode of the calling contract msg.sender?

2

There are opcodes that would theoretically allow you do to this; specifically CODECOPY and EXTCODECOPY. Currently, you'd have to use inline assembly in solidity to actually do this, and it'd probably be gas expensive.

It may be easier, as @Chris Hafey said, to use an ACL. You could have one factory contract that creates all instances of contract X, and contract Y checks the factory contract to check. (You'll probably want to have the factory contract be a different contract than Y to reduce the size of Y, or allow multiple Ys.)

Consider also that as solidity advances, the same code may start to give different bytecode. It's possible that having a factory (that could even be upgraded!) may be the better choice in the end, anyway.

  • Great point, thank you. What does ACL stand for? – syzygy Mar 8 '17 at 3:45
  • 2
    Access Control List – Vixon Mar 8 '17 at 6:00
2

I thought it might be handy to quickly sketch out a crude ACL apparatus.

There are some assumptions that may or may be correct for your case. In the example, "consumer" is produced and owned by "factory" and the protected function is in "factory." Factory maintains an ACL with getters to facilitate enumerating the list of authorized consumers.

pragma solidity ^0.4.6; 

contract Factory {

    mapping(address => bool) public isConsumer;
    address[] public consumers;

    modifier onlyACL() {
        if(!isConsumer[msg.sender]) throw;
        _;
    }

    function newConsumer() 
        public
        returns(address consumerAddress)
    {
        Consumer c = new Consumer();
        consumers.push(c);
        isConsumer[c] = true;
        return c;
    }

    function ACLProtected()
      onlyACL
      returns(bool allowed)
    {
        return true;
    }

    function getConsumerCount()
        public
        constant
        returns(uint consumerCount)
    {
        return consumers.length;
    }

}

contract Consumer {

    address owner;
    Factory f;

    function Consumer() {
        owner = msg.sender;
        f = Factory(owner);
    }

    function consumeFunction()
        public
        constant
        returns(bool success) 
    {
        bool wasAllowed = f.ACLProtected();
        return wasAllowed; 
    }

}

Hope it helps.

1

Interesting use case, but I don't think that is currently possible. You will need to manage a list of addresses that can make the call (like an ACL)

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.