seraphis-migration / wallet3

Info and discussions about a hypothetical full 'wallet2' rewrite from scratch
MIT License
14 stars 0 forks source link

Visualizing enotes #59

Open DangerousFreedom1984 opened 1 year ago

DangerousFreedom1984 commented 1 year ago

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).

1) Initial account statement: 
Status: Unspent  |   Amount: 100  |   Type: Legacy  |   Key-image: <13dc1319149ddfdd0fce2b7a4922dfe5dc0756b044d02d0c1d97212517feb1f7>  |   Timestamp origin: 2023-08-30 14:23:51Z  |   Block height origin: 2  |   Tx id origin: <26622218e9c085cda0fb708b770b15eb2cf93cd68d47585cf41fdafd51e79481>
Total unspent: 100

Now user A sends 10 XMR to user B (an exchange for example) with 1 XMR fees.

2) Account statement after transaction: 
Status: Spent - confirmed  |   Amount: 100  |   Type: Legacy  |   Key-image: <13dc1319149ddfdd0fce2b7a4922dfe5dc0756b044d02d0c1d97212517feb1f7>  |   Timestamp spent: 2023-08-30 14:23:51Z  |   Block height spent: 5  |   Tx id spent: <aa8b58083b35cfb34ed67eea560bc5d13f1a3d7e61fa67b8d6857f27d7b6e868>
Status: Unspent  |   Amount: 89  |   Type: Sp  |   Key-image: <8b78f8b31d0a8b2f668c3dbb0a56134d464e7aef5fdaf41225163697cfc5587f>  |   Timestamp origin: 2023-08-30 14:23:51Z  |   Block height origin: 5  |   Tx id origin: <aa8b58083b35cfb34ed67eea560bc5d13f1a3d7e61fa67b8d6857f27d7b6e868>
Total unspent: 89

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).

3) Show specific enote with key-image:  <13dc1319149ddfdd0fce2b7a4922dfe5dc0756b044d02d0c1d97212517feb1f7>
--------------- INFO FROM ENOTE ---------------
  |   Type: Legacy
  |   Key image: <13dc1319149ddfdd0fce2b7a4922dfe5dc0756b044d02d0c1d97212517feb1f7>
  |   Amount commitment: <baf520859b1c5b194932afc57825427290a943926cfd272da82fde38baa7f848>
  |   Amount: 100
  |   Amount blinding factor: <930513cb3a178397fa6789c1d52f5bc79364361328b17e0ebcd52d112c633009>
  |   Onetime-Address: <53e45341d98bf9139106512ce2cbecdd1c6bfed3a42d8ed462fa5ef4aff74734>
  |   Address index:  805163435/1694845538
  |   Enote ephemeral public key: <8d79254f537d888fe87a1e8a80bc1ece80cb7ee8e7c176db9f2de29f88ae2cd7>
  |   Enote view extension (private key): <3b80eca07e781df68b49c771be7686a212b7d36bd0ffd0ebb1aaf65475e3ce0c>
  |   Transaction output index: 0
  |   Unlock time: 0
--------------- ORIGIN CONTEXT ---------------
  |   Timestamp origin: 2023-08-30 14:23:51Z
  |   Block height origin: 2
  |   Tx id origin: <26622218e9c085cda0fb708b770b15eb2cf93cd68d47585cf41fdafd51e79481>
  |   Origin Status: On-chain
  |   Enote Ledge Index: 2
  |   Enote Transaction Index: 0
--------------- SPENT CONTEXT ---------------
  |   Spent status: Spent - confirmed
  |   Timestamp spent: 2023-08-30 14:23:51Z
  |   Block height spent: 5
  |   Tx id spent: <aa8b58083b35cfb34ed67eea560bc5d13f1a3d7e61fa67b8d6857f27d7b6e868>
--------------- SPENT CONTEXT - DETAILED ---------------
This enote was consumed to send funds to the following addresses: 
  |   Destination: xmra1mt7e346jrhtuyhrr2ic4n2h621yu0c2pb7ae510ni85fa12rt8qn3rq85jngy3gh8dsfjcwqcj94c6b1ab96q3idu0xgpfi1eg6jqprj44a7ae8kate8hqe51kgpcx358hekmuramdr9du3bw7p8hyu4ddn1fx0jih8s0djxggd192d3y8u0umdxi60uh36g
  |   Onetime-address: <ecb43e686de74309caebaa5a5acd69888acb021b33334c14028da2f6d838e74a>
  |   Amount commitment: <7ebb4a2b9dba2443d47ba99586da47970f313308a4f78040760fc2d04e8ff544>
  |   Amount: 10
  |   Enote ephemeral private key: f0d8788c0a1b072eff7e408954131a1b64b566a8a43d5e9ec67a8a80d62d7104
  |   --- 
  |   Type: Change
  |   Destination: xmra1mn5r34te2h18xyttiskgk0rtxhrrec7jc8pu1ykujtd84bf730wcfbn1x5jse3pp2wf16ynuedupch5nu7smxsutayx3hxi92ui9c066fhqg2cbtxyy80ib2s2wuu4y6ddakjpgcbi55r3q2394ytjd2bi54wfj91mhqc91w2ekbifr59itghy10uatgdqes
  |   Amount: 89
  |   Enote ephemeral private key: 0800000000000000000000000000000000000000000000000000000000000000
  |   --- 

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.

4) Get sent_proof of enote using the info obtained looking where it was spent. 
Making proof for enote: <ecb43e686de74309caebaa5a5acd69888acb021b33334c14028da2f6d838e74a> with amount: 10XMR and amount commitment: <7ebb4a2b9dba2443d47ba99586da47970f313308a4f78040760fc2d04e8ff544>
Proof generated: SpEnoteSentProofV1Uz1TK69bLwXPo7iVEqZGqrgPpbWBHdtW58rcUZhHbK3PfyBGUK1r7Ck4CKtNzvmWQtGaeb7u6k53gEeXhuMxBmrvNCTQYgA4fAzcYMQWARQ6G63YPEAjDerX9LkM1rycexUsgbKurej8cPAawarZmwQPoDQDU2WujBwgw1Rmew7hLkEM2g1j95Bw5gBRvJ795JS5q8VX38GdSiNE6BunzyUbxR2u9weWyK8wdwPNCTQYgA4fAzcYMQWARQ6G63YPEAjDerX9LkM1rycexUs

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)

rbrunner7 commented 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.

rbrunner7 commented 1 year ago

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.

DangerousFreedom1984 commented 1 year ago

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.

rbrunner7 commented 1 year ago

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.

DangerousFreedom1984 commented 1 year ago

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?

DangerousFreedom1984 commented 1 year ago

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.