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

Comments

Projects
None yet
9 participants
@vbuterin
Copy link
Collaborator

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

This comment has been minimized.

Copy link
Member

wanderer commented Jun 19, 2016

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

@vbuterin

This comment has been minimized.

Copy link
Collaborator Author

vbuterin commented Jun 19, 2016

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

This comment has been minimized.

Copy link
Contributor

chriseth commented Jun 19, 2016

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

@chfast

This comment has been minimized.

Copy link
Contributor

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

This comment has been minimized.

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

This comment has been minimized.

Copy link
Collaborator Author

vbuterin commented Jun 20, 2016

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

This comment has been minimized.

Copy link
Collaborator

gcolvin commented Jun 23, 2016

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

@chfast

This comment has been minimized.

Copy link
Contributor

chfast commented Jun 24, 2016

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

@zack-bitcoin

This comment has been minimized.

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

This comment has been minimized.

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

This comment has been minimized.

Copy link
Contributor

chriseth commented Sep 12, 2016

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

This comment has been minimized.

Copy link
Member

axic commented Sep 12, 2016

@axic

This comment has been minimized.

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

This comment has been minimized.

Copy link
Contributor

chriseth commented Sep 12, 2016

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

@axic

This comment has been minimized.

Copy link
Member

axic commented Sep 12, 2016

@chriseth 👍

@chriseth

This comment has been minimized.

Copy link
Contributor

chriseth commented Oct 12, 2016

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

This comment has been minimized.

Copy link
Contributor

chriseth commented Feb 13, 2017

Replaced by #214

@chriseth chriseth closed this Feb 13, 2017

@arkpar arkpar referenced this issue Mar 9, 2017

Closed

Byzantium release #4833

12 of 12 tasks complete

@pirapira pirapira referenced this issue Oct 23, 2017

Open

Apply Byzantium changes #459

0 of 10 tasks complete
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment