<p>This answer is a little stale. But here it is anyway.</p>
<p>You need to watch for the endianness of the bytes. How we look at the block id (block header hash) is bigendian, most significant bit first, and how bitcoin-core manages everything behind the scenes is littleendian, least significant bit first.</p>
<p>Here is a simple script to access the entire leveldb block index.</p>
<pre><code>import re
from plyvel import DB

# Note for POSIX users, typically we have to escape spaces, 
# e.g. &quot;Application\ Support&quot;. However this is not needed here so you 
# can write &quot;Application Support&quot; instead.
BITCOIN_DATADIR: str =&quot;/absolute/path/to/your/bitcoin/datadir/&quot;
db = DB(BITCOIN_DATADIR + &quot;blocks/index&quot;)
keys = list(db.iterator(include_value=False))
regtest = re.compile(br&quot;^b&quot;)
block_id_keys = list(filter(regtest.search, keys))
</code></pre>
<p>We can access the data structure and see this:</p>
<pre><code>&gt;&gt;&gt; bytes.hex(block_id_keys[-1][::-1][:-1])
'0000000000429f3501d60512df277b97f539becd18a7541b433e5110b2feffff'
</code></pre>
<p><a href="https://blockstream.info/block/0000000000429f3501d60512df277b97f539becd18a7541b433e5110b2feffff" rel="nofollow noreferrer">https://blockstream.info/block/0000000000429f3501d60512df277b97f539becd18a7541b433e5110b2feffff</a></p>
<p>Going through the <code>[-1][::-1][:-1]</code>, the <code>[-1]</code> is the last item in the list, the <code>[::-1]</code> flips the byte order from littleendian to bigendian, and the <code>[:-1]</code> drops the <code>b&quot;b&quot;</code>.</p>
<p>To see the raw key, we can see the entire structure:</p>
<pre><code>&gt;&gt;&gt; block_id_keys[-1]
b&quot;b\xff\xff\xfe\xb2\x10Q&gt;C\x1bT\xa7\x18\xcd\xbe9\xf5\x97{'\xdf\x12\x05\xd6\x015\x9fB\x00\x00\x00\x00\x00&quot;
</code></pre>
<p>Note the key begins with <code>b&quot;b&quot;</code>.</p>
<p>To get the leveldb key from a bigendian hex blockid, you could do the following:</p>
<pre><code>&gt;&gt;&gt; hex_data = &quot;000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f&quot;
&gt;&gt;&gt; test_key = b&quot;b&quot; + bytes.fromhex(hex_data)[::-1]
&gt;&gt;&gt; db.get(test_key)
b'\x8b\x99@\x00\x0b\x01\x00\x08\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00;\xa3\xed\xfdz{\x12\xb2z\xc7,&gt;gv\x8fa\x7f\xc8\x1b\xc3\x88\x8aQ2:\x9f\xb8\xaaK\x1e^J)\xab_I\xff\xff\x00\x1d\x1d\xac+|'
</code></pre>
<p>Also see <a href="https://bitcoin.stackexchange.com/a/29418/124452">https://bitcoin.stackexchange.com/a/29418/124452</a></p>

CC BY-SA 4.0
2022-01-18T17:25:57.360Z
2022-01-18T17:25:57.360Z
Cal Abel
<p>The leveldb databases are serialized for optimization and do not work well with attempting to manually parse the data. You can more easily get details on a specific blockhash using the built-in JSON-RPC API and use the <code>getblock</code> call.</p>

CC BY-SA 4.0
2018-12-04T10:40:57.557Z
Thank you for your reply, and I will do so. However, what I am trying to do is to reference orphans blocks. I'm not sure I would be able to see these orphans blocks through the API calls.. I mean if I know block O is an orphan block, I will be able to getblock O. But if I am looking for orphan blocks, not knowing their hash, I will be probably face some problems Iterating over all the keys of the leveldb would allow me to distinguish orphan block and "main" blocks.
Elerir
CC BY-SA 4.0
2018-12-09T11:16:37.377Z
I know i shouldn't answer to my own question but I found away to do so :
I'm getting all the keys using db.iterator()
And then using binascii.hexlify / unhexlify I've solved my problems. My workspace was a bit messy and that's why I didn't even realize that simple trick works (I'm sure I had tried)
Elerir
CC BY-SA 4.0
2018-12-04T03:21:45.047Z
2018-12-04T03:21:45.047Z
m1xolyd1an
<p>I am facing a stupid problem. I am trying to read bitcoin/blocks/index leveldb using plyvel. I've set up a regtest and i know there is a block with the hash :</p>

<pre><code>27ce8199dee22f96e4f392dec29ef207fcd8a3c9e43b7d58cb40a5ba01af674b
</code></pre>

<p>I am trying to query it using plyvel.</p>

<p>Note that I already read the topics :</p>

<p><a href="https://bitcoin.stackexchange.com/questions/51387/how-does-bitcoin-read-from-write-to-leveldb">How does Bitcoin read from/write to LevelDB</a></p>

<p><a href="https://bitcoin.stackexchange.com/questions/28168/what-are-the-keys-used-in-the-blockchain-leveldb-ie-what-are-the-keyvalue-pair">What are the keys used in the blockchain levelDB (ie what are the key:value pairs)?</a></p>

<p><a href="https://en.bitcoin.it/wiki/Protocol_documentation" rel="nofollow noreferrer">https://en.bitcoin.it/wiki/Protocol_documentation</a></p>

<p>Then, I know I have to swap the endianness so it becomes :</p>

<pre><code>MYVAR = "4b67af01baa540cb587d3be4c9a3d8fc07f29ec2de92f3e4962fe2de9981ce27"
</code></pre>

<p>Thus, I should query something like :</p>

<pre><code>b + (byte) MYVAR 
</code></pre>

<p>However I do not get how. I guess I missunderstand something in encoding. I tried :</p>

<pre><code>db.get(b'b4b67af01baa540cb587d3be4c9a3d8fc07f29ec2de92f3e4962fe2de9981ce27')
db.get(b'b'+b'4b67af01baa540cb587d3be4c9a3d8fc07f29ec2de92f3e4962fe2de9981ce27')
</code></pre>

<p>..</p>

<p>Then, I opened the bitcoin/blocks/index leveldb using a gui explorer and I noticed the key for this block is :</p>

<pre><code>\x62\x4b\x67\xaf\x01\xba\xa5\x40\xcb\x58\x7d\x3b\xe4\xc9\xa3\xd8\xfc\x07\xf2\x9e\xc2\xde\x92\xf3\xe4\x96\x2f\xe2\xde\x99\x81\xce\x27
</code></pre>

<p>which is \x62 corresponding to the "b" + the hash with \x (escaping caracter ? I know here is my misunderstanding on hex encoding)</p>

<p>and obviously </p>

<pre><code>db.get(b'\x62\x4b\x67\xaf\x01\xba\xa5\x40\xcb\x58\x7d\x3b\xe4\xc9\xa3\xd8\xfc\x07\xf2\x9e\xc2\xde\x92\xf3\xe4\x96\x2f\xe2\xde\x99\x81\xce\x27')
</code></pre>

<p>perfectly works</p>

<p>I also tried these methods :</p>

<p><a href="https://stackoverflow.com/questions/5649407/hexadecimal-string-to-byte-array-in-python">https://stackoverflow.com/questions/5649407/hexadecimal-string-to-byte-array-in-python</a></p>

<p>No one of them works and I really don't get why :</p>

<pre><code>bytes.fromhex(hash)
bytearray.fromhex(hash)
</code></pre>

<p>Thank you in advance</p>

<python><leveldb>
Python - Querying bitcoin's block header using leveldb
Elerir
# Python - Querying bitcoin's block header using leveldb

(Asked by: username_0 on 2018-12-03)

I am facing a stupid problem. I am trying to read bitcoin/blocks/index leveldb using plyvel. I've set up a regtest and i know there is a block with the hash :

```
27ce8199dee22f96e4f392dec29ef207fcd8a3c9e43b7d58cb40a5ba01af674b

```

I am trying to query it using plyvel.

Note that I already read the topics :

[How does Bitcoin read from/write to LevelDB](https://bitcoin.stackexchange.com/questions/51387/how-does-bitcoin-read-from-write-to-leveldb)

[What are the keys used in the blockchain levelDB (ie what are the key:value pairs)?](https://bitcoin.stackexchange.com/questions/28168/what-are-the-keys-used-in-the-blockchain-leveldb-ie-what-are-the-keyvalue-pair)

<https://en.bitcoin.it/wiki/Protocol_documentation>

Then, I know I have to swap the endianness so it becomes :

```
MYVAR = "4b67af01baa540cb587d3be4c9a3d8fc07f29ec2de92f3e4962fe2de9981ce27"

```

Thus, I should query something like :

```
b + (byte) MYVAR 

```

However I do not get how. I guess I missunderstand something in encoding. I tried :

```
db.get(b'b4b67af01baa540cb587d3be4c9a3d8fc07f29ec2de92f3e4962fe2de9981ce27')
db.get(b'b'+b'4b67af01baa540cb587d3be4c9a3d8fc07f29ec2de92f3e4962fe2de9981ce27')

```

..

Then, I opened the bitcoin/blocks/index leveldb using a gui explorer and I noticed the key for this block is :

```
\x62\x4b\x67\xaf\x01\xba\xa5\x40\xcb\x58\x7d\x3b\xe4\xc9\xa3\xd8\xfc\x07\xf2\x9e\xc2\xde\x92\xf3\xe4\x96\x2f\xe2\xde\x99\x81\xce\x27

```

which is \x62 corresponding to the "b" + the hash with \x (escaping caracter ? I know here is my misunderstanding on hex encoding)

and obviously

```
db.get(b'\x62\x4b\x67\xaf\x01\xba\xa5\x40\xcb\x58\x7d\x3b\xe4\xc9\xa3\xd8\xfc\x07\xf2\x9e\xc2\xde\x92\xf3\xe4\x96\x2f\xe2\xde\x99\x81\xce\x27')

```

perfectly works

I also tried these methods :

<https://stackoverflow.com/questions/5649407/hexadecimal-string-to-byte-array-in-python>

No one of them works and I really don't get why :

```
bytes.fromhex(hash)
bytearray.fromhex(hash)

```

Thank you in advance

**Tags:** python, leveldb


---

## 2 answers

### Answer by username_1 on 2022-01-18. Score: 1

This answer is a little stale. But here it is anyway.

You need to watch for the endianness of the bytes. How we look at the block id (block header hash) is bigendian, most significant bit first, and how bitcoin-core manages everything behind the scenes is littleendian, least significant bit first.

Here is a simple script to access the entire leveldb block index.

```
import re
from plyvel import DB

# Note for POSIX users, typically we have to escape spaces, 
# e.g. "Application\ Support". However this is not needed here so you 
# can write "Application Support" instead.
BITCOIN_DATADIR: str ="/absolute/path/to/your/bitcoin/datadir/"
db = DB(BITCOIN_DATADIR + "blocks/index")
keys = list(db.iterator(include_value=False))
regtest = re.compile(br"^b")
block_id_keys = list(filter(regtest.search, keys))

```

We can access the data structure and see this:

```
>>> bytes.hex(block_id_keys[-1][::-1][:-1])
'0000000000429f3501d60512df277b97f539becd18a7541b433e5110b2feffff'

```

<https://blockstream.info/block/0000000000429f3501d60512df277b97f539becd18a7541b433e5110b2feffff>

Going through the `[-1][::-1][:-1]`, the `[-1]` is the last item in the list, the `[::-1]` flips the byte order from littleendian to bigendian, and the `[:-1]` drops the `b"b"`.

To see the raw key, we can see the entire structure:

```
>>> block_id_keys[-1]
b"b\xff\xff\xfe\xb2\x10Q>C\x1bT\xa7\x18\xcd\xbe9\xf5\x97{'\xdf\x12\x05\xd6\x015\x9fB\x00\x00\x00\x00\x00"

```

Note the key begins with `b"b"`.

To get the leveldb key from a bigendian hex blockid, you could do the following:

```
>>> hex_data = "000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f"
>>> test_key = b"b" + bytes.fromhex(hex_data)[::-1]
>>> db.get(test_key)
b'\x8b\x99@\x00\x0b\x01\x00\x08\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00;\xa3\xed\xfdz{\x12\xb2z\xc7,>gv\x8fa\x7f\xc8\x1b\xc3\x88\x8aQ2:\x9f\xb8\xaaK\x1e^J)\xab_I\xff\xff\x00\x1d\x1d\xac+|'

```

Also see <https://bitcoin.stackexchange.com/a/29418/124452>


---

### Answer by username_2 on 2018-12-04. Score: 0

The leveldb databases are serialized for optimization and do not work well with attempting to manually parse the data. You can more easily get details on a specific blockhash using the built-in JSON-RPC API and use the `getblock` call.

> **Comments:**
> **username_0**: Thank you for your reply, and I will do so. However, what I am trying to do is to reference orphans blocks. I'm not sure I would be able to see these orphans blocks through the API calls.. I mean if I know block O is an orphan block, I will be able to getblock O. But if I am looking for orphan blocks, not knowing their hash, I will be probably face some problems Iterating over all the keys of the leveldb would allow me to distinguish orphan block and "main" blocks.  
> **username_0**: I know i shouldn't answer to my own question but I found away to do so : I'm getting all the keys using db.iterator() And then using binascii.hexlify / unhexlify I've solved my problems. My workspace was a bit messy and that's why I didn't even realize that simple trick works (I'm sure I had tried)  

---

