Replies: 3 comments 28 replies
-
The more I think about this, the more I lean toward not supporting additional formats. The reasoning for this is two-fold:
|
Beta Was this translation helpful? Give feedback.
-
A few thoughts about the 3rd open question: how would someone discover a note which was sent to them (or to a specific account). As described in the original post, the naive solution would be to examine each newly created note and see if its script could be executed against a specific account. For high-throughput systems this approach is completely impractical. For one, this can never be done on a smartphone or even a laptop. But also, it required There are actually two broad use cases for why we want note targets to be easily discoverable:
User-to-user interactionsUser-to-user interactions break down further into two categories:
As mentioned above, we assume that the recipient is not powerful enough to scan all incoming notes, and therefore, they must delegate this scanning to someone else (i.e., a full node). If the recipient knows the exact hash of the note, they could make periodic requests to a full node to see if a note with this hash has been created. Or, they could register this hash with the full node, and once the full node sees a note with this hash, they could forward this note to the recipient. From the full node's perspective, the work would be pretty simple: check if a note with a given hash exists (a full node will probably maintain such an index anyway) and send the note to the recipient. However, this approach is undesirable for two reasons:
The second issue could be mitigated by using bloom filters, but I think there is a better solution which addresses both issues. Specifically, the sender could craft a note in such a way that the note's hash has a specific prefix. Then, the recipient would register this prefix with a full node, and any time the full node sees a note with a given prefix, they would forward this note to the recipient. Let's say the recipient sets the prefix to be 10 bits. Then, they would get roughly every 1000th note. For a 16-bit prefix, they would get roughly every 65000th note. The smaller the prefix, the more "false positives" (i.e., notes which were not actually intended for the recipient) will be sent to the recipient - but that's the price to pay for flexibility and privacy. This prefix-based approach can be used for the second category as well (i.e., no separate channel between users). For example, a QR code may contain the desired prefix. Then the sender would get this info and use it to construct the note for recipient. Notes for network transactionsAs mentioned above, with notes for network transactions, we want to achieve two things:
The first part is easily solved by slightly modifying the note format bits described in #7 (reply in thread). Specifically, we could define the values which these bits encode like this:
Now, by examining the first two bits of a note, a block producer will be able to tell whether they should try to process the note themselves or not. To figure out how the note is to be processed, we could also apply the same note prefix idea as before, but add a bit more structure to it. The exact design probably deserves a much more thorough analysis, but we it could look something like this:
Computing the prefixOne thing I didn't describe above is how does the sender ensure that a note's hash has the required prefix. The methodology here is pretty simple: grind on the note's serial number (i.e., try many different serial numbers) until the hash has the required structure. Since computing a note's hash requires 4 invocations of the hash function, the average complexity of finding the right This is actually not so bad. Assuming we use RPO as a hash, on a laptop this can be done in a fraction of a second. I haven't measured this on a smart phone, but my guess is that it should take slightly less than a second on a modern mid-range smart phone. Of course, if we use something more efficient than RPO, then this can be done faster. Thus, for practical settings, we could have something like this:
It is important to point out that at the protocol level we define meaning only for the first 2 bits. All other bits are defined "by convention". There is no reason, for example, why a specific user would not use a smaller (or a bigger) tag. For example, I can set my tag at 10 bits (rather than 14), but in this case, I would have to process every 1000th note instead of every 16000th note. Conversely, I could set my tag to 16-bits, and then I would need to process only every 65000th note, but then senders might have to spend a bit more time finding the right prefix (which may be fine in the future as hash functions or hardware becomes faster). |
Beta Was this translation helpful? Give feedback.
-
UpdatesThe discussion has been split up into multiple issues, for reference they are:
ProposalHere is my summary of the discussion: Types of execution:
Two types of transactions:
Here is how the execution and transaction types related to each other and the note format:
The
The
|
Beta Was this translation helpful? Give feedback.
-
As implemented in #5, notes consist of 3 components:
We need to know all details of these components to consume a note in a transaction, but how the notes are actually recorded on chain could be quite different. Some options are discussed below.
Basic formats
Note hash only
This is by far the most compact way to represent a note on-chain. No information about the script, the vault, or the serial number is recorded - only the note's hash goes on chain. To consume this note, the recipient will need to know all the details, which will probably need to be communicated off-chain. A note stored in this way can be consumed in:
Full note details
The opposite of the above approach is to store all note details on chain. This could take up quite a bit of space, especially if the script is complex (the script will be recorded in the serialized Miden assembly format). However, the upside is that no off-chain communication is needed - anyone observing the chain will be able to process this note.
Potential additional formats
It may be desirable to define some additional formats which are more compact than recording all note details on chain, but at the same time require no off-chain communication. Some examples are below.
Simple transfer
If a note just transfers assets to a single account, we can record the following components:
Seeing this type of a note, the recipient will assume that a standard script is executed. The script could be something like:
The MAST of this script can be constructed based on the account ID recorded on chain. This format is somewhat similar to P2PKH in Bitcoin.
Simple transfer with recall
We can make transfers safer by adding a recall condition. That is, if I sent assets to a non-existent address, I could recall the note after some time. Such a note can be recorded as follows:
A standard script for this note type could look like:
Encoding note type
Instead of adding a new field to identify the type of a note, we could just grind on the serial number until the note hash has a certain structure. For example, we could encode the type in the first 6 or 8 bits of the note hash. This would give us between 64 and 256 available types, and the time needed to grind 6 or 8 bits is negligible.
Open questions
Beta Was this translation helpful? Give feedback.
All reactions