Scope confusion using delegate call

Clash Royale CLAN TAG#URR8PPP
up vote
2
down vote
favorite
I am having trouble understanding the scope with delegatecall method. Here are my two contracts:
contract Caller
uint public testVar = 88;
uint public myVariable = 6;
function delegatecallExample(address _contract, uint newVar) public
_contract.delegatecall(bytes4(keccak256("updateMyVariable(uint256)")), newVar);
contract CalledContract
uint public myVariable = 5;
function updateMyVariable(uint newVar) public payable
myVariable = newVar;
After deploying to a fresh remix instance, calling Caller.delegatecallExample with CalledContracts address and lets say 111, I observe that CalledContracts first declared variable (testVar in this case) is changed to 111 instead of myVariable. So what is the scope of delegatecall?
solidity delegatecall
add a comment |Â
up vote
2
down vote
favorite
I am having trouble understanding the scope with delegatecall method. Here are my two contracts:
contract Caller
uint public testVar = 88;
uint public myVariable = 6;
function delegatecallExample(address _contract, uint newVar) public
_contract.delegatecall(bytes4(keccak256("updateMyVariable(uint256)")), newVar);
contract CalledContract
uint public myVariable = 5;
function updateMyVariable(uint newVar) public payable
myVariable = newVar;
After deploying to a fresh remix instance, calling Caller.delegatecallExample with CalledContracts address and lets say 111, I observe that CalledContracts first declared variable (testVar in this case) is changed to 111 instead of myVariable. So what is the scope of delegatecall?
solidity delegatecall
add a comment |Â
up vote
2
down vote
favorite
up vote
2
down vote
favorite
I am having trouble understanding the scope with delegatecall method. Here are my two contracts:
contract Caller
uint public testVar = 88;
uint public myVariable = 6;
function delegatecallExample(address _contract, uint newVar) public
_contract.delegatecall(bytes4(keccak256("updateMyVariable(uint256)")), newVar);
contract CalledContract
uint public myVariable = 5;
function updateMyVariable(uint newVar) public payable
myVariable = newVar;
After deploying to a fresh remix instance, calling Caller.delegatecallExample with CalledContracts address and lets say 111, I observe that CalledContracts first declared variable (testVar in this case) is changed to 111 instead of myVariable. So what is the scope of delegatecall?
solidity delegatecall
I am having trouble understanding the scope with delegatecall method. Here are my two contracts:
contract Caller
uint public testVar = 88;
uint public myVariable = 6;
function delegatecallExample(address _contract, uint newVar) public
_contract.delegatecall(bytes4(keccak256("updateMyVariable(uint256)")), newVar);
contract CalledContract
uint public myVariable = 5;
function updateMyVariable(uint newVar) public payable
myVariable = newVar;
After deploying to a fresh remix instance, calling Caller.delegatecallExample with CalledContracts address and lets say 111, I observe that CalledContracts first declared variable (testVar in this case) is changed to 111 instead of myVariable. So what is the scope of delegatecall?
solidity delegatecall
asked Aug 25 at 7:14
Cem Güler
1134
1134
add a comment |Â
add a comment |Â
3 Answers
3
active
oldest
votes
up vote
1
down vote
accepted
To expand on Henk's answer, an important implementation detail is that the storage layout is also used from the calling contract.
Since you declare testVar first, as far as CalledContract is concerned, it is in the same storage location as the CalledContract myVariable. Thus, when delegate call sets myVariable, it is actually updating the storage of testVar.
If you switch the declaration order to:
contract Caller
uint public myVariable = 6;
uint public testVar = 88;
function delegatecallExample(address _contract, uint newVar) public
_contract.delegatecall(bytes4(keccak256("updateMyVariable(uint256)")), newVar);
it will update myVariable instead of testVar.
add a comment |Â
up vote
2
down vote
This is the correct behaviour for delegatecall. delegatecall is like call, but the difference is the storage context functions run in. When calling another contract, any functions that contract runs access their own storage. With delegatecall, however, the called contract accesses the storage of the caller.
In your example, Caller delegatecalls CalledContract. The function updateMyVariable accesses and updates the first element in storage of Caller, which is testVar, because myVariable points to the first storage element.
Docs on call and delegatecall
add a comment |Â
up vote
1
down vote
I don't think your question was directly answered in the previous responses.
When any function is called - delegatecall or otherwise - the EVM loads the requisite pointers & values into that call frame's volatile stack/memory.
So unless you explicitly:
a) align caller+delegate contract storage
b) explicitly pass in the caller contract's storage reference addresses
as arguments to use in the function's call frame
your storage pointers are left up to the Delegate's standard function context.
Correct me if I'm wrong. I'm inducing.
add a comment |Â
3 Answers
3
active
oldest
votes
3 Answers
3
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
1
down vote
accepted
To expand on Henk's answer, an important implementation detail is that the storage layout is also used from the calling contract.
Since you declare testVar first, as far as CalledContract is concerned, it is in the same storage location as the CalledContract myVariable. Thus, when delegate call sets myVariable, it is actually updating the storage of testVar.
If you switch the declaration order to:
contract Caller
uint public myVariable = 6;
uint public testVar = 88;
function delegatecallExample(address _contract, uint newVar) public
_contract.delegatecall(bytes4(keccak256("updateMyVariable(uint256)")), newVar);
it will update myVariable instead of testVar.
add a comment |Â
up vote
1
down vote
accepted
To expand on Henk's answer, an important implementation detail is that the storage layout is also used from the calling contract.
Since you declare testVar first, as far as CalledContract is concerned, it is in the same storage location as the CalledContract myVariable. Thus, when delegate call sets myVariable, it is actually updating the storage of testVar.
If you switch the declaration order to:
contract Caller
uint public myVariable = 6;
uint public testVar = 88;
function delegatecallExample(address _contract, uint newVar) public
_contract.delegatecall(bytes4(keccak256("updateMyVariable(uint256)")), newVar);
it will update myVariable instead of testVar.
add a comment |Â
up vote
1
down vote
accepted
up vote
1
down vote
accepted
To expand on Henk's answer, an important implementation detail is that the storage layout is also used from the calling contract.
Since you declare testVar first, as far as CalledContract is concerned, it is in the same storage location as the CalledContract myVariable. Thus, when delegate call sets myVariable, it is actually updating the storage of testVar.
If you switch the declaration order to:
contract Caller
uint public myVariable = 6;
uint public testVar = 88;
function delegatecallExample(address _contract, uint newVar) public
_contract.delegatecall(bytes4(keccak256("updateMyVariable(uint256)")), newVar);
it will update myVariable instead of testVar.
To expand on Henk's answer, an important implementation detail is that the storage layout is also used from the calling contract.
Since you declare testVar first, as far as CalledContract is concerned, it is in the same storage location as the CalledContract myVariable. Thus, when delegate call sets myVariable, it is actually updating the storage of testVar.
If you switch the declaration order to:
contract Caller
uint public myVariable = 6;
uint public testVar = 88;
function delegatecallExample(address _contract, uint newVar) public
_contract.delegatecall(bytes4(keccak256("updateMyVariable(uint256)")), newVar);
it will update myVariable instead of testVar.
answered Aug 25 at 7:25
Raghav Sood
2,0901216
2,0901216
add a comment |Â
add a comment |Â
up vote
2
down vote
This is the correct behaviour for delegatecall. delegatecall is like call, but the difference is the storage context functions run in. When calling another contract, any functions that contract runs access their own storage. With delegatecall, however, the called contract accesses the storage of the caller.
In your example, Caller delegatecalls CalledContract. The function updateMyVariable accesses and updates the first element in storage of Caller, which is testVar, because myVariable points to the first storage element.
Docs on call and delegatecall
add a comment |Â
up vote
2
down vote
This is the correct behaviour for delegatecall. delegatecall is like call, but the difference is the storage context functions run in. When calling another contract, any functions that contract runs access their own storage. With delegatecall, however, the called contract accesses the storage of the caller.
In your example, Caller delegatecalls CalledContract. The function updateMyVariable accesses and updates the first element in storage of Caller, which is testVar, because myVariable points to the first storage element.
Docs on call and delegatecall
add a comment |Â
up vote
2
down vote
up vote
2
down vote
This is the correct behaviour for delegatecall. delegatecall is like call, but the difference is the storage context functions run in. When calling another contract, any functions that contract runs access their own storage. With delegatecall, however, the called contract accesses the storage of the caller.
In your example, Caller delegatecalls CalledContract. The function updateMyVariable accesses and updates the first element in storage of Caller, which is testVar, because myVariable points to the first storage element.
Docs on call and delegatecall
This is the correct behaviour for delegatecall. delegatecall is like call, but the difference is the storage context functions run in. When calling another contract, any functions that contract runs access their own storage. With delegatecall, however, the called contract accesses the storage of the caller.
In your example, Caller delegatecalls CalledContract. The function updateMyVariable accesses and updates the first element in storage of Caller, which is testVar, because myVariable points to the first storage element.
Docs on call and delegatecall
edited Aug 25 at 7:31
answered Aug 25 at 7:23
Henk
2,2571217
2,2571217
add a comment |Â
add a comment |Â
up vote
1
down vote
I don't think your question was directly answered in the previous responses.
When any function is called - delegatecall or otherwise - the EVM loads the requisite pointers & values into that call frame's volatile stack/memory.
So unless you explicitly:
a) align caller+delegate contract storage
b) explicitly pass in the caller contract's storage reference addresses
as arguments to use in the function's call frame
your storage pointers are left up to the Delegate's standard function context.
Correct me if I'm wrong. I'm inducing.
add a comment |Â
up vote
1
down vote
I don't think your question was directly answered in the previous responses.
When any function is called - delegatecall or otherwise - the EVM loads the requisite pointers & values into that call frame's volatile stack/memory.
So unless you explicitly:
a) align caller+delegate contract storage
b) explicitly pass in the caller contract's storage reference addresses
as arguments to use in the function's call frame
your storage pointers are left up to the Delegate's standard function context.
Correct me if I'm wrong. I'm inducing.
add a comment |Â
up vote
1
down vote
up vote
1
down vote
I don't think your question was directly answered in the previous responses.
When any function is called - delegatecall or otherwise - the EVM loads the requisite pointers & values into that call frame's volatile stack/memory.
So unless you explicitly:
a) align caller+delegate contract storage
b) explicitly pass in the caller contract's storage reference addresses
as arguments to use in the function's call frame
your storage pointers are left up to the Delegate's standard function context.
Correct me if I'm wrong. I'm inducing.
I don't think your question was directly answered in the previous responses.
When any function is called - delegatecall or otherwise - the EVM loads the requisite pointers & values into that call frame's volatile stack/memory.
So unless you explicitly:
a) align caller+delegate contract storage
b) explicitly pass in the caller contract's storage reference addresses
as arguments to use in the function's call frame
your storage pointers are left up to the Delegate's standard function context.
Correct me if I'm wrong. I'm inducing.
answered Aug 28 at 13:05
Ask Programmers
415
415
add a comment |Â
add a comment |Â
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fethereum.stackexchange.com%2fquestions%2f57418%2fscope-confusion-using-delegate-call%23new-answer', 'question_page');
);
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
