[Ethereum] Callcode | Delegatecall don’t work

callcodecontract-debuggingdelegatecallsolidity

I was playing around with call, delegatecall and callcode and discovered that the function reset stopped working after I had made a callcode call (here are my actions):

FROM JS SIDE:

— A.makeCall({gas:300000}); // NO ERRORS
— A.sender(); // 0x0000000000000000000000000000000000000000 AS EXPECTED
— A.myVar(); // 0 AS EXPECTED
— B.sender(); // addressA AS EXPECTED
— B.myVar(); // 1 AS EXPECTED

— A.reset({gas: 300000}); // NO ERRORS;

— A.sender(); // 0x0000000000000000000000000000000000000000 AS EXPECTED
— A.myVar(); // 0 AS EXPECTED
— B.sender(); // 0x0 AS EXPECTED
— B.myVar(); // 0 AS EXPECTED

— A.makeCallCode({gas:300000}); // NO ERRORS
— A.sender(); // 0x0000000000000000000000000000000000000002 Oops! It looks like there was no access to msg.sender and sender variable was assigned argument x instead. 
— A.myVar(); // 0 Oops! Nothing was assigned, because of the ↑
— B.sender(); // 0x0 AS EXPECTED
— B.myVar(); // 0 AS EXPECTED

— A.reset({gas: 300000}); //ALL KIND OF ERRORS; WTF IS GOING ON HERE? NO MATTER HOW MUCH GAS I SUPPLY IT STILL FAILS. https://testnet.etherscan.io/tx/0x6654b6739f55690c7114fa9e8cfb7a5959e73d60c37782aee4e211487de859f2 

contract A {
    address public addressB;   
    address public sender;
    uint public myVar;

    function A() {
        addressB = new B();
    }

    function makeCall(){
        addressB.call(bytes4(sha3('set(uint256)')), 1);
    }
    function makeCallCode(){
        addressB.callcode(bytes4(sha3('set(uint256)')), 2);
    }
    function makeDelegateCall(){
        addressB.delegatecall(bytes4(sha3('set(uint256)')), 3);
    }

    function reset(){
        sender = 0;
        myVar = 0;
        B(addressB).reset();
    }
}

contract B {
    address public sender;
    uint public myVar;

    function set(uint x){
        myVar = x;
        sender = msg.sender;
    }
    function reset(){
        sender = 0;
        myVar = 0;        
    }
}

Best Answer

The problem has to do with how variables arranged in the storage. The storage of the called and the calling contract should match. The answer to this question can be found here https://github.com/ethereum/solidity/issues/944

Related Topic