I know that Bitcoin Core uses LevelDB since 0.8 version. However, I couldn't find detailed explanation about how Bitcoin stores and retrieves from LevelDB. E.g. If B transaction uses an output from previous transaction A as input, how does Bitcoin lookup this transaction and see if it's spent? After transaction B is spent, how does this transaction get updated?
In the specific example you asked, it does so by querying the LevelDB located in
./bitcoin/chainstate (there is where the
UTXO set is stored).
UTXOs are identified by its
txid (Little Endian representation) leaded by a
is identified in the LevelDB by:
or what is the same:
since the hex representation of 'c' is 63. Notice that when you query the database you should not do it using the string representation of the value, but the byte array one.
Each entry in the LevelDB contains two values, the
identifier (explained avobe and used to query the data), and the
value of each entry (the
UTXO) is encoded in the LevelDB following the structure that follows (extracted from this comment from the source code):
- Serialized format
- unspentness bitvector, for vout
and further; least significant byte first
- the non-spent CTxOuts (via CTxOutCompressor)
- The nCode value consists of:
- bit 1: IsCoinBase()
- bit 2: vout
is not spent
- bit 4: vout
is not spent
- The higher bits encode N, the number of non-zero bytes in the following bitvector.
- In case both bit 2 and bit 4 are unset, they encode N-1, as there must be at least one non-spent output).
You can find a better formated explanation and examples in the source code from the provided link.
Notice that, since chainstate database used to trigger anti-virus software, as you can check in this issue and in this question, the first lines of the chainstate contains the
obfuscation key, a 64-bit value identified by
0e00obfuscation_key that should be XORed with each data value from the database. To do so, the key is concatenated with itself until it reaches the length of the obfuscated value.
o_k = '27c78118b7316105' be our obfuscation key, and
be one entry from the database. As you can see,
value does not follow the above introduced format, since it is obfuscated.
value is 60 characters long, so if we extend the obsfuscation key since it reaches the same length, we get:
Now, if we perform the XOR between the value and the key:
26c326d7353661dc7005d274976f458691f24f0f05d141335f4ad5927e41 XOR 27c78118b731610527c78118b731610527c78118b731610527c78118b731
That matches with the previous stated format, and it's indeed the
UTXO value identified by