Skip to content
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

New opcode: STATIC_CALL #116

Closed
vbuterin opened this issue Jun 19, 2016 · 17 comments
Closed

New opcode: STATIC_CALL #116

vbuterin opened this issue Jun 19, 2016 · 17 comments

Comments

@vbuterin
Copy link
Contributor

vbuterin commented Jun 19, 2016

If block.number >= METROPOLIS_FORK_BLKNUM, then opcode 0xfa functions equivalently to a CALL, except it takes 6 arguments not including value, and calls the child with a STATIC flag on. Any calls, static or otherwise, made by an execution instance with a STATIC flag on will also have a STATIC flag on. Any attempts to make state-changing operations inside an execution instance with a STATIC flag on, including nonzero-value calls, creates, and SSTORE, SSTOREBYTES or SUICIDE operations, will instead throw an exception.

Rationale

This allows contracts to make calls that are clearly non-state-changing, reassuring developers and reviewers that re-entrancy bugs or other problems cannot possibly arise from that particular call; it is a pure function that returns an output and does nothing else. This may also make purely functional HLLs easier to implement.

@wanderer
Copy link
Member

would there be anyway for a contract to dectect if it was in static mode or not?

@vbuterin
Copy link
Contributor Author

Suppose contract C has code def test(): ~call(msg.sender, 0, 1, 0, 0, 0, 0), call C.test(), see if it passes. That said, I don't see the need for it; solidity should only allow you to call constant functions in static mode, and non-constant functions only in non-static mode.

@chriseth
Copy link
Contributor

Sounds great! On the solidity side, this opcode could be utilized by all calls into functions marked as constant.

@chfast
Copy link
Member

chfast commented Jun 20, 2016

This looks like a good feature to me as well.

However, do you think there is a time to do a step back and see our call system from higher perspective? Just to know what design decisions where wrong, what is missing, and where should we go in the future?

@axic
Copy link
Member

axic commented Jun 20, 2016

Agree with @chriseth that this nicely matches with what is marked as constant in Solidity and the ABI.

Also agree with @chfast that probably quickly adding different call semantics might not be the best approach, when the system could be reviewed in the first place with all the experience gathered so far over the 11 months of public testing.

@vbuterin
Copy link
Contributor Author

So far we have CALL and DELEGATECALL (as far as I can see CALLCODE is useless now that DELEGATECALL exists). DELEGATECALL is essentially a hack that makes an account's code de-facto mutable. I don't think changing CALL is viable given how many contracts are relying on it. I think CALL/STATIC_CALL has precedent because C++ and other languages have a notion of "constant functions"; this is just what is necessary to make constant functions actually constant in a multi-user multi-contract environment where some of the things you're calling may be black boxes. We could also come up with other calling styles (eg. SANDBOXED_CALL in #117, which (in my modified interpretation) adds the restriction that the call can only change state in the destination address).

@gcolvin
Copy link
Contributor

gcolvin commented Jun 23, 2016

This is easy enough to implemen. Why STATIC_CALL rather than CONSTANT_CALL?

@chfast
Copy link
Member

chfast commented Jun 24, 2016

Because the static keyword is the most overused word in the world of programming languages.

@zack-bitcoin
Copy link

zack-bitcoin commented Jul 10, 2016

Is there a way to call a function without putting that function onto the consensus state of any contract?

@sjalq
Copy link

sjalq commented Jul 13, 2016

I think this is a step in the right and the wrong direction at once.

To gain a lot from this we need a few concepts;

  1. Memioization: The ability to calculate a function, param set only once and store the answer. To do this the function cannot access volatile state, the volatile state must be passed in via parameters. The benefit for Ethereum is unclear at present; it may play out that memioization can reduce evaluation time and possibly cause a major drop in gas prices. It could be that it adds nothing and the cache costs more to maintain than to ignore.
  2. Side-effects: What this is ultimately about is the ability to call a "Query" in Command/Query Separation terms. To do that, we cannot simply call existing methods that were written with state changes in mind, we need to properly flag methods on the blockchain as having no side effects. The benefits for Ethereum get huge here; we can begin to build up a library of trust worthy functions that can also be parallelized to an astonishing degree depending on the problem. This will greatly reduce evaluation times and gas prices. To ensure non-side effecting calls, we can also not allow a Query to call a Command (function with side effects). We also need a mechanism to prevent calls to other contracts from pointing to Queries at compile time, but pointing to Commands when the other contracts get upgraded.

@chriseth
Copy link
Contributor

On the solidity side we will soon distinguish between functions that do not modify state but can read state and actual pure functions which only depend on their arguments (and not on the state).

Adding PURE_CALL can enforce that on EVM-level and would also allow some optimizations at execution time.

@axic
Copy link
Member

axic commented Sep 12, 2016

@chriseth seems like we had the same idea: https://www.reddit.com/r/ethereum/comments/5256ht/ethereum_20_mauve_paper/d7jbt9h. See also @vbuterin's answer.

@axic
Copy link
Member

axic commented Sep 12, 2016

@chriseth actually, the original proposal above allows the use of SLOAD so it would map to Solidity's view keyword and not to pure.

@chriseth
Copy link
Contributor

@axic yes, my comment was about adding both STATIC_CALL and PURE_CALL.

@axic
Copy link
Member

axic commented Sep 12, 2016

@chriseth 👍

@chriseth
Copy link
Contributor

Another idea about redesigning the call opcode: Currently, solidity performs a basic check to see whether the called address is at least a contract (it cannot check any further type information, but at least this creates some basic protection). With #150 this makes calls even more expensive on the gas side but not on the resource consumption side. In light of this, it might be good to provide a way to automatically include the extcodesize > 0 check as part of the call (of course, we still need the ability to send ether and also send ether with data to non-contract accounts, so this should only be a "flag" of the opcode).

@chriseth
Copy link
Contributor

Replaced by #214

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

9 participants