I'm trying to understand the data structure in monerod and create a simple workflow for a transaction's life cycle.

It doesn't look like this has been done post-RingCT activation, and I see a lot of confusion in the community (myself included). I will create a public post once I fully understand this, I will attempt to further simplify it, and share it with the community.

Here's what I have so far, I would appreciate comments or corrections.

1) The transaction starts with the Monerod aggregating the input(s) that a sender needs for this transaction.

2) Once that's determined, the wallet sources decoys TXOs (and their respective key images) by looking at past transactions in the chain.

3) A Borromean ring signature is generated by aggregating the signature of the real TXO and its key image with all mixins.

4) A Pedersen commitment scheme encodes the value of all TXOs through homomorphic addition. A separate data field is created with a range proof to confirm that the product > 0.

5) The sender then generates a Stealth Address by wrapping the receiver's address a la quasi-CryptoNote, plus an indexer: P = Hs(r, A, index#)G + B

6) The sender's wallet looks for decoy outputs (with their key offsets) and output values are not encoded through a Pedersen commit. I'm assuming two things here that are not clear:

  • 6.1) Output values are not encoded though the commitment scheme (?)
  • 6.2) Key images are separate data points that (put simply) represent a transaction's pubKey. The intended receiver has a private key that allows an output to be spent. Each output has its own key image, which is not included in the TXO list (?) I'm also assuming TXOs can be separated from key images.

7) The transaction is created & broadcasted to the network.

8) The receiver's wallet will use the private view key to see which images he can decode. Every time the chain is scanned, a list of key images appears. Some of them are unspendable (either because they have already been spent OR they have been used as decoys), but some of them are spendable. The receiver uses a private spend key to verify this by attempting to sign the image.

9) One of the key images with the intended amount can be singed and the receiver can confirm that he has received the funds.

I also plan to create a diagram showing this workflow so any help would be greatly appreciated.


I'll do my best to answer:

1) Actually it starts with the wallet, not daemon, aggregating the inputs for spending.

2) The wallet asks the daemon for the mixins (decoys)

6) All values are encrypted as Pedersen commitments

6.1) They are also Pedersen commitments

6.2) Key Images are actually on each txin

8) Receivers wallet (receiver) checks each txout stealth address to see if it belongs to them. The wallet does Hs(aR)G + B with a being the receivers private view key, R being the tx pubic key, G the Ed25519 base point and B being the receivers public spend key. If the output stealth address matches Hs(aR)G + B, the wallet then checks to ensure it's not already spent by computing it's key image and checking the blockchain. This is the purpose of key images, to check whether an output is already spent (double spend protection).

  • Thank you for this. One thing that is still a little unclear is how key images are computed from the stealth address. I think there's some confusion about the difference between a stealth address, a tx public key and a key image. My original understanding is that the stealth address, given its use of ECDH, was the key image, is this incorrect? – Raz Lemniscate Oct 6 '18 at 20:32
  • No the stealth address is not the key image. The key image is derived from the tx public key(s) with the outputs to spend and the senders private keys. I strongly suggest reading a great article: steemit.com/monero/@luigi1111/… – jtgrassie Oct 6 '18 at 20:53
  • Since values are masked, could you explain how the receiver knows how much he has received? – WeCanBeFriends Apr 20 at 13:16
  • The amount and mask are encrypted via ecdh. The receiver derives the tx shared secret and then using their private view key can decode the blinding factor and amount. – jtgrassie Apr 20 at 15:40
  • Do you have the specific equations used for this? Or a link to the code? – WeCanBeFriends Apr 20 at 16:38

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.