Double delegate call doesn't work

Clash Royale CLAN TAG#URR8PPP
up vote
2
down vote
favorite
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!
contract-development delegatecall
add a comment |Â
up vote
2
down vote
favorite
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!
contract-development delegatecall
add a comment |Â
up vote
2
down vote
favorite
up vote
2
down vote
favorite
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!
contract-development delegatecall
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!
contract-development delegatecall
asked Aug 15 at 10:22
Mikky Snowman
386
386
add a comment |Â
add a comment |Â
 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 valueare located on storage slot0. - with 
address aandaddress blocated on storage slot1 
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 :)
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
add a comment |Â
 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 valueare located on storage slot0. - with 
address aandaddress blocated on storage slot1 
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 :)
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
add a comment |Â
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 valueare located on storage slot0. - with 
address aandaddress blocated on storage slot1 
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 :)
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
add a comment |Â
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 valueare located on storage slot0. - with 
address aandaddress blocated on storage slot1 
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 :)
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 valueare located on storage slot0. - with 
address aandaddress blocated on storage slot1 
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 :)
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
add a comment |Â
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
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%2f56575%2fdouble-delegate-call-doesnt-work%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