1

It is currently possible to use a view or constant function to temporarily modify state, for example:

contract Thingy {
    uint public thing;

    function doubler(uint input) public view returns (uint) {
        thing = input * 2;
        return thing;
    }
}

The above code will actually work, but as we are only using a call, the value of thing is reverted after doubler returns.

The following behaviour was actually useful to me recently as a bit of a hacky work around on some problem I was dealing with.

My question is - the compiler currently only throws a warning, not an error, meaning the code will still compile. Will this still be true in the future, or should I avoid exploiting this behaviour?

2

It is only a temporary thing: as per the Solidity documentation:

The compiler does not enforce yet that a view method is not modifying state.

The same goes for pure functions:

The compiler does not enforce yet that a pure method is not reading from the state.

I think that it is safe to say that the intention is to enforce these "promises" in future versions of Solidity and that in the long-term you should think about a different approach to solving similar problems to the one that you previously encountered.

That said, code already compiled and deployed to the main Ethereum network should continue to work as it currently does independent of any future compiler changes.

2

It's silly that the compiler even lets you compile this. You definitely shouldn't modify state in a constant/view function, as that's the entire point of a constant/view function. That being said, view/constant are just for the compiler, so yes, if you really wanted to do this, nothing is stopping you.

The reason that the state is reverted after doubler returns is that you're calling it from off-chain. If you were to call doubler from an on-chain transaction, then the state would very much be updated. This is actually very unsafe. If some malicious party wanted to call your view function doubler, then it would modify the state in your contract. See the following:

pragma solidity ^0.4.17;

contract Thingy {
    uint public thing = 1;

    function doubler(uint input) public view returns (uint) {
        thing = input * 2;
        return thing;
    }

    function test() public {
        doubler(thing);
    }
    function getDoubler() public view returns(uint){
        return thing;
    }
}

If you call test() on-chain then getDoubler() off-chain, thing will actually be doubled every time.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.