pragma solidity >=0.4.22 <0.7.0;
contract D {
uint public n;
address public sender;
function delegatecallSetN(address _e, uint _n) public {
_e.delegatecall(abi.encode(bytes4(keccak256("setN(uint256)")), _n));
}
}
contract E {
uint public n;
address public sender;
uint test = 10;
function setN(uint256 _n) public {
n = _n;
sender = msg.sender;
}
}
Question 1:
I have this contract. Now, when I call a delegatecallSetN
from remix with the address of E, it successfully calls E contract's setN
function. as we know how delegatecall
works, it sets my passed _n
value on D contract. Now, what about sender
value on D contract ? It still is 0x000000...000 . Why doesn't it set msg.sender
on it ?
Question 2:
Let's say in contract E's setN
function, I add test = 50
. As we know, the code of setN
will be executed in the context of Contract D which doesn't have test
variable at all. Why doesn't it result in exception or error at all and why does the transaction still succeed ?
UPDATED CODE:
pragma solidity >=0.4.22 <0.7.0;
contract D {
uint public n;
address public sender;
function delegatecallSetN(address _e, uint _n) public {
_e.delegatecall(abi.encodeWithSignature("setN(uint256)", _n));
}
}
contract E {
uint public n;
uint public test;
address public sender;
function setN(uint256 _n) public {
n = _n;
sender = msg.sender;
test = 20;
}
}
abi.encodeWithSignature
it works as expected bothn
andsender
are updated correctly forD
. Regarding question 2) the variables at contract level are referenced by a storage slot at compile time, since slots always exists you cannot check during runtime if a variable was defined or not.abi.encodeWithSignature
, I am going to include the remix code in my updated question and you can test it too. Basicallyn
variable of D contract gets set, but not thesender
. I just tested andsender
became 0x0000000000000000000000000000000000000014 this address. which doesn't seem right. Question 2) I still don't understand your answer for the Question 2 unfortunately.