0

Using a delegatecall() to call another contract will have that contract run from within your context (e.g. if it calls a contract on its turn as a result, msg.sender will be your address). I am aware that also for storing values this goes in a similar fashion. But how?

If a contract stores a values as a result of a delegatecall()

  1. this value will be stored at the same slot in the caller contract as it would have in the delegatecalled contract.
  2. this value will be stored in the same variable name in the caller contract as it would in the delegatecalled contract (and if it doesn't exist, nothing/something happens).

Thanks in advance!

1

if the target variable in the caller contract is in slot 0, the returned value will be the slot 0 of the delegatedcalled contract.

For instance:

contract caller {
  uint public number;
  address public callerAddress;

  function delegatecallSetNumber(address delegatedAddress, uint256 _number) public {
    delegatedAddress.delegatecall(bytes4(keccak256("setNumber(uint256)")), _number);
  }
}

contract delegatedcalled {
  uint public number;
  address public callerAddress;
  function setNumber(uint _number) public {
    number = _number;
    callerAddress = msg.sender;
  }
}

1. After the delegate call, the value number in the caller will be the value in the slot 0 (number) of the delegatecalled contract.

2. If we modify the delegatecalled contract like this:

contract delegatedcalled {      
  address public callerAddress;
  uint public number;
function setNumber(uint _number) {
    number = _number;
    callerAddress = msg.sender;
  }
}

The variable number in the caller will have the slot 0 in the delegatecalled contract (the address)

3. Changing the name of the variables in the delegatedcalled contract have no effect in the result, the contract below will still work identically as in 1 (see above)

contract delegatedcalled {
  uint public numberxxxx;
  address public callerAddress;
  function setNumber(uint _number) {
    numberxxxx = _number;
    callerAddress = msg.sender;
  }
}

Hope this helps you

  • Thanks @Jaime! Alright. So if I understand correctly, it solely looks at the slot and will store the variable in that slot no matter if its a different type of variable? So even though slot 0 might be an address in the original caller it could store a uint or a string if that is what the delegatecalled contract executes? – Valentijn van den Hout Jan 7 at 16:20
  • Yes. This is because the system stores words of 32 bytes and the way these are stored is not dependent on the type given in solidity which is an abstraction. I tested this in remix. If you try the code I posted you will be able to see it. If this answered your question please accept the answer. Hope this is clear. – Jaime Jan 7 at 16:58

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.