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: INJECTED_STATIC_CALL #199

Closed
pipermerriam opened this issue Jan 30, 2017 · 18 comments
Closed

New Opcode: INJECTED_STATIC_CALL #199

pipermerriam opened this issue Jan 30, 2017 · 18 comments

Comments

@pipermerriam
Copy link
Member

pipermerriam commented Jan 30, 2017

I propose a new opcode, INJECTED_STATIC_CALL which would be built off of the semantics of STATIC_CALL from EIP116. The INJECTED_STATIC_CALL opcode would operate in the same manner as STATIC_CALL, disallowing any state modifying actions. This opcode would take one additional address argument. The code executed by INJECTED_STATIC_CALL would be executed in the context of the storage for the given address.

The motivation for this opcode comes from a gap in functionality that EIP144 may leave. EIP144 will allow external calls to query the storage of arbitrary contracts using EVM code. The addition of this new opcode would enable this same functionality for contracts.

@pipermerriam pipermerriam changed the title New Opcode: INJECT_STATIC_CALL New Opcode: INJECTED_STATIC_CALL Jan 30, 2017
@Arachnid
Copy link
Contributor

What's the motivating use-case for this? As far as I'm concerned, contracts only being able to interact with each other via their exposed public APIs is an asset, not a liability.

@danfinlay
Copy link
Contributor

As long as it only allows reads, what liability could it create? The whole blockchain is public anyways, this just makes some of that data easier to read.

@Arachnid
Copy link
Contributor

I'm concerned that it will encourage people to ignore or avoid the interfaces publicly exposed by contracts, and I haven't heard a compelling use-case for offering it.

All of the data in a contract can be accessed offchain, and that's fine, but I think there's a good argument for requiring contracts to talk to each other only via their ABIs.

@pipermerriam
Copy link
Member Author

pipermerriam commented Jan 31, 2017

@Arachnid in all previous context's that I've done development I think I would agree but for smart contract development I think this fits well. Here are the use cases that I see as compelling.

  1. It is easy to reach the gas limit in contract development. One of the common ways I've gone about reducing size is munging all of my getters together. Instead of function getA, function getB, function getC you end up with function getABC which returns all 3 values. There are cases where the combined getter API is good but there are also plenty of cases where it results in harder to read code. This opcode would allow for contract developers to write the right getter API rather than the one that reduces the deploy gas costs.

  2. Contracts don't always expose the data you need in the format you need. In the traditional web world, we typically would just write some code to translate the data into the format we want. In contract development this type of data munging can be prohibitively expensive. Allowing direct access to the storage will allow this type of data munging in a much more efficient way.

  3. Being able to fetch only the piece of data you need reduces gas costs for the contracts reading that data.

Arguments against that I've heard.

  1. What about contracts that make you pay for their data. Since the data is already available to the outside world, I think that this pattern is fundamentally flawed. It is trivial to circumvent these types of paywalls.

@pipermerriam
Copy link
Member Author

Another thing that I like this feature for is situations where you contracts that just act as views on top of an underlying database contract. With a sufficiently complex database contract it becomes very difficult to forecast what read APIs you may need going forward. In the current world this requires that you build in the ability to get at 100% of the data up front. This new opcode would allow you to only build the initial API that you need for reading data (or none at all) with the knowledge that you can implement that API in the view contracts that sit in front of the DB contract.

@nmushegian
Copy link

I thought hiding private state (from other on-chain consumers) was a design feature of the EVM. injectCall is just sugar for something you can already off chain

@pipermerriam
Copy link
Member Author

I thought hiding private state (from other on-chain consumers) was a design feature of the EVM.

Given that it is relatively trivial to circumvent the "privateness" of that data I'd posture that this isn't a very solid or reliable feature.

injectCall is just sugar for something you can already off chain

Along that reasoning, since you can already do this off chain, why not allow it on-chain as well.

@nmushegian
Copy link

Given that it is relatively trivial to circumvent the "privateness" of that data I'd posture that this isn't a very solid or reliable feature.

You can read the data from my Super Authoritative Oracle Aggregator and resubmit it, but I can still charge the first consumer on-chain who wants the "real" thing. These and probably other building blocks stop working. I bet there will be some kind of obfuscation arms race if this is enabled.

@nmushegian
Copy link

Along that reasoning, since you can already do this off chain, why not allow it on-chain as well.

Ok and along that reasoning, we should be able to read historic log state into contract state.

@pipermerriam
Copy link
Member Author

Ok and along that reasoning, we should be able to read historic log state into contract state.

And if we legalize marijuana we'll probably have to legalize heroin and cocaine as well. Can not use that style of argument?

I can still charge the first consumer on-chain who wants the "real" thing.

This is purely my opinion, but the business model of contract's which charge other contracts for data feels flawed and not worth protecting. It is borderline trivial to circumvent or undermine these systems.

I'd also point out that were this to be implemented, it doesn't preclude oracles from charging for information. It just eliminates the ability to charge for information that is already on the blockchain.

@nmushegian
Copy link

It just eliminates the ability to charge for information that is already on the blockchain.

This essentially forces all architectures to be push-oriented instead of allowing pull-oriented data flows. This may be viable, but it really needs us to try working through some non trivial examples and see if it forces awkward constraints on systems that use monetized feeds

@nmushegian
Copy link

I would love input from anyone who was in the original "allow private state or not" debate. @gavofyork maybe?

@pipermerriam
Copy link
Member Author

More discussion over at the BTCRelay repository relevant to this. ethereum/btcrelay#44

I'd present that as further evidence that private state is a flawed concept. Monetized feeds are fine, but money is paying for the data to be put into the blockchain (much like what oraclize.it does). If the payment is for data that is already on chain then there will be ways to circumvent that payment (which can be done today with the current EVM).

@nmushegian
Copy link

nmushegian commented Mar 24, 2017

If the payment is for data that is already on chain then there will be ways to circumvent that payment (which can be done today with the current EVM).

I guess the point is that you actually can't fully circumvent it and preserve the EVM's trust properties, and it was a deliberate choice to force this out of this layer in order to enable certain kinds of dapps.

Another way to say this is that certain kinds of "metadata" should be treated as off chain data (like logs and maybe private state). I believe this enables a kind of pull-oriented dataflow which might be more efficient if we want 'pay for new data' feature (I'd need time to make that argument). Whether or not this is sufficient reason to have private state is not clear to me.

I don't find the btcrelay discussion to be convincing one way or the other, it's not an interesting "already in the state but unaccessible" case if I understand correctly. I'd really like to see what the people who deliberately discussed this and then decided this way have to say. I think this happened because of a blog post during POC phase or something like that.

@pipermerriam
Copy link
Member Author

I'd really like to see what the people who deliberately discussed this and then decided this way have to say

I am interested in this as well. @vbuterin ? can you provide any information about previous conversations that have happened resulting in the choice to make contract state "private" by default?

@vbuterin
Copy link
Contributor

vbuterin commented May 5, 2017

I think that aside from preserving a bit of data feed monetizability the idea was to preserve an object-oriented programming principle, where contracts would interact with each other through calls instead of directly reading into each other's state. One practical benefit of this is that right now it's theoretically possible to make hardforks that heavily reorganize the way that storage and code work, eg. completely rewriting how storage is organized and then making appropriate modifications to code to fit into the new model, but allowing contracts to access external storage would make this trickier, as you would have to deal with the case where code of contract A acts on storage of contract B. DELEGATECALL also does this, but it's less bad because you can transform the code at runtime whereas with INJECTED_STATIC_CALL it's the storage that would need to be transformed.

@Arachnid
Copy link
Contributor

Arachnid commented May 5, 2017 via email

@pipermerriam
Copy link
Member Author

I don't feel strongly enough about this proposal to try and push it forward. Thanks @vbuterin for the context on the original decision.

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

6 participants