I'm currently coding a small Monero tool just to better understand how it all works. I already implemented address-generation from scratch (thanks to luigis address test page) and the next step is to scan the whole Blockchain for transactions that have outputs associated with an address. I have found the site xmrchain which lets you do just that for single transactions, like this random one: https://xmrchain.net/tx/a8fdf7a2fb4f153980f7b5b968f54bde375b0484fd897a2f9fb3139a9fe91c46 There, you can click on "decode outputs", supply your private viewkey and address, and it shows you which outputs belong to you.

Unfortunately, all these calculations are done on the server. Could someone explain to me how I would do the same thing manually, with my private/public viewkey, address, and all the transaction data you get with the /gettransactions RPC-call?


The math behind output checking is as follows

When output is created (by the sender), it's created as:

P = H_s(rA||i)G + B,

where P is the output, H_s the hash to scalar function, r the TX private key (randomly generated by the sender), A the recipient public view key, i the output index in the transaction (|| is concatenation), G the basepoint of the elliptic curve, and B the recipient public spend key.

Thanks to elliptic curve arithmetic, rA == aR holds true, where a is the recipient private view key, and R is the TX public key. This is what is know as shared secret since only the sender and recipient know it but they never had to communicate it to one another.

When the recipient is looking for his outputs, he's doing, for each TX on the blockchain:

  1. Get the TX public key R, outputs P and output indexes i.
  2. For each index, compute P' = H_s(aR||i) + B
  3. Compare P' == P ?
  4. If equal, it's a match, continue to decode the amount.

For implementation, tha xmrchain block explorer is actually open source and you can inspect the source.

Also, there's a TX checker on Luigi's page, which is another implementation of the above.

Note that PR-2056 will change this somewhat for some cases, so it's worth looking into.


Using Luigi's page and the answer from JollyMort.

When you find out i you can decode amount from rct_signatures

  1. ecdh = rct_signatures.ecdhInfo[i]
  2. key = H_s(rA||i) see above, also it's f1 here (section FUN)
  3. ecdh = decode_rct_ecdh(ecdh, key)
  4. amount = s2d(ecdh.amount); // amount /= 1e12;

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.