New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Introduce a real constant keyword and rename the current behaviour #992

Closed
axic opened this Issue Sep 1, 2016 · 47 comments

Comments

Projects
None yet
@axic
Member

axic commented Sep 1, 2016

I think the following makes more sense compared to what we have now.

Now:

  • constant function should not modify the state (not fully enforced yet)
  • constant state variable (ie. the one in the class and not in a method) is evaluated every time it is called

After the change:

    1. the keyword view is introduced for functions (it replaces constant). Calling a view cannot alter the behaviour of future interactions with any contract. This means such functions cannot use SSTORE, cannot send or receive ether and can only call other view or pure functions.
    1. the keyword pure is introduced for functions, they are view functions with the additional restriction that their value only depends on the function arguments. This means they cannot use SSTORE, SLOAD, cannot send or receive ether, cannot use msg or block and can only call other pure functions.
    1. the keyword constant is invalid on functions
    1. the keyword constant on any variable means it cannot be modified (and could be placed into memory or bytecode by the optimiser)
  • 5) the keyword volatile is introduced for variables, which read their referenced value every time (this is what constant does today to variables) [agreed to remove this functionality]

Any example of the volatile keyword:

contract A {
    uint volatile number = block.number;
    function a() returns (uint) {
        return number; // this returns the *current* block.number every time it is called
    }
}

I'm not sure the volatile option is useful and thus we might decide to remove it.

@axic axic changed the title from Rename the current constant keyword (and reserve it for the future) to Introduce a real constant keyword and rename the current behaviour Sep 1, 2016

@Arachnid

This comment has been minimized.

Show comment
Hide comment
@Arachnid

Arachnid Sep 1, 2016

the keyword stateless is introduced for functions (it replaces constant)

This seems like the wrong word; constant functions are definitely not stateless; they often depend on state. If a new name must be used, perhaps something like immutable or pure (in the sense that a pure function is side-effect-free, which is what we're really describing)?

Arachnid commented Sep 1, 2016

the keyword stateless is introduced for functions (it replaces constant)

This seems like the wrong word; constant functions are definitely not stateless; they often depend on state. If a new name must be used, perhaps something like immutable or pure (in the sense that a pure function is side-effect-free, which is what we're really describing)?

@axic

This comment has been minimized.

Show comment
Hide comment
@axic

axic Sep 1, 2016

Member

I'm trying to find the word and stateless ia far from perfect. It should describe that the state is not modified.

Also additionally we could introduce real constant functions, which are indeed stateless and dont depend on the state. I.e. calculating something based on the inputs.

Member

axic commented Sep 1, 2016

I'm trying to find the word and stateless ia far from perfect. It should describe that the state is not modified.

Also additionally we could introduce real constant functions, which are indeed stateless and dont depend on the state. I.e. calculating something based on the inputs.

@Arachnid

This comment has been minimized.

Show comment
Hide comment
@Arachnid

Arachnid Sep 1, 2016

Well, from a CS-theoretic POV, 'pure' is definitely the term you want. More informally, 'side effect free', but that's harder to condense into a keyword.

Arachnid commented Sep 1, 2016

Well, from a CS-theoretic POV, 'pure' is definitely the term you want. More informally, 'side effect free', but that's harder to condense into a keyword.

@redsquirrel

This comment has been minimized.

Show comment
Hide comment
@redsquirrel

redsquirrel Sep 1, 2016

Contributor

I think 'immutable' will be the least ambiguous to most developers.

Contributor

redsquirrel commented Sep 1, 2016

I think 'immutable' will be the least ambiguous to most developers.

@axic

This comment has been minimized.

Show comment
Hide comment
@axic

axic Sep 1, 2016

Member

I like pure, but are we likely to find another use for it? Does view as keyword make sense?

Member

axic commented Sep 1, 2016

I like pure, but are we likely to find another use for it? Does view as keyword make sense?

@axic

This comment has been minimized.

Show comment
Hide comment
@axic

axic Sep 1, 2016

Member

@redsquirrel immutable wouldmean to me that child classes cannot ovveride it.

Member

axic commented Sep 1, 2016

@redsquirrel immutable wouldmean to me that child classes cannot ovveride it.

@redsquirrel

This comment has been minimized.

Show comment
Hide comment
@redsquirrel

redsquirrel Sep 1, 2016

Contributor

@axic I suggest following Java and using 'final' for functions that cannot be overridden.

Contributor

redsquirrel commented Sep 1, 2016

@axic I suggest following Java and using 'final' for functions that cannot be overridden.

@Arachnid

This comment has been minimized.

Show comment
Hide comment
@Arachnid

Arachnid Sep 1, 2016

I like pure, but are we likely to find another use for it?

I don't think so; certainly this is the only usage for the term I'm aware of.

I suggest following Java and using 'final' for functions that cannot be overridden.

I don't think that was under discussion here?

Arachnid commented Sep 1, 2016

I like pure, but are we likely to find another use for it?

I don't think so; certainly this is the only usage for the term I'm aware of.

I suggest following Java and using 'final' for functions that cannot be overridden.

I don't think that was under discussion here?

@VoR0220

This comment has been minimized.

Show comment
Hide comment
@VoR0220

VoR0220 Sep 1, 2016

Collaborator

I agree that we should use pure...perhaps strict? But I really like the idea of pure as a side effect free input. Rather than volatile which conjures up bad imagery, why not static?

Collaborator

VoR0220 commented Sep 1, 2016

I agree that we should use pure...perhaps strict? But I really like the idea of pure as a side effect free input. Rather than volatile which conjures up bad imagery, why not static?

@chriseth

This comment has been minimized.

Show comment
Hide comment
@chriseth

chriseth Sep 1, 2016

Contributor

nonmutating?

Contributor

chriseth commented Sep 1, 2016

nonmutating?

@VoR0220

This comment has been minimized.

Show comment
Hide comment
@VoR0220

VoR0220 Sep 1, 2016

Collaborator

too long...overly blunt descriptive. Less is more imo.

Collaborator

VoR0220 commented Sep 1, 2016

too long...overly blunt descriptive. Less is more imo.

@ethernomad

This comment has been minimized.

Show comment
Hide comment
@ethernomad

ethernomad Sep 1, 2016

Contributor

readonly?

Contributor

ethernomad commented Sep 1, 2016

readonly?

@VoR0220

This comment has been minimized.

Show comment
Hide comment
@VoR0220

VoR0220 Sep 1, 2016

Collaborator

what's wrong with pure or strict as is used in js?

Collaborator

VoR0220 commented Sep 1, 2016

what's wrong with pure or strict as is used in js?

@axic

This comment has been minimized.

Show comment
Hide comment
@axic

axic Sep 1, 2016

Member

Many of the definitions of pure say it does not depend on state and no matter when it is called, based on the input parameters it should always return the same predictable result.

Therefore it does not suit our application.

@VoR0220 static does not reflect what it is. The volatile part is a different behaviour (= what constant variables do).

Updated the description with further clarification which should help coming up with a good name.

Member

axic commented Sep 1, 2016

Many of the definitions of pure say it does not depend on state and no matter when it is called, based on the input parameters it should always return the same predictable result.

Therefore it does not suit our application.

@VoR0220 static does not reflect what it is. The volatile part is a different behaviour (= what constant variables do).

Updated the description with further clarification which should help coming up with a good name.

@VoR0220

This comment has been minimized.

Show comment
Hide comment
@VoR0220

VoR0220 Sep 1, 2016

Collaborator

hmmm...so I like that idea in regards to pure it enables solidity to become "functional" (and pleases all the zealots), but in regards to view...I think it might be better to just bite the bullet and call it immutable (because that's what it is). As for volatile, there are uses for it, but not many...probably just call it mutable.

Collaborator

VoR0220 commented Sep 1, 2016

hmmm...so I like that idea in regards to pure it enables solidity to become "functional" (and pleases all the zealots), but in regards to view...I think it might be better to just bite the bullet and call it immutable (because that's what it is). As for volatile, there are uses for it, but not many...probably just call it mutable.

@chriseth

This comment has been minimized.

Show comment
Hide comment
@chriseth

chriseth Sep 1, 2016

Contributor

The problem with immutable is that you cannot apply that adjective to the function. The function itself never changes.

Contributor

chriseth commented Sep 1, 2016

The problem with immutable is that you cannot apply that adjective to the function. The function itself never changes.

@VoR0220

This comment has been minimized.

Show comment
Hide comment
@VoR0220

VoR0220 Sep 1, 2016

Collaborator

right but the output does. Perhaps you could create such a differentiation. You might do something like this

function f) returns immutable (my, output, signature) {

}
Collaborator

VoR0220 commented Sep 1, 2016

right but the output does. Perhaps you could create such a differentiation. You might do something like this

function f) returns immutable (my, output, signature) {

}
@axic

This comment has been minimized.

Show comment
Hide comment
@axic

axic Sep 1, 2016

Member

@VoR0220 it is not the output or the function which is mutable/immutable.

Case 1: function can read state variables (sload). The output of this function will depend on the current state.

Case 2: function can modify state variables (sstore). The output of this function will depend on the current state, as well as it can change the state, which then affects any future invocations.

I've borrowed view from databases. The function provides a modifiedview of the current state (i.e. it uses sload and applies transformations).

Member

axic commented Sep 1, 2016

@VoR0220 it is not the output or the function which is mutable/immutable.

Case 1: function can read state variables (sload). The output of this function will depend on the current state.

Case 2: function can modify state variables (sstore). The output of this function will depend on the current state, as well as it can change the state, which then affects any future invocations.

I've borrowed view from databases. The function provides a modifiedview of the current state (i.e. it uses sload and applies transformations).

@axic

This comment has been minimized.

Show comment
Hide comment
@axic

axic Sep 2, 2016

Member

Can we agree that the behaviour called volatile above should not be present and we can remove it?

Member

axic commented Sep 2, 2016

Can we agree that the behaviour called volatile above should not be present and we can remove it?

@ethers

This comment has been minimized.

Show comment
Hide comment
@ethers

ethers Sep 2, 2016

Member

I don't see much need for volatile.

Many of the definitions of pure say it does not depend on state and no matter when it is called, based on the input parameters it should always return the same predictable result.
Therefore it does not suit our application.

Doesn't the current proposal fit pure? 2) the keyword pure is introduced for functions (they cannot call SSTORE or SLOAD)
Which part is pure breaking?

I think the 4 proposals are good. No one else has made comments about readonly, and I think it fits well with in the 1st proposal, which would read as:

  1. the keyword readonly is introduced for functions (it replaces constant, these functions cannot call SSTORE, but can call SLOAD)

readonly and pure sound accurate enough.

Member

ethers commented Sep 2, 2016

I don't see much need for volatile.

Many of the definitions of pure say it does not depend on state and no matter when it is called, based on the input parameters it should always return the same predictable result.
Therefore it does not suit our application.

Doesn't the current proposal fit pure? 2) the keyword pure is introduced for functions (they cannot call SSTORE or SLOAD)
Which part is pure breaking?

I think the 4 proposals are good. No one else has made comments about readonly, and I think it fits well with in the 1st proposal, which would read as:

  1. the keyword readonly is introduced for functions (it replaces constant, these functions cannot call SSTORE, but can call SLOAD)

readonly and pure sound accurate enough.

@axic

This comment has been minimized.

Show comment
Hide comment
@axic

axic Sep 2, 2016

Member

Doesn't the current proposal fit pure?

Sorry for the confusion, the description was updated after those comments. pure (and every other keyword) was initially proposed for what 1) is. It fits 2) well.

For 1) I like view, readonly, and nonmutating (but this is way too long).

Member

axic commented Sep 2, 2016

Doesn't the current proposal fit pure?

Sorry for the confusion, the description was updated after those comments. pure (and every other keyword) was initially proposed for what 1) is. It fits 2) well.

For 1) I like view, readonly, and nonmutating (but this is way too long).

@Arachnid

This comment has been minimized.

Show comment
Hide comment
@Arachnid

Arachnid Sep 2, 2016

Many of the definitions of pure say it does not depend on state and no matter when it is called, based on the input parameters it should always return the same predictable result.

Yes, you're right - I stand corrected. readonly is probably the sanest I've seen so far, though view also works.

RE constant/volatile/etc, besides dropping the functionality (which seems good to me), why not call it 'alias' or 'define'? That seems to be effectively what it is.

Arachnid commented Sep 2, 2016

Many of the definitions of pure say it does not depend on state and no matter when it is called, based on the input parameters it should always return the same predictable result.

Yes, you're right - I stand corrected. readonly is probably the sanest I've seen so far, though view also works.

RE constant/volatile/etc, besides dropping the functionality (which seems good to me), why not call it 'alias' or 'define'? That seems to be effectively what it is.

@chriseth

This comment has been minimized.

Show comment
Hide comment
@chriseth

chriseth Sep 2, 2016

Contributor

I think that volatile is just a buggy behaviour of constant. We can introduce something like alias in the future, it is certainly planned for types (using x = y) and could also be introduced for general expressions.

I updated the description to specify the behaviour in more detail.

Question: Can a pure function return address(this)? I.e. is it required to be pure just from its source code or is it fine to be pure "after deployment"? Can a pure function return a storage value that it set in the constructor (i.e. from the block hash) and never modified in the contract?

From the keywords: The problem with readonly is similar to the one with immutable - it applies to the function while it should apply to the state. On the other hand, view is not an adjective.

Contributor

chriseth commented Sep 2, 2016

I think that volatile is just a buggy behaviour of constant. We can introduce something like alias in the future, it is certainly planned for types (using x = y) and could also be introduced for general expressions.

I updated the description to specify the behaviour in more detail.

Question: Can a pure function return address(this)? I.e. is it required to be pure just from its source code or is it fine to be pure "after deployment"? Can a pure function return a storage value that it set in the constructor (i.e. from the block hash) and never modified in the contract?

From the keywords: The problem with readonly is similar to the one with immutable - it applies to the function while it should apply to the state. On the other hand, view is not an adjective.

@axic

This comment has been minimized.

Show comment
Hide comment
@axic

axic Sep 6, 2016

Member

@chriseth moved alias into its own issue and removed volatile from the description.

I.e. is it required to be pure just from its source code or is it fine to be pure "after deployment"?

That is a good question. I would argue that it is more useful to allow this and any constants set during the constructor (if that becomes possible).

Storage should not be accessed by pure functions unless we introduce writeonce storage slots set during the constructor, but what is the reason to use them? They are more expensive than storing it in bytecode.

Member

axic commented Sep 6, 2016

@chriseth moved alias into its own issue and removed volatile from the description.

I.e. is it required to be pure just from its source code or is it fine to be pure "after deployment"?

That is a good question. I would argue that it is more useful to allow this and any constants set during the constructor (if that becomes possible).

Storage should not be accessed by pure functions unless we introduce writeonce storage slots set during the constructor, but what is the reason to use them? They are more expensive than storing it in bytecode.

@chriseth

This comment has been minimized.

Show comment
Hide comment
@chriseth

chriseth Sep 6, 2016

Contributor

Further discussion: Are events allowed in view functions? I would rather say no, as they have an effect on the blockchain even if that effect is not visible from within the EVM.

Contributor

chriseth commented Sep 6, 2016

Further discussion: Are events allowed in view functions? I would rather say no, as they have an effect on the blockchain even if that effect is not visible from within the EVM.

@ethernomad

This comment has been minimized.

Show comment
Hide comment
@ethernomad

ethernomad Sep 6, 2016

Contributor

View functions should not be able to spend any gas.

Contributor

ethernomad commented Sep 6, 2016

View functions should not be able to spend any gas.

@chriseth

This comment has been minimized.

Show comment
Hide comment
@chriseth

chriseth Sep 6, 2016

Contributor

@ethernomad if they are executed on chain, they will always spend gas, but they can be used together with the new static_call opcode that is under discussion and they will be used together with eth_call if invoked from web3.js.

Contributor

chriseth commented Sep 6, 2016

@ethernomad if they are executed on chain, they will always spend gas, but they can be used together with the new static_call opcode that is under discussion and they will be used together with eth_call if invoked from web3.js.

@axic

This comment has been minimized.

Show comment
Hide comment
@axic

axic Sep 6, 2016

Member

Are events allowed in view functions?

I think this question also applies to pure. It is a though question, logs do change the state, but in a way which doesn't influence the future execution of either view or pure functions.

Member

axic commented Sep 6, 2016

Are events allowed in view functions?

I think this question also applies to pure. It is a though question, logs do change the state, but in a way which doesn't influence the future execution of either view or pure functions.

@chriseth

This comment has been minimized.

Show comment
Hide comment
@chriseth

chriseth Sep 9, 2016

Contributor

Let us write a specification about what is and what is not allowed (into the description of this issue). Things to be sorted: be sorted: selfdestruct, log (events), this.balance, address.balance, tx.*, new

Contributor

chriseth commented Sep 9, 2016

Let us write a specification about what is and what is not allowed (into the description of this issue). Things to be sorted: be sorted: selfdestruct, log (events), this.balance, address.balance, tx.*, new

@VoR0220

This comment has been minimized.

Show comment
Hide comment
@VoR0220

VoR0220 Sep 9, 2016

Collaborator

Why do we need to sort those ones out? Can I haz links?

Collaborator

VoR0220 commented Sep 9, 2016

Why do we need to sort those ones out? Can I haz links?

@vbuterin

This comment has been minimized.

Show comment
Hide comment
@vbuterin

vbuterin Sep 13, 2016

Contributor

For volatile, would you be able to do this:

uint volatile foo = block.number + block.timestamp;

Or even:

uint volatile foo = this.bar()

If so, speaking from my experience as a python developer who has dealt many times with debugging code involving @Property declarations, this sounds extremely dangerous. Things should do what they seem to do and nothing else; variable lookups that are actually function calls that might lead to re-entrant weirdness sound like a nightmare for auditing and could potentially mislead contract readers.

Contributor

vbuterin commented Sep 13, 2016

For volatile, would you be able to do this:

uint volatile foo = block.number + block.timestamp;

Or even:

uint volatile foo = this.bar()

If so, speaking from my experience as a python developer who has dealt many times with debugging code involving @Property declarations, this sounds extremely dangerous. Things should do what they seem to do and nothing else; variable lookups that are actually function calls that might lead to re-entrant weirdness sound like a nightmare for auditing and could potentially mislead contract readers.

@axic

This comment has been minimized.

Show comment
Hide comment
@axic

axic Sep 13, 2016

Member

volatile describes what constant does currently. We have agreed to remove this functionality and will perhaps introduce typedef / aliases later: #1013.

Member

axic commented Sep 13, 2016

volatile describes what constant does currently. We have agreed to remove this functionality and will perhaps introduce typedef / aliases later: #1013.

@chriseth

This comment has been minimized.

Show comment
Hide comment
@chriseth

chriseth Sep 13, 2016

Contributor

Note that this "volatile" thing is abusing one application of the constant keyword. This application was intended to provide actual compile-time (or at least deploy-time) constants. As everywhere else, this is not yet correctly enforced.

Contributor

chriseth commented Sep 13, 2016

Note that this "volatile" thing is abusing one application of the constant keyword. This application was intended to provide actual compile-time (or at least deploy-time) constants. As everywhere else, this is not yet correctly enforced.

@chriseth chriseth added the accepted label Sep 30, 2016

@axic

This comment has been minimized.

Show comment
Hide comment
@axic

axic Oct 5, 2016

Member

Things to be sorted: be sorted: selfdestruct, log (events), this.balance, address.balance, tx.*, new

Perhaps we need to define for view whether it can take the state of the contract only or the entire state as an input.

pure:

  • cannot use selfdestruct, new, log, this.balance, address.balance, tx.*, msg.*, block.*

view:

  • cannot use selfdestruct, new
  • can use this.balance
  • can use tx.*, msg.*, block.*

Canonically speaking, view should not use log as it changes the state, however, currently it changes the state in a way it won't affect future invocations of view. Being future proof, I would say it shouldn't be allowed to use it.

Member

axic commented Oct 5, 2016

Things to be sorted: be sorted: selfdestruct, log (events), this.balance, address.balance, tx.*, new

Perhaps we need to define for view whether it can take the state of the contract only or the entire state as an input.

pure:

  • cannot use selfdestruct, new, log, this.balance, address.balance, tx.*, msg.*, block.*

view:

  • cannot use selfdestruct, new
  • can use this.balance
  • can use tx.*, msg.*, block.*

Canonically speaking, view should not use log as it changes the state, however, currently it changes the state in a way it won't affect future invocations of view. Being future proof, I would say it shouldn't be allowed to use it.

@chriseth

This comment has been minimized.

Show comment
Hide comment
@chriseth

chriseth Oct 10, 2016

Contributor

You are right, in serenity, log will be changed to actually make modifications to storage of a certain contract. This means, log should be viewed as a call to a non-view, non-pure function of another contract. Because of that, view should not be able to use log, I would say.

Contributor

chriseth commented Oct 10, 2016

You are right, in serenity, log will be changed to actually make modifications to storage of a certain contract. This means, log should be viewed as a call to a non-view, non-pure function of another contract. Because of that, view should not be able to use log, I would say.

@VoR0220

This comment has been minimized.

Show comment
Hide comment
@VoR0220

VoR0220 Oct 10, 2016

Collaborator

so events are no longer going to be free/near free in terms of gas?

Collaborator

VoR0220 commented Oct 10, 2016

so events are no longer going to be free/near free in terms of gas?

@chriseth

This comment has been minimized.

Show comment
Hide comment
@chriseth

chriseth Jan 2, 2017

Contributor

I think we more or less found that our framework is not yet fully specified because pure functions might modify memory. My current proposal would be the following:

view and pure are attributes applied to the function, and they only concern storage and other permanent state.
The pure keyword should be renamed, because a "pure" function is still able to modify memory references that are passed in (but not storage references). In order to prevent this, the type of such an input variable has to be <memory type> constant.

So in essence, "view" and "pure" apply to "this" (and other state including other contracts) and all other input variables have their own specifiers.

Contributor

chriseth commented Jan 2, 2017

I think we more or less found that our framework is not yet fully specified because pure functions might modify memory. My current proposal would be the following:

view and pure are attributes applied to the function, and they only concern storage and other permanent state.
The pure keyword should be renamed, because a "pure" function is still able to modify memory references that are passed in (but not storage references). In order to prevent this, the type of such an input variable has to be <memory type> constant.

So in essence, "view" and "pure" apply to "this" (and other state including other contracts) and all other input variables have their own specifiers.

@3esmit

This comment has been minimized.

Show comment
Hide comment
@3esmit

3esmit Mar 3, 2017

I suggest the new name as expression or volatile that will evaluate in each call.
See this code:

contract LockableCoin is AbstractCoin {
    //creation time, defined when contract is created
    uint public creationTime = now;
    //time constants, defines epoch size and periods
    uint public constant UNLOCKED_TIME = 25 days;
    uint public constant LOCKED_TIME = 5 days;
    uint public constant EPOCH_LENGTH = UNLOCKED_TIME + LOCKED_TIME;
    //current epoch constant formula, recalculated in any contract call
    uint public constant CURRENT_EPOCH = (now - creationTime) / EPOCH_LENGTH + 1;    
    //next lock constant formula, recalculated in any contract call
    uint public constant NEXT_LOCK = (creationTime + CURRENT_EPOCH * UNLOCKED_TIME) + (CURRENT_EPOCH - 1) * LOCKED_TIME;
//(...)
}

From https://github.com/ethereans/github-token/blob/master/contracts/LockableCoin.sol

3esmit commented Mar 3, 2017

I suggest the new name as expression or volatile that will evaluate in each call.
See this code:

contract LockableCoin is AbstractCoin {
    //creation time, defined when contract is created
    uint public creationTime = now;
    //time constants, defines epoch size and periods
    uint public constant UNLOCKED_TIME = 25 days;
    uint public constant LOCKED_TIME = 5 days;
    uint public constant EPOCH_LENGTH = UNLOCKED_TIME + LOCKED_TIME;
    //current epoch constant formula, recalculated in any contract call
    uint public constant CURRENT_EPOCH = (now - creationTime) / EPOCH_LENGTH + 1;    
    //next lock constant formula, recalculated in any contract call
    uint public constant NEXT_LOCK = (creationTime + CURRENT_EPOCH * UNLOCKED_TIME) + (CURRENT_EPOCH - 1) * LOCKED_TIME;
//(...)
}

From https://github.com/ethereans/github-token/blob/master/contracts/LockableCoin.sol

@3esmit

This comment has been minimized.

Show comment
Hide comment
@3esmit

3esmit Mar 24, 2017

Why word volatile being not considered? I see use cases for this, and its really useful and easy to understand. Volatile are expressions that result a value change due contract storage, chain or call variables change.
Such as:

 //caller balance
    mapping (address => uint) balances;
    uint volatile callerBalance = balances[msg.sender];

//lock epoch
    uint256 public creationTime = now;
    uint256 public unlockedTime = 25 days 
    uint256 public lockedTime = 5 days; 
    uint256 public volatile EPOCH_LENGTH = unlockedTime + lockedTime;
    uint256 public volatile CURRENT_EPOCH = (now - creationTime) / EPOCH_LENGTH + 1;    
    uint256 public volatile NEXT_LOCK = (creationTime + CURRENT_EPOCH * unlockedTime) + (CURRENT_EPOCH - 1) * lockedTime;

I was first fooled by a constant owner that changed in any call, but using a special keyword for this case makes sense.
Just removing this hability makes solidity more restrictive.
Volatile is useful when you need a constant that is synced to various variables and is used a lot of times in almost all functions, if not this case, internal function and a memory var is better.

3esmit commented Mar 24, 2017

Why word volatile being not considered? I see use cases for this, and its really useful and easy to understand. Volatile are expressions that result a value change due contract storage, chain or call variables change.
Such as:

 //caller balance
    mapping (address => uint) balances;
    uint volatile callerBalance = balances[msg.sender];

//lock epoch
    uint256 public creationTime = now;
    uint256 public unlockedTime = 25 days 
    uint256 public lockedTime = 5 days; 
    uint256 public volatile EPOCH_LENGTH = unlockedTime + lockedTime;
    uint256 public volatile CURRENT_EPOCH = (now - creationTime) / EPOCH_LENGTH + 1;    
    uint256 public volatile NEXT_LOCK = (creationTime + CURRENT_EPOCH * unlockedTime) + (CURRENT_EPOCH - 1) * lockedTime;

I was first fooled by a constant owner that changed in any call, but using a special keyword for this case makes sense.
Just removing this hability makes solidity more restrictive.
Volatile is useful when you need a constant that is synced to various variables and is used a lot of times in almost all functions, if not this case, internal function and a memory var is better.

@chriseth

This comment has been minimized.

Show comment
Hide comment
@chriseth

chriseth Mar 24, 2017

Contributor

I like to restrict the number of keywords as much as possible, especially if there is another solution that does almost the same thing.

Contributor

chriseth commented Mar 24, 2017

I like to restrict the number of keywords as much as possible, especially if there is another solution that does almost the same thing.

@pirapira

This comment has been minimized.

Show comment
Hide comment
@pirapira

pirapira Apr 26, 2017

Member

Related: #2181

Member

pirapira commented Apr 26, 2017

Related: #2181

@axic

This comment has been minimized.

Show comment
Hide comment
@axic

axic Aug 15, 2017

Member

Here is a summary of the current design:

There's enum for statemutability, from most restricted to least restricted: pure, view, nonpayable, payable. A function can only be one of these.

view:

  • cannot use selfdestruct, new
  • can use this.balance
  • can use tx.*, msg.*, block.*
  • can only call view or pure functions
  • cannot send ether
  • can use sload
  • cannot use sstore

pure:

  • cannot use selfdestruct, new, log, this.balance, address.balance, tx.*, msg.*, block.*
  • can only call pure functions
  • cannot use sload
  • cannot use sstore

Remarks:

  • JSON ABI has a new field statemutability introduced with a string value as above
  • JSON ABI keeps constant/payable for backwards compatibility for a while
  • constructor / fallback cannot be view or pure
  • constant as a specifier on functions is phased out (removed at the next breaking release)
Member

axic commented Aug 15, 2017

Here is a summary of the current design:

There's enum for statemutability, from most restricted to least restricted: pure, view, nonpayable, payable. A function can only be one of these.

view:

  • cannot use selfdestruct, new
  • can use this.balance
  • can use tx.*, msg.*, block.*
  • can only call view or pure functions
  • cannot send ether
  • can use sload
  • cannot use sstore

pure:

  • cannot use selfdestruct, new, log, this.balance, address.balance, tx.*, msg.*, block.*
  • can only call pure functions
  • cannot use sload
  • cannot use sstore

Remarks:

  • JSON ABI has a new field statemutability introduced with a string value as above
  • JSON ABI keeps constant/payable for backwards compatibility for a while
  • constructor / fallback cannot be view or pure
  • constant as a specifier on functions is phased out (removed at the next breaking release)
@axic

This comment has been minimized.

Show comment
Hide comment
@axic

axic Aug 25, 2017

Member

This is finally implemented and documented. To only thing left is enforcing these restrictions and that is tracked in #2606.

Member

axic commented Aug 25, 2017

This is finally implemented and documented. To only thing left is enforcing these restrictions and that is tracked in #2606.

@chriseth chriseth closed this Aug 25, 2017

jsdavis28 added a commit to Intellimatix/SikkaToken that referenced this issue Nov 17, 2017

Refactor SafeMath with pure modifier
Replace constant modifier with pure in SafeMath: ethereum/solidity#992
@fulldecent

This comment has been minimized.

Show comment
Hide comment
@fulldecent

fulldecent Jan 15, 2018

Contributor

What version is this implemented in?

Contributor

fulldecent commented Jan 15, 2018

What version is this implemented in?

@bitsnaps

This comment has been minimized.

Show comment
Hide comment
@bitsnaps

bitsnaps Mar 6, 2018

@fulldecent I believe view and constant are both working right now, I would like to see readonly, but for compatibility I prefer to stick with view, it's still less ambiguous than constant anyway
https://ethereum.stackexchange.com/questions/25200/solidity-what-is-the-difference-between-view-and-constant

bitsnaps commented Mar 6, 2018

@fulldecent I believe view and constant are both working right now, I would like to see readonly, but for compatibility I prefer to stick with view, it's still less ambiguous than constant anyway
https://ethereum.stackexchange.com/questions/25200/solidity-what-is-the-difference-between-view-and-constant

@mojl

This comment has been minimized.

Show comment
Hide comment
@mojl

mojl Mar 7, 2018

Is it normal behavior for a pure function to access a constant "state variable"?

It make sense architecture-wise, but is this intended and will be doubled down on?

mojl commented Mar 7, 2018

Is it normal behavior for a pure function to access a constant "state variable"?

It make sense architecture-wise, but is this intended and will be doubled down on?

@axic

This comment has been minimized.

Show comment
Hide comment
@axic

axic Mar 7, 2018

Member

A constant "state variable" is just a constant value, it is not a storage variable.

Member

axic commented Mar 7, 2018

A constant "state variable" is just a constant value, it is not a storage variable.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment