3

During blockchain scanning I need to do:

P − Hs(aR)G

with every output in order to determie whether it is mine, or not.

Where in tx_json are P and R stored?

jtgrassie
  • 19,111
  • 4
  • 14
  • 51
ivanahepjuk
  • 149
  • 5

1 Answers1

3

The full math you have to do is:

D = P - Hs(8aR || i)G, where i is a varint representing the index of the output. You then check whether D matches your main public spend key or any of your subaddress public spend keys. if it does, the output is destined for you.

The output public key P is in the json as vout.target.key. The transaction public key R is not separately listed, so you'll need to parse the extra field in the json and locate the txpubkey subfield.

The txextra field format is documented here: https://cryptonote.org/cns/cns005.txt

It's the "Tx public key" field mentioned in that document that you are interested in.

Also note that to support transactions with multiple subaddress recipients, there is also a new TX_EXTRA_TAG_ADDITIONAL_PUBKEYS field. If this field is present, then you'll need to check each output against the corresponding additional txpubkey listed in that field.

knaccc
  • 8,468
  • 16
  • 22
  • @jtgrassie Ah oops thanks, missed that P is in there. Why though would the txpubkey R be listed as "tx_hash"? – knaccc Mar 21 '19 at 12:05
  • I would like to write python script, which is going through blockchain and for each output it sends P and R to hardware wallet, where I am determining if output is mine or not. So, I can get P from tx_json, but what is the best method for getting R ? How the tx_blob is structured? – ivanahepjuk Mar 21 '19 at 12:07
  • @jtgrassie I'm not sure why you think that. I've messaged you on IRC so you can sanity check me. – knaccc Mar 21 '19 at 12:20
  • So, in each block, which have transactions, there are tx_hashes(R) and destination_keys(P). Each transaction has one R and could have one or more P's. I can query those numbers by searching for tx_hashes (R) or "VOUT" fields (P). I can get those informations from jsons, but also from binary form. Is there some documentation about binary structure? This would allow me to query the whole block and parse those P's and R's form binary form..? And thank you of course for your answers! – ivanahepjuk Mar 21 '19 at 13:26
  • @ivanahepjuk the txhash, also known as the txid is a keccak hash that is used to uniquely identify the transaction. it is not the same as the tx public key R, which is an EC point and not a hash. A transaction can have one or more Rs too, if the TX_EXTRA_TAG_ADDITIONAL_PUBKEYS field is present in txextra. The structure has changed recently, so the C source code is really the only definitive source. I have partially documented some elements of a tx here: https://monero.stackexchange.com/questions/5664/size-requirements-for-different-pieces-of-a-monero-transaction/5665#5665 – knaccc Mar 21 '19 at 14:02
  • 3
    Here's an example getting the tx pub key R out of the extra field. This is using the extra from this tx. – jtgrassie Mar 21 '19 at 16:16
  • Thank you all for comments. I checked proposed links and also cryptonote_basic/tx_extra.h, please help me a bit, I am close to understanding:) So, in tx_extra field there could be two kind of fields: (tag)(value) or (tag)(length)(value). Which tags have value and which doesn't? I think I must parse all fields, even though I need only tx_pub_key. Otherwise any 0x01 could be read as a tag. – ivanahepjuk Mar 24 '19 at 18:38
  • As per my working example, only tags 0x00 and 0x01 omit the length specifier (this is because they don't need it). All other tags are (tag)(length)(value). – jtgrassie Mar 25 '19 at 00:24
  • @jtgrassie the example seems to break for https://monerohash.com/explorer/search?value=1167e3621e4ae4de170c932f48471c8fc2cd9b8f9e312da6f2ca70225bf0f425 can it be that the size is actually varint, but the example assumes the size is 1 byte? – redacted Apr 08 '19 at 15:34
  • 1
    Size is a varint - the example is just a quick demo (I didn't bother adding varint decoding). – jtgrassie Apr 08 '19 at 22:25