9

Let's say contract A does not know the address of contract C but it knows what function of C it wants to call. Contract B stores contracts's C address. Therefore contract A wants to request a call to C's function but at the address of contract B. Furthermore, the function returns a value about which contract A cares. Essentially, contract C is a library that contract A wants to use for his own computations but does not know the libraries' address.

Now, I have looked into various ways of doing this with call, delegatecall and fallback function but I think it might not be possible to do it exactly like that.

For example, there was once suggested solution here which I hope is fine to copy here for convenience:

contract Relay {
address public currentVersion;
address public owner;

function Relay(address initAddr){
    currentVersion = initAddr;
    owner = msg.sender;
}

function(){
    if(!currentVersion.delegatecall(msg.data)) throw;
}

Solution 1: I have tried something like the above code, making my contract B to have a fallback function. However, when A executed a call to C through it then it returned me some strange result back to A which made me believe that it will just not work this way for some reason; the result of C will not return through fallback back to A.

Solution 2: The closest I got it to work is when I had A execute a delegatecall to B which in turn executes the delegatecall to C. This meant that C was executing in the context of A and so when I set a storage variable in C, I am actually setting a storage variable in A. Then I had the result of the computation stored in a state variable in A which is not bad. However, this solution also means that B needs to have hardcoded all the variables/logic in the fallback function and cannot access its storage variables because it executes in the context of A. It cannot have the address of C stored in a state variable like the currentVersion in the example above.

I am not sure if everything what I wrote is correct but this is my take on it. I am hoping that maybe solution 1 should still be possible but I did something wrong? Am I missing something?

md2312
  • 193
  • 6

1 Answers1

6

Instead of relaying the call, why not just use contract B to store the value and have contract A read the value? Instead of delegating the call to B, read the address from B and delegate directly to C.

Tjaden Hess
  • 37,046
  • 10
  • 91
  • 118
  • I was playing around with the idea of hiding the address of C to A altogether (by obfuscation, at least) plus having the fallback function of B to charge A to do this relay. – md2312 Jun 06 '16 at 18:22
  • 1
    You can't really hide it, that's beyond current technology. You can still charge, though. In order to fetch the address, A would have to call a function of B that requires payment – Tjaden Hess Jun 06 '16 at 18:24
  • 1
    Does it mean that the above Relay contract example is not really going to work for calls with return values? – md2312 Jun 07 '16 at 13:23
  • Hey @md2312 I'm trying to accomplish exactly the same as you (hide a contract behind a relay/dispatcher contract so I can update it later if necessary), but I'm stuck with functions with return values and the delegatecall approach. Does all of this ended up working for you? – jlpiedrahita Jan 22 '17 at 18:44
  • 1
    It can be tricky if you want to be able to return values, but it can definitely be done with a little inline assembly – Tjaden Hess Jan 22 '17 at 19:07
  • Would you have an example, @TjadenHess ? – n1cK Mar 04 '18 at 18:59