3

This is more of a general discussion then a direct question.

I am trying to find a way for a smart contract to be identified somehow by another one.

My final goal is to allow some functions in "contract1" to only be executed by contracts that have been created following the template of "contract2" but may contain different kind of data.

A first though was, could I keep a sort of hash or key in "contract2" and send it over to "contract1" following a bit the example of the transfer function in ERC223:

 // Function that is called when a user or another contract wants to transfer funds .
function transfer(address _to, uint _value, bytes _data) public returns (bool success) {

    if (isContract(_to)) {
        return transferToContract(_to, _value, _data);
    } else {
        return transferToAddress(_to, _value, _data);
    }
}

basically adding one more if function:

 // Function that is called when a user or another contract wants to transfer funds .
    function transfer(address _to, uint _value, bytes _data) public returns (bool success) {

        if (isContract(_to) && _data == *SECRETKEY*) {
            return transferToContract(_to, _value, _data);
        } else {
            return transferToAddress(_to, _value, _data);
        }
    }

But obviously the problem with this is that the key would need to be kept in clear and therefore not so secret after all.

Does anyone have any suggestions on how could I go about doing this ?

3

You can keep mapping (address => bool) authorizedContracts; inside contract1. And the method addAuthorizedContract should be open only to the owner of contract1.

If you want to avoid calling contract1 to add authorized contracts and move authorization proofs to contract2 instances you can require contract2 instances to include the signature of their address. The signature must belong to some predefined account (e.g. the owner of the contract). Something like this:

function transfer(address _to, uint _value, uint8 v, bytes32 r, bytes32 s) public returns (bool success) {

    if (isContract(_to) && ecrecover(sha3("\x19Ethereum Signed Message:\n20", msg.sender),v,r,s) == this.owner)) {
        return transferToContract(_to, _value, _data);
    } else {
        return transferToAddress(_to, _value, _data);
    }
}

When you create instances of contract2 you will need to also include the signature (that you create off-chain) that they will pass along when calling transfer on contract1.

You can read more about ecrecover here Ecrecover after eth_sign update with preamble

2

You could use extcodesize and extcodecopy to fetch the code for msg.sender. Then you could hash it and compare to a hash of the known good source code.

Note that this only works if the goal is to identify identical contracts. (Code is identical except for the data stored.) That's my understanding of the question, but if that's not your goal, then this approach does not work.

  • Requires manual off-the-blockchain labor anyway because the source codes are not identical (just from the same template), so I think authorizing contract address is much easier – Lauri Peltonen Feb 13 '18 at 19:39
  • My understanding was that the goal was to identify contracts with identical code, but I agree that the wording in the question is a little ambiguous. – user19510 Feb 13 '18 at 19:41
  • I added a paragraph making that clear in my answer. – user19510 Feb 13 '18 at 19:42
1

As you said, you can't really have secrets in the contract. Except if some data is encrypted off-the-blockchain and the result sent to the contract.

The problem with that approach is the work that needs to be done outside blockchain (on your local node probably). There are some ideas at https://blog.ethereum.org/2016/01/15/privacy-on-the-blockchain/ . But it's all rather theoretical currently.

As you need to do manual work anyway off-the-blockchain, as @medvedev1088 just answered, the easiest way is to just allow certain contract addresses.

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.