Skip to content

Commit a7451fd

Browse files
committed
doc: add python-bitcoinlib example
Add an example on using python-bitcoinlib, to help inspecting the bytes objects returned by the bitcoinkernel API.
1 parent c26d23d commit a7451fd

File tree

3 files changed

+64
-1
lines changed

3 files changed

+64
-1
lines changed

README.md

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
[![versions](https://img.shields.io/pypi/pyversions/py-bitcoinkernel.svg)](https://github.com/stickies-v/py-bitcoinkernel)
44
[![license](https://img.shields.io/github/license/stickies-v/py-bitcoinkernel.svg)](https://github.com/stickies-v/py-bitcoinkernel/blob/main/LICENSE)
55

6-
`py-bitcoinkernel` is a Python wrapper around
6+
`py-bitcoinkernel` (or `pbk` in short) is a Python wrapper around
77
[`libbitcoinkernel`](https://github.com/bitcoin/bitcoin/pull/30595)
88
providing a clean, Pythonic interface while handling the low-level
99
ctypes bindings and memory management.
@@ -138,6 +138,10 @@ with open("raw_blocks.txt", "r") as file:
138138

139139
### Common operations
140140

141+
> [!NOTE]
142+
> See [doc/examples](./doc/examples/) for more common usage examples of
143+
> `pbk`
144+
141145
ChainstateManager exposes a range of functionality to interact with the
142146
chainstate. For example, to print the current block tip:
143147

@@ -175,6 +179,10 @@ with open(filename, "wb") as f:
175179
want to use `py-bitcoinkernel` with an existing chainstate, you'll
176180
need to either first shut down `Bitcoin Core`, or clone the `blocks/`
177181
and `chainstate/` directories to a new location.
182+
- The `bitcoinkernel` API currently does not offer granular inspection
183+
of most kernel objects. See [doc/examples](./doc/examples/) for ideas
184+
on using third-party (de)serialization libraries to convert kernel
185+
objects to/from bytes.
178186

179187
## Resources
180188
Some helpful resources for learning about `libbitcoinkernel`:

doc/examples/README.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
# Example usage of py-bitcoinkernel
2+
3+
- Using `python-bitcoinlib` to (de)serialize and inspect kernel objects:
4+
[python-bitcoinlib.md](./python-bitcoinlib.md)

doc/examples/python-bitcoinlib.md

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
# Python-bitcoinlib Examples
2+
3+
The [`python-bitcoinlib`](https://github.com/petertodd/python-bitcoinlib)
4+
library allows constructing various objects from bytes. We can use this
5+
to more granularly inspect kernel objects that expose their contents as
6+
bytes, such as [`Block`](#inspecting-block-data) (`kernel_Block`) and
7+
[`TransactionOutput`](#inspecting-transactionoutput-data)
8+
(`kernel_TransactionOutput`).
9+
10+
> [!NOTE]
11+
> The `python-bitcoinlib` library is unrelated to this project, and
12+
> information here is provided only on a best-effort basis.
13+
14+
## Setup
15+
16+
First, we'll create a ChainstateManager and load the current chain tip:
17+
18+
```py
19+
import pbk
20+
chainman = pbk.load_chainman("/tmp/bitcoin/signet/", pbk.ChainType.SIGNET)
21+
tip = chainman.get_block_index_from_tip()
22+
```
23+
24+
## Inspecting Block Data
25+
26+
To analyze the block, we can use the `python-bitcoinlib` `CBlock` class:
27+
28+
```py
29+
from bitcoin.core import CBlock
30+
31+
block_bytes = chainman.read_block_from_disk(tip).data
32+
cblock = CBlock.deserialize(block_bytes)
33+
34+
assert tip.block_hash.hex == cblock.GetHash().hex()
35+
print(f"Block {cblock.GetHash().hex()} has {len(cblock.vtx)} transactions and {cblock.GetWeight()} weight")
36+
print(f"The last transaction has witness data: {cblock.vtx[-1].wit.vtxinwit}")
37+
```
38+
39+
## Inspecting TransactionOutput data
40+
41+
```py
42+
from bitcoin.core.script import CScript
43+
from pprint import pprint
44+
45+
undo = chainman.read_block_undo_from_disk(tip)
46+
result = {}
47+
for i, tx in enumerate(undo.iter_transactions()):
48+
result[i] = [CScript(output.script_pubkey.data) for output in tx.iter_outputs()]
49+
print(f"Block {tip.height} has transactions spending the following previous outputs:")
50+
pprint(result)
51+
```

0 commit comments

Comments
 (0)