0

This is a sequel to a previous question of mine.

I want to implement a validation function (e.g. for passwords) within a central contract, that could be used by other contracts. It is important to notice, that this validation also considered the address of the caller. Therefore it needs to be called by delegatecall in order to access the actual caller through msg.sender. Since I cannot receive values when calling a function by delegatecall call (see my previous request), my new attempt is to abort processing by using several require statements within the validation function. Unfortunately, this does not seem to work, even if I force a require abortion.

contract Caller {

 function doSomething(address _callee, string _text) public {
   _callee.delegatecall(
                     bytes4(keccak256("validate(string)")), _text));

 /* further process if text is valid */
 }
}

contract Callee {

 function validate(string _text) public view {
  /* validity check */
  require(false);
 }
}

Even in the above example code, where I force an abortion, doSomething finished successfully. Any hint?

1

delagetcall will return false if it fails, you are not handling the returned value, you could do:

require(_callee.delegatecall(bytes4(keccak256("validate(string)")), _text)));

hope this helps

4
  • As a note for the OP, this is a Solidity thing. The opcode itself works the same as the call/callcode opcode, in that they all push a failure/success state to the stack, and whether or not to bubble up the failure is up to the calling code. Solidity, by default, does this "bubbling" when contracts are called high level with their ABI (transfer also bubbles up on failure), but it doesn't do it when you do low level calls like delegatecall and call like in the OP. – flygoing Jul 5 '18 at 21:16
  • 1
    When I do it this way (require(contract.delegatecall...), the call will fail, when I try to access any property of the called contract. Is the reason for this, that the code is called from the calling storage? – Sebastian Dine Jul 6 '18 at 17:17
  • Are you talking about the example in your question? it will always fail because you have require(false), but I am guessing this is not what you mean. Please share the code you are referring to. – Jaime Jul 6 '18 at 17:19
  • I did some testing and found out, that it is indeed a problem of the scope. Let's say I have a public uint as a property of the called contract, that is set by the function that is called with delegatecall. Before the delegatecall the value is 0 and afterwards it is still 0 because it is another scope. When I call the same function without delegatecall, the value will change. – Sebastian Dine Jul 7 '18 at 12:21

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.