-
Notifications
You must be signed in to change notification settings - Fork 270
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
Feat: "Stable" state variable #4130
Labels
T-tracking
Type: Tracking Issue. This contains tasklists.
Milestone
Comments
Until we have access to the header from the context it is quite impractical to get a hold of the header value. When #3937 is fixed it should make it fairly easy. |
#3937 is tackled so this is not blocked now. |
This was referenced Jan 31, 2024
LHerskind
added a commit
that referenced
this issue
Jan 31, 2024
michaelelliot
pushed a commit
to Swoir/noir_rs
that referenced
this issue
Feb 28, 2024
Initial crude implementation for AztecProtocol#4130. The way I am getting a hold of the public values through the oracle in here is an abomination. AztecProtocol#4320 is created to fix this.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
The What
The "stable" state variable is a "quick-n-dirty" application enforced immutable - it is way to have something that can be read in both private and public execution.
The state variable is stored in public state, but support both a
read_public
and aread_private
function.The
read_public
is the same as the normalread
on public variables, but theread_private
can be executed in private functions against any prior public state tree (after the contract was deployed).This allows for storing "constant" values like
decimals
,name
andsymbol
in a way that uses the same values in private and public (no need for both aprivate
and apublic
state variable).The values MUST be constant and set in the constructor! If they are updated later on, private execution can "choose" which value to use by altering what
historical_header
they are using to build their proof. This is KNOWN and expected.The state will follow something like
The Why
The reason that stable values is interested, is really because it is a "worse" version of immutables with public/private access.
So why are immutables interested?
Say you have a private donation contract, that whenever people are sending funds, it will split the funds 50/50 between charity A and charity B, essentially like 0xsplits. Since we don't want the user to define A and B but have them defined in contract we need some kind of storage that can be accessed by anyone in private.
The simples way we have with private storage variables are putting it into an immutable singleton and then having everyone use that - Simple!
However, we have an issue here, we need everyone to know the pre-image of the note that we put into the singleton, otherwise they cannot prove knowledge of it 🤔.
So how do we share this public secret? We could emit it as an unencrypted log, but now anyone using it need to have parsed through the logs and we need some standard way to share this.
Personally I dislike this solution with a passion, it adds a dependency of logs to execution.
But say we do that for now.
Our donation is popular, but organizations and daos would like to have support for public donations so they can easily show that they donated, and more easily integrate it into their contracts. For public execution we still need the split, so we put them in public state A and B and call it a day - easy.
We now have 2 version of both A and B, one immutable singleton for each of them and another public state variable for each of them. The probability that we make a fault is now much larger, as we have multiple values that should be the same, but could be made to differ (any 🪃's?).
Cost wise, we have emitted 64 bytes per public value, and 64 bytes + unencrypted logs per immutable, so we need 128bytes+ 🤮 and mess up the separation of concerns.
So say we introduce immutables, a value that is broadcast as part of the code when deploying, and can be read in both public and private, because it is just returning path of the code and not reading storage. In this case, we can have the same A and B values in both domains, making it easier to use, but at the same time reducing the costs as we don't need to emit all the extra data around what contract the data belongs to, so we can get away with just 32 bytes for each of the addresses 😎 4x+ decrease in amount of data to broadcast.
Since this require changes to deployments and need syntax and new oracles to read the data nicely the undertaking might take some time.
Shorter term, we can do the "stable" value proposed in above, throw the data in public state ~64 bytes per field in data costs, and then you simply prove in private that the value is at the expected location in public.
Portal Addresses, and how they relate
You might see how this related to portal addresses? A portal is essentially just the single immutable value that a contract have available today under an enshrined name + the caveat that outgoing messages will be sent to that address.
The reason that we ended up having the
portal_address
like this is relatively simple, it is the exact same issue as above, where we want the contract to know where to direct some message of funds that is consistent between the two domains, but also ease to "know".Essentially, we don't need that the
portal_address
is really the address of therecipient
, we just need the to support constraining therecipient
to some contract defined value very easily - which right now is done by limiting it to only be theportal_address
.A benefit of allowing the contract to pass an address along with the
content
for cross-chain messages is that we can now send from any L2 to any L1 and then simply have the L1 contract perform access control on what it will receive messages from - it is already doing so anyway as many L2 contracts could point at the same portal.Another place where the
portal_address
is used is when the L2 contract is validating the sender of the message it received. But this is done at the application circuit, and can already be altered to be whatever the contract decides, it as mentioned earlier, simply need something to constrain it against.Tasks
Tasks
The text was updated successfully, but these errors were encountered: