0

I have two Solidity contracts, where contract Caller depends on a second contract Callee. Contract Callee provides a public view function which checks the validity of a string (e.g. an password), according to some internal rules. Caller needs to check a string in its own function by calling Callee, before he can further process. Furthermore Caller needs to call the function of Callee by using delegatecall, because the internal validity check considers the calling address.

contract Caller {

  function doSomething(string _text, address _callee) public {
     bool valid = bool(_callee.delegatecall(
                          bytes4(keccak256("check(string _text)")), _text)
                  );

     require(valid == true);
     /* further process if text is valid */
  }
}

contract Callee {

  function check(string _text) public view returns(bool){
    /* validity check */
    return true;
  }
}

The problem with this code is, that the call of function check seems to be asynchronous and therefore the require statement in function doSomething will always fail. Is this a problem of delegatecall? Is there a way to call the external function synchronously?

0

I finally found the answer to my problem: Sadly, one cannot receive values from delegatecall function calls.

  • Well, the virtual machine DOES support return values in DELEGATECALL opcode :func opDelegateCall(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) – Nulik Jul 6 '18 at 1:03
  • really? Do I read the opcode correctly: It can return a byte array? – Sebastian Dine Jul 6 '18 at 16:49
  • I am not really expert in writing contracts, but DELGATECALL opcode works the same way as CALL opcode. I know because I modified the VM for a custom blockchain processing. It is absolutely identical, open core/vm/instructions.go and see for yourself. The ret variable holds the []byte array returned by DELEGATECALL. Maybe you can write a small part of your contract in assembly, so you call DELEGATECALL and catch this return value. This return value is put in memory at outOffset position. – Nulik Jul 6 '18 at 18:56
  • I think this ret variable indicates if the processing of the called function was successful. – Sebastian Dine Jul 7 '18 at 10:32
  • 1
    no, ret is the output returned from the EVM. If there was any error it returns the error. This output is encoded according to the ABI. If you call abi.Unpack() on ret you will get the value according to its type. For example, all integers are stored in 32 bytes arrays, all strings have first string length and then string data follows, and so on... – Nulik Jul 7 '18 at 14:36

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.