Open DangerousFreedom1984 opened 1 year ago
What you bring up here is a very interesting question, and an important one. Thinking about it was part of my motivation to build TechWallet, the only Monero wallet I know that focusses heavily on enotes (still called outputs there) instead of transactions or just sums of XMR you hold and manage. That testnet-only wallet is here and open for everybody to play with and experience firsthand how such a focus on enotes could look: https://monerotech.info/Wallet
We can certainly discuss here what we see as the best approach of presenting XMR funds to users in a wallet app, but I don't think that any discussion will ever develop a large practical relevance. Even if we, the Seraphis wallet workgroup, or we, the developers of the core Monero software, come to a strong recommendation "how it should be done", wallet app builders are still free how to build new wallets or modify existing ones, and they will act on this freedom.
And, well, there are different wallets for different groups of users, with different levels of knowledge, and different requirements, and it may turn out to be a bad idea to bother all of them with the concept of enotes. There are also multi-coin wallets where I imagine it would be next to impossible to present Monero almost fully centered on enotes, but other cryptocurrencies in more traditional ways. We even have currencies like Ethereum present in such multi-currency wallets that don't have any enote equivalent at all and as far as I know work with a quite different concept of account.
If I posit that different wallet apps have and will continue to have very different UI / UX approaches, what does that mean for the thing we want to build, a new core software component tentatively named wallet3
so far?
In my opinion this means a quite simple thing: We should build wallet3
in a way that is able to provide wallet apps with a maximum of info, so they are fully free to present info to the user in whatever way they deem suitable. No idea about a good Monero wallet app UI shall ever fail because it turns out the core wallet component is not able to deliver the necessary info, either because the info is not exposed through the API, or worse still, the component does not store the info in the first place.
One piece of such info I stumbled over when I built TechWallet is, if I remember correctly, the info which transactions enotes arrived with. It's not important for the internal working of wallet2
of course, so there was no immediate hard necessity to store it. And probably the designers and implementers of wallet2
did not think it important enough to keep the info around for the sole benefit of wallet apps that may want to present it to the user in one way or another.
We should try to have no such holes in wallet3
.
I already voted for this in an earlier issue with this comment.
I agree with your comments that wallet3 should provide the all the information needed for other wallets and API's to use it. In this sense, the EnoteStore
and the TransactionStore
(basically storing the key_images
and PaymentProposals
) should be enough. So for our wallet we can also have both, like a show_enotes
and show_transfers
(like in wallet2) functions and the user decides what he wants to use.
Can you please check my pet example - you will be much faster than I would be: Do the EnoteStore
and TransactionStore
as they exist now store somehow which transaction a particular enote arrrived with, and if spent which transaction it was a input for?
It's worth repeating: I would not recommend taking today's wallet2
based commands e.g. in the CLI wallet as reference. We can do better than that.
Yes, they do. Just look at the structs SpEnoteOriginContextV1
and SpEnoteSpentContextV1
. The only thing missing from the enote_store is the destination and ephemeral_private_keys, which are stored in the transaction_store from the structs JamtisPaymentProposalSelfSendV1
and JamtisPaymentProposalV1
.
Yes, we can do better like showing enotes directly but we can also just show the transactions like it is done today. Why not?
By the way, the MoneroTech website is very nice! The way the enotes are shown here is exactly how you show them there. It is nice for learning and for curious people but there may be too much information too. Maybe only showing transactions makes more sense for some users.
I would like to discuss how the user will interact with his (spent/unspent) enotes.
Currently it is pretty hidden from the user the concept of enotes (or whatever you want to call it like outputs/stealth-addresses/onetime-address...) because we organize them into 'transactions' (as they are also organized like that in the blockchain) and we do everything based on the transactions. For example when we want to visualize our history of interactions with the chain we use 'show_transfers' and all the wallets that I know of would organize the showing functions showing the group of enotes (transactions) instead of the individual ones. Also when we want to make a knowledge_proof, we make proofs based on the txid and never on the single enotes contained there.
With Seraphis, we will have the opportunity to treat the enotes really like digital notes of cash. So instead of showing the transactions and making knowledge proofs on transactions, we can now deal directly with the enotes.
I will go through an example to demonstrate that.
Scenario: The Seraphis hardfork happened and user A has a 100 XMR legacy enote bill. (As if user A received 100 xmr in one transaction before the hardfork).
Now user A sends 10 XMR to user B (an exchange for example) with 1 XMR fees.
Notice that the initial legacy enote with 100 XMR became two seraphis enotes (one of 89 XMR that user A owns and is shown on the wallet) and one that user B owns but not shown here (because user A doesnt own it of course).
Now user A wants to make a knowledge proof showing that his 100 XMR went to user B who received 10 XMR. First, he can inquiry more information about the spent enote by specifying its key_image (the showing function doesnt need to show the key_images every time though there is no risk for security in doing so, only privacy is at risk if the computer is being spied on).
Second, he can use the information of the spent enote (destination/ota/amount) to create a seraphis sent_proof for example, which proves that address B received the amount of 10 XMR.
From the verifier side, he needs the proof, the onetime-address and the amount commitment. If the verifier refuses to accept the proof, the prover can openly publish: the ephemeral_private_key and the recipient address. So any third party looking at the proof must agree that the person in possession of those information created the transaction and the address claimed indeed received the funds.
There is a big problem though, once all these info is revealed anyone can claim that they made this transaction. So if this happens then the only way that the prover has to prove that he made the transaction is by regenerating the transaction with the same input parameters. So the prover should provide a legacy_spend_proof. Which could be either done in this way using jeffro's lib or in this way by passing a reference to the EnoteStore using jberman's scanner. Both are working but I'm not sure yet which we should use (maybe depends on the situation).
So this is just one scenario showing how to work with enotes instead of transactions. The unit_test simulating exactly this scenario can be found here.
I think that the main advantage of working with enotes directly is the feeling/perception that you get when opening a real wallet and seeing real notes.
There are many cool things that could be done on the wallet side like:
Of course the enotes could also be grouped into transactions and only transactions could be displayed (like it is done today) but I think we would not be harvesting the full potential of seraphis and enotes. So I think that going in the direction of creating filters/comparators for enotes like done here is the way to go to visualize them (and transactions if people would still be using this term) instead of gathering them into a transaction like that.
(of course the std::cout is just for prototyping)