Scope confusion using delegate call

The name of the pictureThe name of the pictureThe name of the pictureClash 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?







share|improve this question
























    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?







    share|improve this question






















      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?







      share|improve this question












      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?









      share|improve this question











      share|improve this question




      share|improve this question










      asked Aug 25 at 7:14









      Cem Güler

      1134




      1134




















          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.






          share|improve this answer



























            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






            share|improve this answer





























              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.






              share|improve this answer




















                Your Answer







                StackExchange.ready(function()
                var channelOptions =
                tags: "".split(" "),
                id: "642"
                ;
                initTagRenderer("".split(" "), "".split(" "), channelOptions);

                StackExchange.using("externalEditor", function()
                // Have to fire editor after snippets, if snippets enabled
                if (StackExchange.settings.snippets.snippetsEnabled)
                StackExchange.using("snippets", function()
                createEditor();
                );

                else
                createEditor();

                );

                function createEditor()
                StackExchange.prepareEditor(
                heartbeatType: 'answer',
                convertImagesToLinks: false,
                noModals: false,
                showLowRepImageUploadWarning: true,
                reputationToPostImages: null,
                bindNavPrevention: true,
                postfix: "",
                onDemand: true,
                discardSelector: ".discard-answer"
                ,immediatelyShowMarkdownHelp:true
                );



                );













                 

                draft saved


                draft discarded


















                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






























                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.






                share|improve this answer
























                  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.






                  share|improve this answer






















                    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.






                    share|improve this answer












                    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.







                    share|improve this answer












                    share|improve this answer



                    share|improve this answer










                    answered Aug 25 at 7:25









                    Raghav Sood

                    2,0901216




                    2,0901216




















                        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






                        share|improve this answer


























                          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






                          share|improve this answer
























                            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






                            share|improve this answer














                            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







                            share|improve this answer














                            share|improve this answer



                            share|improve this answer








                            edited Aug 25 at 7:31

























                            answered Aug 25 at 7:23









                            Henk

                            2,2571217




                            2,2571217




















                                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.






                                share|improve this answer
























                                  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.






                                  share|improve this answer






















                                    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.






                                    share|improve this answer












                                    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.







                                    share|improve this answer












                                    share|improve this answer



                                    share|improve this answer










                                    answered Aug 28 at 13:05









                                    Ask Programmers

                                    415




                                    415



























                                         

                                        draft saved


                                        draft discarded















































                                         


                                        draft saved


                                        draft discarded














                                        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













































































                                        Comments

                                        Popular posts from this blog

                                        What does second last employer means? [closed]

                                        List of Gilmore Girls characters

                                        Confectionery