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?

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.

  • 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 6 '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 6 '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 7 '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

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.