1

I'm trying to move storage of my contract into Storage contract with this code

contract Storage {

    struct Block {
        address landlord;
        uint sellPrice;
    }
    Block[101][101] public blocks; 

    function setBlockOwner(uint8 _x, uint8 _y, address _newOwner) external {
        blocks[_x][_y].landlord = _newOwner;
    } 
    function getBlockOwner(uint8 _x, uint8 _y) external view returns (address) {
        return blocks[_x][_y].landlord;
    } 
}

contract MyContract {

    struct Block {
        address landlord;
        uint sellPrice;
    }
    Block[101][101] public blocks; 

    Storage strg;

    function setStorage(address addr) public { strg = Storage(addr); }

    function setNewBlockOwner(uint8 _x, uint8 _y, address _newOwner) public returns (bool) {  //TODO make private
        //strg.setBlockOwner(_x, _y, _newOwner);    //throws with "revert"
        blocks[_x][_y].landlord = _newOwner;        //throws with "out of gas"
        return true;
    }

    // calling this function with (1, 1, 20, 20, some_addr)
    function setBlockOwnerForArea(uint8 fromX, uint8 fromY, uint8 toX, uint8 toY, address _newOwner) {
        for (uint8 ix=fromX; ix<=toX; ix++) {
            for (uint8 iy=fromY; iy<=toY; iy++) {
                setNewBlockOwner(ix, iy, _newOwner);
            }
        }
    }
}

When I'm testing setBlockOwnerForArea with explicitly large values (like 1, 1, 20, 20, some_addr) calling setNewBlockOwner 400 or more times I'm expecting to get "Out of gas" exception.

Instead I get "out of gas" only when storing locally, and "revert" when using Storage contract.

Is it how it should work? Could my Truffle setup interfere somehow?

...setBlockOwnerForArea works with lower values perfectly in both cases...

takeshi
  • 1,760
  • 1
  • 13
  • 33
  • Did you try to increase the gas limit? – Elisha Drion Mar 26 '18 at 13:33
  • @ElishaDrion no, the point is that I want to get out of gas exception. But instead getting "revert" when switching to external storage pattern. – takeshi Mar 26 '18 at 13:36
  • 1
    I tested on Ropsten and it worked fine. By the way, as a note, for MyContract, you want to use Storage as an abstract contract, no need to precise how the functions work. – Elisha Drion Mar 26 '18 at 14:07
  • @ElishaDrion thank you for your help! But I'm trying to figure out how out of gas exceptions work and why there is a difference when deploying external storage. I've deployed two versions of MyContract on testnet, run it with the same parameters and get different exceptions. Using external storage - https://ropsten.etherscan.io/tx/0x0ed86a7fcb2a578dd0d64928f80c21ad109410b965f57522a38a5314cf95dca7, using "local" storage - https://ropsten.etherscan.io/tx/0x41103da5dfa455e28d6d8cecf5e301147e66ba79733e4238db437844ba8acf13. Published source code for both contracts too. – takeshi Mar 27 '18 at 11:59
  • Except they both have "out of gas" errors? I don't see a specific "revert". In this case, with Solidity, when it's out of gas, the entire tx is reverted anyway, so no changes are made to storage. – Elisha Drion Mar 27 '18 at 12:24
  • But the exceptions are different. Truffle sees "revert" and there is also REVERT opcode in VM Trace on Etherscan for the transactions. Probably there is no way for a caller contract to know the specific exception it gets when calling external contract. Maybe It only gets REVERT. The closest answer I found is here - https://ethereum.stackexchange.com/a/8636/2919 – takeshi Mar 27 '18 at 12:36
  • 1
    Trying to see why too...But in any case, they both do a REVERT, it seems to be explicit when using external storage and implicit using local. It's just that it's not written "REVERT" for one. – Elisha Drion Mar 27 '18 at 13:30
  • 1
    Possible answer here : https://www.reddit.com/r/ethdev/comments/72bfrd/solidity_and_evm_error_handling_questions/ – Elisha Drion Mar 27 '18 at 14:08

1 Answers1

2

As stated in my comment, this is what I deployed.

contract Storage {

    struct Block {
        address landlord;
        uint sellPrice;
    }
    Block[101][101] public blocks; 

    function setBlockOwner(uint8 _x, uint8 _y, address _newOwner) external {
        blocks[_x][_y].landlord = _newOwner;
    } 
    function getBlockOwner(uint8 _x, uint8 _y) external view returns (address) {
        return blocks[_x][_y].landlord;
    } 
}

interface Storage {
    function setBlockOwner(uint8 _x, uint8 _y, address _newOwner) external;
    function getBlockOwner(uint8 _x, uint8 _y) external view returns (address);
}

contract MyContract {

    struct Block {
        address landlord;
        uint sellPrice;
    }
    Block[101][101] public blocks; 

    Storage strg;

    function setStorage(address addr) public { strg = Storage(addr); }

    function setNewBlockOwner(uint8 _x, uint8 _y, address _newOwner) public returns (bool) {  //TODO make private
        strg.setBlockOwner(_x, _y, _newOwner);    //throws with "revert"
        blocks[_x][_y].landlord = _newOwner;        //throws with "out of gas"
        return true;
    }
}

I deployed the contracts on the Ropsten testnet.

This is the Storage contract : https://ropsten.etherscan.io/address/0xac509af257f809a9314cc798d6e338dcba1993b1#readContract

Try the values 60,60 and 100,100.

This is the MyContract : https://ropsten.etherscan.io/address/0x02d5f85bd3cd66f21a21e84b8a34d06bd3b89221#code

Elisha Drion
  • 2,641
  • 9
  • 16
  • I'm sorry, but I cannot mark this as an answer. My question is why I can't get out of gas exception, when using external storage pattern. I've deployed to testnet too. Please see question comments. – takeshi Mar 27 '18 at 12:06
  • 1
    Ah, I have been misreading your entire question since the beginning... Could you give an example where you get your revert? – Elisha Drion Mar 27 '18 at 12:10
  • these exceptions differ https://ethereum.stackexchange.com/questions/43868/cannot-get-out-of-gas-exception-when-calling-external-contract/43873?noredirect=1#comment51124_43868 – takeshi Mar 27 '18 at 12:13
  • Oh, the link doesn't work... it is just a link to the 4th comment under my question. – takeshi Mar 27 '18 at 12:20