The documentation on transaction's 'extra' field is spread out and not completely clear. This is the original cryptonote description. Here is a different question that reveals some more of the concepts.
I would like to devote this question to listing all information about the 'extra' field, and its standard interpretation and implementation. In other words, how it is stored in transaction data, and the rules surrounding common tags. Qualifying answers may verify, correct, or add to the following information (note: the answer should include all good information from below; once answered, I will edit the question down to just the question).
- The field's location within transaction data is defined by the transaction's structure. Currently (protocol v12) the transaction version is v2, and 'extra' lives between 'vout' (outputs) and 'rct_signatures' (ringct data).
- The field is interpreted as an array of bytes with little endian order (indexed 0, 1, 2).
- It is composed of information sections, which each begin with a 'tag' byte. A tag defines how the bytes after it are interpreted. Wherever relevant, the leftmost byte (lower index) is considered most significant.
- The field's core implementation can be found here: src/cryptonote_basic/tx_extra.h
- Wallets should understand the rules for all known tags, in order to correctly parse the ones they care about.
- Bytes to be interpreted as 'length' or 'amount' are considered varints (section 1.2).
Basic tags (in hexidecimal format):
0x00
: padding, ignore and move to the next byte; there can be up to 255 of these0x01
: transaction public key, the next 32 bytes is that key (an elliptic curve point) in byte format (it can be converted to a group element); one of these per transaction0x02
: extra nonce, the next byte is its length (may be up to 255); this is like an extra field within the extra field, and the utility of that is unclear to me; the byte after its length is an 'extra nonce tag' interpreted according to special rules (see below); one of these per transaction0x03
: merge mining tag, how does this one work?0x04
: additional public keys, the next byte is the number of additional keys (elliptic curve points in bytes, 32 bytes each), and the byte after that is the most significant byte of the first additional key; one of these sets per transaction, and there should be either 1 or #outputs total amount of transaction public keys per transaction (standard, or at-least-one-ouput-is-a-subaddress cases)0xDE
: mysterious minergate tag, the next byte is its length
Special extra nonce tags (tags within the extra nonce section):
0x00
: payment ID, the next 32 bytes are a payment ID in clear text; one of these per transaction (deprecated as of core implementation v0.15, which means it will be ignored/skipped over by the main wallet)0x01
: encrypted payment ID, the next 8 bytes are an encrypted payment ID; one of these per transaction (the core implementation will add a dummy encrypted payment ID to transactions where one isn't specified, to improve transaction indistinguishability)
An example (transaction hash 3033917f822512e7b9dab4eb3477cd9ec61052224723623c1353f4d160e8dd68
):
"extra":[1,240,78,249,111,229,39,232,253,137,61,146,133,192,190,13,58,96,239,78,21,116,133,204,111,251,40,170,155,126,208,23,244,2,9,1,253,234,238,74,23,163,141,203] = [1 (transaction public key),...32 bytes...,2 (extra nonce),9 (length of extra nonce),1 (encrypted payment ID within extra nonce),...8 bytes...]
Open question(s):
If e.g. there are two transaction public keys with tag 0x01
, how will the core implementation interpret this? Will it ignore the first, or second one, or try to use both of them? What about other tag multiples?