-
Notifications
You must be signed in to change notification settings - Fork 204
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
Retroactive: Add Noir contract function types #1168
Comments
The semantics around inlining were copied from a chat I had with @sirasistant -- Gracias ser |
Typo. Also: In Solidity, if a user wants to call an |
Thanks for spotting the typo! That sounds somewhat confusing since Note: We don't allow function overloading, so users would need to find some naming scheme for their internal and external functions. ^ This does not preclude bugs btw, just makes them less common due to not having function overloading. Maybe we can have some other annotation to convey the fact that "this should definitely not be inlined" |
Regarding
Non secret functions would need to be compiled to brillig to be proven in a brillig VM by a third party, the sequencer, who could just say that the function fails to execute otherwise. Made a PR for this change here #2052 |
Closed with:
|
Problem
A Noir program has one type of function - a private function.
The function can have visibility identifiers, specifying whether the function when in a library, can be callable by another Noir program, but the function type itself stays the same.
As of writing this issue, we do not have visibility identifiers for Noir programs. The obvious choice would be to use
pub
because this is what Rust uses, though we may want to re-consider given the ambiguity aroundpub
-- maybe its fine.Proposed solution
Types of functions
Secret
These are functions which can only be executed by the client, because they are the only entity with the private information.
Functions are by default secret.
Non-Secret
The naming of functions which are not secret is still under discussion. We are aiming to not call them public, since its not clear if we mean a function which is publicly visible or a function which can be executed in a public context, like an ethereum solidity function. There is a also the added confusion due to zkSNARKs using the terminology "public inputs" to refer to inputs to a proof which can be shared by the prover and verifier.
I will use non-secret in this issue.
Now, simply put non-secret functions are functions which do not require the entity executing it to have private information. This state is shared, similar to public blockchains like Ethereum, so it must also be synchronized/sequenced.
We make the following assumption: Networks will have a sequencer whom they can rely on to execute and sequence public state. This does not have to be the same entity whom is executing the private state, which means that the entity executing their private state only needs to know about their private state which can be parallelized, and not worry about non-secret state which needs to be synchonized.
If you think about Ethereum, this is roughly how it works minus the private information. There are Nodes who will execute non-secret functions and sequence non-secret state mutations.
Ordering
The ordering of non-secret and secret state execution is important. Since a sequencer will be sequencing your non-secret functions, these will happen after the proofs have been created for secret functions. It is therefore not possible in a single-shot for a non-secret function to call a secret function; since execution of non-secret functions happen after secret functions.
We want to make this an error in the Noir compiler
Loss of generality
We make a simple argument that this does not lose any generality in practice.
Imagine the scenario where a user wanted to call a secret function
s
from a non-secret functionns
in a single-shot(transaction). The only case where this is feasible is if the user also held and synchronized the non-secret state too. i.e. the user is the sequencer. This is by definition, since secret state does not need to be synchronized/ordered whereas non-secret state does.Unconstrained
These are functions which allow the user to perform non-determinism. They are not directly callable from other contracts, since the code in the unconstrained function should only appply to the current contract.
They are still placed in the contract ABI and are callable from entities like wallets. This is what a user will use to, for example, get their balance.
Visibility
External
(This is up for discussion -- and will change after more discussion with @iAmMichaelConnor)
An external function is a function that will be placed in the contract ABI.
Internal
An internal function is a function that can only be called from functions in the same contract.
Inlining
Same contract
non-secret functions are not allowed to call secret functions, even in the same contract.
Rough Idea
This is because an internal and an external function are processed differently, one can view them as having different ABIs. If we were to allow same contract, external functions to be inlined, then the compiler would need to make the appropriate transformations behind the scene, by determining whether we should inline because it is the same contract and function type or not. The proposed strategy will leave this is in the hand of the developer, making it more explicit.
The downside of such an approach is that developes may end up doing the following pattern:
Here we have an internal and external version of the same function, one will be called inside the contract so that it gets inlined and the other will be called from outside of the contract.
Different contract
Note: If two contracts are defined within the same file, the rules still apply as if they were defined in two different files or in entirely different projects.
Calling a function from another contract is never inlined. To emphasize, for example, a secret function in contract A, calling a secret function in contract B, will not be inlined, since that would violate the property that functions should only ever modify their own contract state.
Submission Checklist
The text was updated successfully, but these errors were encountered: