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 call
ing 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
delegatecall
s 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 call
ing 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
delegatecall
s 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 call
ing 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
delegatecall
s 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 call
ing 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
delegatecall
s 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 call
ing 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
delegatecall
s 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