51

According to the solidity 0.4.17 Release Notes

this release finally checks the modifiers view (used to be named constant) and pure on functions. As a rule of thumb, use view if your function does not modify storage and pure if it does not even read any state information - but the compiler will also suggest the tightest restriction itself.

What does that mean in practice?

0

4 Answers 4

80

In earlier versions, we would apply the constant modifier to indicate that a function doesn't change the storage state in any way. For example:

pragma solidity 0.4.16; 

contract UseConstant {

    string greeting;

    function UseConstant() public {
        greeting = "Hello";
    }

    function SayHello() public constant returns(string says) {
        return greeting;
    }
}

constant indicates that network verification won't be necessary. Callers receive return values (quickly, from local storage and processing) instead of transaction hashes.

Starting with solc 0.4.17, constant is depricated in favor of two new and more specific modifiers.

View This is generally the replacement for constant. It indicates that the function will not alter the storage state in any way.

Pure This is even more restrictive, indicating that it won't even read the storage state.

A pure function might look something like this very contrived example:

function returnTrue() public pure returns(bool response) {
    return true;
}

In Remix, you'll get a warning when you use the old constant modifier. It will examine the function code and indicate the maximum restrictiveness you can safely apply.

Hope it helps.

UPDATE

This is a popular Q&A so I decided to elaborate on it in a more detailed Medium post: https://blog.b9lab.com/calls-vs-transactions-in-ethereum-smart-contracts-62d6b17d0bc2

22

The constant modifier has the meaning that the function won't modify the contract storage (but the word constant didn't actually convey the meaning that it is used for).

The new replacements for constant after Solidity 0.4.17 release, view and pure, convey the meaning of their usage.


view can be considered as the subset of constant that will read the storage (hence viewing). However, the storage will not be modified.

Example:

contract viewExample {

    string state;

    // other contract functions

    function viewState() public view returns(string) {
        //read the contract storage 
        return state;
    }
}

pure can be considered as the subset of constant where the return value will only be determined by its parameters (input values). There will be no read or write to storage and only local variables will be used (has the concept of pure functions in functional programming).

Example:

contract pureExample {

    // other contract functions

    function pureComputation(uint para1 , uint para2) public pure returns(uint result) {
        // do whatever with para1 and para2 and assign to result as below
        result = para1 + para2;
        return  result;
    }

}

To execute/call these pure or view functions from outside, no transaction is needed. Just a call is enough since the state of the blockchain is not changed by calling these. Hence no gas/ether is required for using these functions from outside.

However, internal calls to these functions may cost gas if the internal call is from a transaction. More details regrading how internal calls to these may cost gas can be found here.

6

Say you have a function like this one in the SafeMath library:

function add(uint256 x, uint256 y)
    internal pure
    returns(uint256) {
        uint256 z = x + y;
        assert((z >= x) && (z >= y));
        return z;
    }

No state is being read here.

Whereas

String something;

    function tellMeSomething() returns (string whatever){
    whatever = something;
    }

would access storage. My guess is, that in the first case, when compiling the contract, no opcodes for reading the state in whatsoever way need to be implemented, like it would be the case in the latter example. This should save gas during deployment I think.

5

If a function in solidity writes into storage ex: sendTokenTo(John), it will not have one of these labels. (this function writes into storage because it must change someone's token balance on the blockchain) This is what you are used to. Second, if a function simply reads from storage, but doesn't write anything into storage ex: getTokenBalance(John), this will be a view function. Lastly, if a function doesn't read or write storage, then it is a pure function ex: onePlusOne().

Using pure and view functions allows these functions to consume zero gas, because they are not modifying state. Calling these functions with something like web3.js will result in these pure/view functions being executed by your own node, while executing a normal function that writes into storage will require a miner to execute this function, consuming gas.

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