Double delegate call doesn't work

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP











up vote
2
down vote

favorite
1












To create an upgradeable contract I have to use multiple proxies. The contract applies to Proxy A, then Proxy A applies to Proxy B. But delegatecall doesn't work in this case.



The simplified code of my contracts:



pragma solidity ^0.4.24;


contract A
uint256 public value = 100;

function mul() public
value *= 2;



contract B
uint256 public value = 200;
address a;

constructor(address _a)
a = _a;


function delegate() public
a.delegatecall(bytes4(keccak256("mul()")));



contract C
uint256 public value = 500;
address b;

constructor(address _b)
b = _b;


function delegate() public
b.delegatecall(bytes4(keccak256("delegate()")));




delegate() function works only if it called at contract B



Thanks!







share|improve this question
























    up vote
    2
    down vote

    favorite
    1












    To create an upgradeable contract I have to use multiple proxies. The contract applies to Proxy A, then Proxy A applies to Proxy B. But delegatecall doesn't work in this case.



    The simplified code of my contracts:



    pragma solidity ^0.4.24;


    contract A
    uint256 public value = 100;

    function mul() public
    value *= 2;



    contract B
    uint256 public value = 200;
    address a;

    constructor(address _a)
    a = _a;


    function delegate() public
    a.delegatecall(bytes4(keccak256("mul()")));



    contract C
    uint256 public value = 500;
    address b;

    constructor(address _b)
    b = _b;


    function delegate() public
    b.delegatecall(bytes4(keccak256("delegate()")));




    delegate() function works only if it called at contract B



    Thanks!







    share|improve this question






















      up vote
      2
      down vote

      favorite
      1









      up vote
      2
      down vote

      favorite
      1






      1





      To create an upgradeable contract I have to use multiple proxies. The contract applies to Proxy A, then Proxy A applies to Proxy B. But delegatecall doesn't work in this case.



      The simplified code of my contracts:



      pragma solidity ^0.4.24;


      contract A
      uint256 public value = 100;

      function mul() public
      value *= 2;



      contract B
      uint256 public value = 200;
      address a;

      constructor(address _a)
      a = _a;


      function delegate() public
      a.delegatecall(bytes4(keccak256("mul()")));



      contract C
      uint256 public value = 500;
      address b;

      constructor(address _b)
      b = _b;


      function delegate() public
      b.delegatecall(bytes4(keccak256("delegate()")));




      delegate() function works only if it called at contract B



      Thanks!







      share|improve this question












      To create an upgradeable contract I have to use multiple proxies. The contract applies to Proxy A, then Proxy A applies to Proxy B. But delegatecall doesn't work in this case.



      The simplified code of my contracts:



      pragma solidity ^0.4.24;


      contract A
      uint256 public value = 100;

      function mul() public
      value *= 2;



      contract B
      uint256 public value = 200;
      address a;

      constructor(address _a)
      a = _a;


      function delegate() public
      a.delegatecall(bytes4(keccak256("mul()")));



      contract C
      uint256 public value = 500;
      address b;

      constructor(address _b)
      b = _b;


      function delegate() public
      b.delegatecall(bytes4(keccak256("delegate()")));




      delegate() function works only if it called at contract B



      Thanks!









      share|improve this question











      share|improve this question




      share|improve this question










      asked Aug 15 at 10:22









      Mikky Snowman

      386




      386




















          1 Answer
          1






          active

          oldest

          votes

















          up vote
          5
          down vote



          accepted










          When, in C, you do b.delegatecall(, what happens is that:



          • the code used is that of B

          • the storage used is that of C

          And B and C have the same storage layout:



          • both the uint value are located on storage slot 0.

          • with address a and address b located on storage slot 1

          So now you are executing B's code with C's storage. And you ask a.delegatecall(bytes4(keccak256("mul()")));. What the underlying bytecode does is actually take C's value at storage slot 1, in effect b, and use that as a. So you are about to delegatecall on B again.



          And you call mul() on B? There is no such function, so it does nothing. In fact, depending on your version of Solidity, this call would silently fail or not.



          It's working as expected :)






          share|improve this answer






















          • Thanks, your answer is very comprehensive. I wonder if it is possible to achieve what Mikky want to do.
            – Mehmet Doğan
            Aug 15 at 14:55










          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%2f56575%2fdouble-delegate-call-doesnt-work%23new-answer', 'question_page');

          );

          Post as a guest






























          1 Answer
          1






          active

          oldest

          votes








          1 Answer
          1






          active

          oldest

          votes









          active

          oldest

          votes






          active

          oldest

          votes








          up vote
          5
          down vote



          accepted










          When, in C, you do b.delegatecall(, what happens is that:



          • the code used is that of B

          • the storage used is that of C

          And B and C have the same storage layout:



          • both the uint value are located on storage slot 0.

          • with address a and address b located on storage slot 1

          So now you are executing B's code with C's storage. And you ask a.delegatecall(bytes4(keccak256("mul()")));. What the underlying bytecode does is actually take C's value at storage slot 1, in effect b, and use that as a. So you are about to delegatecall on B again.



          And you call mul() on B? There is no such function, so it does nothing. In fact, depending on your version of Solidity, this call would silently fail or not.



          It's working as expected :)






          share|improve this answer






















          • Thanks, your answer is very comprehensive. I wonder if it is possible to achieve what Mikky want to do.
            – Mehmet Doğan
            Aug 15 at 14:55














          up vote
          5
          down vote



          accepted










          When, in C, you do b.delegatecall(, what happens is that:



          • the code used is that of B

          • the storage used is that of C

          And B and C have the same storage layout:



          • both the uint value are located on storage slot 0.

          • with address a and address b located on storage slot 1

          So now you are executing B's code with C's storage. And you ask a.delegatecall(bytes4(keccak256("mul()")));. What the underlying bytecode does is actually take C's value at storage slot 1, in effect b, and use that as a. So you are about to delegatecall on B again.



          And you call mul() on B? There is no such function, so it does nothing. In fact, depending on your version of Solidity, this call would silently fail or not.



          It's working as expected :)






          share|improve this answer






















          • Thanks, your answer is very comprehensive. I wonder if it is possible to achieve what Mikky want to do.
            – Mehmet Doğan
            Aug 15 at 14:55












          up vote
          5
          down vote



          accepted







          up vote
          5
          down vote



          accepted






          When, in C, you do b.delegatecall(, what happens is that:



          • the code used is that of B

          • the storage used is that of C

          And B and C have the same storage layout:



          • both the uint value are located on storage slot 0.

          • with address a and address b located on storage slot 1

          So now you are executing B's code with C's storage. And you ask a.delegatecall(bytes4(keccak256("mul()")));. What the underlying bytecode does is actually take C's value at storage slot 1, in effect b, and use that as a. So you are about to delegatecall on B again.



          And you call mul() on B? There is no such function, so it does nothing. In fact, depending on your version of Solidity, this call would silently fail or not.



          It's working as expected :)






          share|improve this answer














          When, in C, you do b.delegatecall(, what happens is that:



          • the code used is that of B

          • the storage used is that of C

          And B and C have the same storage layout:



          • both the uint value are located on storage slot 0.

          • with address a and address b located on storage slot 1

          So now you are executing B's code with C's storage. And you ask a.delegatecall(bytes4(keccak256("mul()")));. What the underlying bytecode does is actually take C's value at storage slot 1, in effect b, and use that as a. So you are about to delegatecall on B again.



          And you call mul() on B? There is no such function, so it does nothing. In fact, depending on your version of Solidity, this call would silently fail or not.



          It's working as expected :)







          share|improve this answer














          share|improve this answer



          share|improve this answer








          edited Aug 15 at 11:53

























          answered Aug 15 at 11:18









          Xavier Leprêtre B9lab

          5,432827




          5,432827











          • Thanks, your answer is very comprehensive. I wonder if it is possible to achieve what Mikky want to do.
            – Mehmet Doğan
            Aug 15 at 14:55
















          • Thanks, your answer is very comprehensive. I wonder if it is possible to achieve what Mikky want to do.
            – Mehmet Doğan
            Aug 15 at 14:55















          Thanks, your answer is very comprehensive. I wonder if it is possible to achieve what Mikky want to do.
          – Mehmet Doğan
          Aug 15 at 14:55




          Thanks, your answer is very comprehensive. I wonder if it is possible to achieve what Mikky want to do.
          – Mehmet Doğan
          Aug 15 at 14:55












           

          draft saved


          draft discarded


























           


          draft saved


          draft discarded














          StackExchange.ready(
          function ()
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fethereum.stackexchange.com%2fquestions%2f56575%2fdouble-delegate-call-doesnt-work%23new-answer', 'question_page');

          );

          Post as a guest













































































          這個網誌中的熱門文章

          How to combine Bézier curves to a surface?

          Propositional logic and tautologies

          Distribution of Stopped Wiener Process with Stochastic Volatility