<p><code>bitcoind</code> uses <code>leveldb</code> to store its utxo database, which is also referred to as chainstate. This can be found in the Bitcoin data directory under <code>chainstate/</code>.</p>
<p>UTXOs are identified by their <code>txid</code> (using their little-endian representation) led by a <code>C</code>. For versions before <code>0.15</code>, the entries are prefixed with <code>c</code> instead.</p>
<p><strong>Example</strong></p>
<p>Transaction <code>246c5a81b6ad0dfc0dbc0b2ff5bde65ee1913f75a47d409b8ff8074a27ec1000</code>
is identified in the chainstate by <code>C0010ec274a07f88f9b407da4753f91e15ee6bdf52f0bbc0dfc0dadb6815a6c24</code> or what is the same <code>430010ec274a07f88f9b407da4753f91e15ee6bdf52f0bbc0dfc0dadb6815a6c24</code> (since the hex representation of the uppercase ASCII character 'C' is 43).</p>
<p>Each entry in the leveldb contains two values, the <code>identifier</code> (already explained and used as key in the map) and the <code>value</code>.</p>
<p>The <code>value</code> of each entry (the <code>UTXO</code> itself) is encoded using the following structure (<a href="https://github.com/bitcoin/bitcoin/blob/d4a42334d447cad48fb3996cad0fd5c945b75571/src/coins.h#L21L69" rel="nofollow noreferrer">check this comment from the source code for more detail</a>):</p>
<blockquote>
<ul>
<li>Serialized format
<ul>
<li>VARINT(nVersion)</li>
<li>VARINT(nCode)</li>
<li>unspentness bitvector, for vout<code>[2]</code> and further; least significant byte first</li>
<li>the non-spent CTxOuts (via CTxOutCompressor)</li>
<li>VARINT(nHeight)      * The nCode value consists of:
<ul>
<li>bit 1: IsCoinBase()</li>
<li>bit 2: vout<code>[0]</code> is not spent</li>
<li>bit 4: vout<code>[1]</code> is not spent</li>
<li>The higher bits encode N, the number of non-zero bytes in the following bitvector.</li>
<li>In case both bit 2 and bit 4 are unset, they encode N-1, as there must be at least one non-spent output).</li>
</ul>
</li>
</ul>
</li>
</ul>
</blockquote>
<p>Notice that, since the database used to trigger anti-virus software(<a href="https://github.com/bitcoin/bitcoin/issues/6613" rel="nofollow noreferrer">2</a>, <a href="https://bitcoin.stackexchange.com/questions/50901/what-is-an-obfuscation-key">3</a>), an obfuscation key was introduced so the data can be masked. The key is a 64-bit value identified by <code>0e00obfuscation_key</code> that should be XORed with each data value from the database. Given the entries in the database may be longer than the key, the key is concatenated with itself until it reaches the expected length to de-obfuscate a value.</p>
<p><strong>Example</strong></p>
<p>Let's use the following obfuscation key and entry in the database:</p>
<pre><code>// Obfuscation key
o_k = &quot;27c78118b7316105&quot;

// Entry
{
    &quot;key&quot;: &quot;43000002f414665fb03389dd19776732bf90883bcb399d23323747596e98dd1801&quot;,
    &quot;value&quot;: &quot;26c326d7353661dc7005d274976f458691f24f0f05d141335f4ad5927e41&quot;
}
</code></pre>
<p>As you can see, <code>value</code> does not follow the above-introduced format, since it is obfuscated. <code>value</code> is 60 characters long, so we need to extend our obfuscation key to match its size:</p>
<pre><code>27c78118b731610527c78118b731610527c78118b731610527c78118b731
</code></pre>
<p>Now, if we perform the XOR between the value and the key, we obtain:</p>
<pre><code>    &gt; 26c326d7353661dc7005d274976f458691f24f0f05d141335f4ad5927e41 XOR 27c78118b731610527c78118b731610527c78118b731610527c78118b731  

    0104a7cf820700d957c2536c205e2483b635ce17b2e02036788d548ac970
</code></pre>
<p>That matches the previously stated format, and it's indeed the <code>UTXO</code> identified by <code>43000002f414665fb03389dd19776732bf90883bcb399d23323747596e98dd1801</code></p>

CC BY-SA 3.0
2017-03-17T21:46:01.330Z
Thanks. Finally I figured out that Bitcoin uses LevelDB to save the transaction index, which uses the transaction hash as key and file position as value. The actual binary transaction data are stored in the block files.
Yangrui
CC BY-SA 3.0
2017-03-27T18:58:23.513Z
@Yangrui That used to be how Bitcoin Core worked up to version 0.7.x. As of 0.8.0, there is no transaction index at all anymore, and only a database with a _copy_ of the unspent transaction _outputs_. This means no disk lookup for the actual transaction is needed anymore, and we're able to support pruning (deleting the actual block data from disk after validation).
Pieter Wuille
CC BY-SA 3.0
2017-03-28T20:03:27.630Z
Thanks Pieter. So if a transaction is spent, is it just removed from the UTXO db right away?
Yangrui
CC BY-SA 3.0
2018-04-10T01:09:13.177Z
For future travelers like me, the key for chainstate is not an ascii `0e00obfuscation_key`, but a hex `\x0e\x00obfuscate_key` (as of v0.15.0.1)
num1
CC BY-SA 3.0
2018-04-10T02:04:05.120Z
`\x0e` and `\x00` indicate `0e` and `00` hex respectively.
sr_gi
CC BY-SA 4.0
2019-07-18T11:01:14.047Z
Also, the hex representation of "c" is 0x43, or 67 decimal (not 63 as written above). Just some info if you got confused like me.
dimsumcode
CC BY-SA 4.0
2019-07-18T13:30:52.337Z
Nope, C is 0x43, c is 0x63
sr_gi
CC BY-SA 4.0
2019-07-23T10:30:19.637Z
You're correct. But I think I was trying to say that the key bytes in the UTXO for a "coin" start with 0x43 (not 0x63). I think they start with a 'C' and not a 'c'.  Am I mistaken?
dimsumcode
CC BY-SA 4.0
2019-07-31T19:53:43.323Z
It is now, but it was not when the answer was posted. The UTXO set format was changed in Bitcoin Core 0.15. For 0.15+ (inclusive) it is 'C', for 0.15- it is 'c'.
sr_gi
CC BY-SA 4.0
2019-06-14T02:02:06.447Z
Can you please explain how you managed to xor two 30-byte numbers and get a 28-byte number, that doesn't appear to be their bitwise xor in any way I can figure out?
Nate Eldredge
CC BY-SA 4.0
2019-06-14T19:13:51.813Z
@NateEldredge I can't recall how I got that value, but you're completely right. The actual deobfuscated value should be 0104a7cf820700d957c2536c205e2483b635ce17b2e02036788d548ac970
sr_gi
CC BY-SA 4.0
2017-03-16T10:01:34.387Z
2024-01-10T22:08:58.387Z
2024-01-10T22:08:58.387Z
sr_gi
<p>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?</p>

CC BY-SA 3.0
2017-02-17T11:13:18.433Z
have you had a look at this: http://bitcoin.stackexchange.com/questions/28168/what-are-the-keys-used-in-the-blockchain-leveldb-ie-what-are-the-keyvalue-pair?rq=1
rny
CC BY-SA 3.0
2017-02-18T21:18:55.413Z
I looked it but it only stated the schema of a transaction. So does Bitcoin client remove a transaction from LevelDB once it's spent?
Yangrui
<blockchain><leveldb>
How does Bitcoin read from/write to LevelDB
Yangrui
# How does Bitcoin read from/write to LevelDB

(Asked by: username_0 on 2017-02-14)

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?

**Tags:** blockchain, leveldb

> **Comments:**
> **username_1**: have you had a look at this: http://bitcoin.stackexchange.com/questions/28168/what-are-the-keys-used-in-the-blockchain-leveldb-ie-what-are-the-keyvalue-pair?rq=1  
> **username_0**: I looked it but it only stated the schema of a transaction. So does Bitcoin client remove a transaction from LevelDB once it's spent?  

---

## 1 answers

### Answer by username_2 on 2017-03-16. Score: 23 | Accepted answer

bitcoind uses leveldb to store its utxo database, which is also referred to as chainstate. This can be found in the Bitcoin data directory under chainstate/.
UTXOs are identified by their txid (using their little-endian representation) led by a C. For versions before 0.15, the entries are prefixed with c instead.
Example
Transaction 246c5a81b6ad0dfc0dbc0b2ff5bde65ee1913f75a47d409b8ff8074a27ec1000
is identified in the chainstate by C0010ec274a07f88f9b407da4753f91e15ee6bdf52f0bbc0dfc0dadb6815a6c24 or what is the same 430010ec274a07f88f9b407da4753f91e15ee6bdf52f0bbc0dfc0dadb6815a6c24 (since the hex representation of the uppercase ASCII character 'C' is 43).
Each entry in the leveldb contains two values, the identifier (already explained and used as key in the map) and the value.
The value of each entry (the UTXO itself) is encoded using the following structure (check this comment from the source code for more detail):


Serialized format

VARINT(nVersion)
VARINT(nCode)
unspentness bitvector, for vout[2] and further; least significant byte first
the non-spent CTxOuts (via CTxOutCompressor)
VARINT(nHeight)      * The nCode value consists of:

bit 1: IsCoinBase()
bit 2: vout[0] is not spent
bit 4: vout[1] 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).






Notice that, since the database used to trigger anti-virus software(2, 3), an obfuscation key was introduced so the data can be masked. The key is a 64-bit value identified by 0e00obfuscation_key that should be XORed with each data value from the database. Given the entries in the database may be longer than the key, the key is concatenated with itself until it reaches the expected length to de-obfuscate a value.
Example
Let's use the following obfuscation key and entry in the database:
// Obfuscation key
o_k = "27c78118b7316105"

// Entry
{
    "key": "43000002f414665fb03389dd19776732bf90883bcb399d23323747596e98dd1801",
    "value": "26c326d7353661dc7005d274976f458691f24f0f05d141335f4ad5927e41"
}

As you can see, value does not follow the above-introduced format, since it is obfuscated. value is 60 characters long, so we need to extend our obfuscation key to match its size:
27c78118b731610527c78118b731610527c78118b731610527c78118b731

Now, if we perform the XOR between the value and the key, we obtain:
    > 26c326d7353661dc7005d274976f458691f24f0f05d141335f4ad5927e41 XOR 27c78118b731610527c78118b731610527c78118b731610527c78118b731  

    0104a7cf820700d957c2536c205e2483b635ce17b2e02036788d548ac970

That matches the previously stated format, and it's indeed the UTXO identified by 43000002f414665fb03389dd19776732bf90883bcb399d23323747596e98dd1801

> **Comments:**
> **username_0**: Thanks. Finally I figured out that Bitcoin uses LevelDB to save the transaction index, which uses the transaction hash as key and file position as value. The actual binary transaction data are stored in the block files.  
> **username_3**: @username_0 That used to be how Bitcoin Core worked up to version 0.7.x. As of 0.8.0, there is no transaction index at all anymore, and only a database with a _copy_ of the unspent transaction _outputs_. This means no disk lookup for the actual transaction is needed anymore, and we're able to support pruning (deleting the actual block data from disk after validation).  
> **username_0**: Thanks Pieter. So if a transaction is spent, is it just removed from the UTXO db right away?  
> **username_4**: For future travelers like me, the key for chainstate is not an ascii `0e00obfuscation_key`, but a hex `\x0e\x00obfuscate_key` (as of v0.15.0.1)  
> **username_2**: `\x0e` and `\x00` indicate `0e` and `00` hex respectively.  
> **username_6**: Can you please explain how you managed to xor two 30-byte numbers and get a 28-byte number, that doesn't appear to be their bitwise xor in any way I can figure out?  
> **username_2**: @NateEldredge I can't recall how I got that value, but you're completely right. The actual deobfuscated value should be 0104a7cf820700d957c2536c205e2483b635ce17b2e02036788d548ac970  
> **username_5**: Also, the hex representation of "c" is 0x43, or 67 decimal (not 63 as written above). Just some info if you got confused like me.  
> **username_2**: Nope, C is 0x43, c is 0x63  
> **username_5**: You're correct. But I think I was trying to say that the key bytes in the UTXO for a "coin" start with 0x43 (not 0x63). I think they start with a 'C' and not a 'c'.  Am I mistaken?  
> **username_2**: It is now, but it was not when the answer was posted. The UTXO set format was changed in Bitcoin Core 0.15. For 0.15+ (inclusive) it is 'C', for 0.15- it is 'c'.  

---

