Skip to content

Commit 2dd4fd2

Browse files
committed
add: examples using jshell and also updated readme
1 parent ff7b7c0 commit 2dd4fd2

File tree

7 files changed

+851
-408
lines changed

7 files changed

+851
-408
lines changed

README.md

Lines changed: 29 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,8 @@ This library is **alpha** - under active development. APIs may change and functi
2323
## Requirements
2424

2525
- **JDK 25+** (for FFM API support)
26-
- **CMake 3.16+**
27-
- **C++20 compiler** (GCC 11+ or Clang 14+)
26+
- **CMake 3.16+** fore Bitcoin Core compiling
27+
- **C++20** for Bitcoin Core compiling
2828
- **Boost libraries** - see Bitcoin Core [build documentation](https://github.com/bitcoin/bitcoin/blob/master/doc/build-unix.md)
2929

3030
## Quick Start
@@ -46,6 +46,24 @@ cd java-bitcoinkernel
4646
./gradlew test
4747
```
4848

49+
### Interactive Testing with JShell
50+
51+
Launch an interactive JShell session to explore the API:
52+
53+
```bash
54+
./examples/jshell-run.sh
55+
```
56+
57+
Then try:
58+
```java
59+
var kernel = createTempKernel();
60+
var chainman = kernel.getChainstateManager();
61+
var blocks = loadBlockData("tests/block_data.txt");
62+
// ... explore the API interactively
63+
```
64+
65+
See [examples/README.md](examples/README.md) for detailed JShell usage and more examples.
66+
4967
### Usage Example
5068

5169
```java
@@ -105,14 +123,14 @@ try (ScriptPubkey scriptPubkey = new ScriptPubkey(scriptPubkeyBytes);
105123

106124
BitcoinKernel.verify(
107125
scriptPubkey,
108-
amount, // Amount in satoshis
109-
tx, // Transaction being verified
110-
spentOutputs, // Array of outputs being spent
111-
inputIndex, // Input index to verify
112-
flags // Verification flags
126+
amount,
127+
tx,
128+
spentOutputs,
129+
inputIndex,
130+
flags
113131
);
114132

115-
System.out.println("Transaction verified successfully!");
133+
System.out.println("Transaction verified successfully");
116134
}
117135
```
118136

@@ -121,7 +139,6 @@ try (ScriptPubkey scriptPubkey = new ScriptPubkey(scriptPubkeyBytes);
121139
The wrapper follows Java's `AutoCloseable` pattern:
122140
- Objects created from byte arrays **own** their native memory
123141
- Objects obtained as views (e.g., `Block.getTransaction()`) **do not own** memory
124-
- Always use try-with-resources to ensure proper cleanup
125142

126143
## Development
127144

@@ -150,9 +167,9 @@ cd ../..
150167
## Platform Support
151168

152169
Currently tested on:
153-
- Linux (Ubuntu 22.04+)
154-
- macOS (12.0+)
155-
- ⚠️ Windows (not tested yet)
170+
- Linux (Ubuntu 22.04+)
171+
- macOS (12.0+)
172+
- Windows (not tested yet)
156173

157174
## References
158175

examples/BasicBlockProcessing.java

Lines changed: 165 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,165 @@
1+
import org.bitcoinkernel.*;
2+
import org.bitcoinkernel.Chainstate.*;
3+
import org.bitcoinkernel.Blocks.*;
4+
5+
import java.io.*;
6+
import java.nio.file.*;
7+
import java.util.*;
8+
9+
/**
10+
* Example: Basic Block Processing
11+
*
12+
* This example demonstrates:
13+
* - Creating a Bitcoin Kernel instance
14+
* - Processing blocks from a file
15+
* - Querying chain state
16+
* - Iterating through the blockchain
17+
*
18+
* Usage:
19+
* javac --class-path ../build/classes/java/main BasicBlockProcessing.java
20+
* java --class-path ../build/classes/java/main:. \
21+
* --enable-native-access=ALL-UNNAMED \
22+
* -Djava.library.path=../bitcoinkernel/bitcoin/build/lib \
23+
* BasicBlockProcessing
24+
*/
25+
public class BasicBlockProcessing {
26+
27+
public static void main(String[] args) throws Exception {
28+
System.out.println("=".repeat(70));
29+
System.out.println("Basic Block Processing Example");
30+
System.out.println("=".repeat(70) + "\n");
31+
32+
// Create a temporary directory for the blockchain data
33+
Path tempDir = Files.createTempDirectory("bitcoin-example");
34+
Path blocksDir = tempDir.resolve("blocks");
35+
Files.createDirectories(blocksDir);
36+
37+
System.out.println("Data directory: " + tempDir);
38+
System.out.println("Blocks directory: " + blocksDir + "\n");
39+
40+
// Initialize the Bitcoin Kernel
41+
try (BitcoinKernel kernel = new BitcoinKernel(
42+
ChainType.REGTEST,
43+
tempDir,
44+
blocksDir,
45+
msg -> System.out.println(" [Kernel] " + msg)
46+
)) {
47+
System.out.println("Bitcoin Kernel initialized\n");
48+
49+
// Get the chainstate manager
50+
ChainstateManager chainman = kernel.getChainstateManager();
51+
52+
// Load and process blocks from test data
53+
String blockDataFile = "../tests/block_data.txt";
54+
if (!new File(blockDataFile).exists()) {
55+
System.err.println("Block data file not found: " + blockDataFile);
56+
System.out.println("Run this from the examples/ directory");
57+
return;
58+
}
59+
60+
System.out.println("Reading blocks from " + blockDataFile);
61+
List<byte[]> blocks = readBlockData(blockDataFile);
62+
System.out.println("Loaded " + blocks.size() + " blocks\n");
63+
64+
// Process each block
65+
System.out.println("Processing blocks...");
66+
int processed = 0;
67+
for (int i = 0; i < Math.min(10, blocks.size()); i++) {
68+
try (Block block = new Block(blocks.get(i))) {
69+
boolean[] isNewBlock = new boolean[1];
70+
boolean success = chainman.ProcessBlock(block, isNewBlock);
71+
72+
if (success && isNewBlock[0]) {
73+
processed++;
74+
System.out.println(" Block " + i + ": processed");
75+
}
76+
}
77+
}
78+
System.out.println("Processed " + processed + " new blocks\n");
79+
80+
// Query chain state
81+
Chain chain = chainman.getChain();
82+
System.out.println("Chain Statistics:");
83+
System.out.println("Height: " + chain.getHeight());
84+
System.out.println("Total blocks: " + (chain.getHeight() + 1) + "\n");
85+
86+
// Get genesis block
87+
BlockTreeEntry genesis = chain.getByHeight(0);
88+
System.out.println("Genesis Block:");
89+
System.out.println("Height: " + genesis.getHeight());
90+
System.out.println("Hash: " + bytesToHex(genesis.getBlockHash().getHash()) + "\n");
91+
92+
// Get tip block
93+
if (chain.getHeight() > 0) {
94+
BlockTreeEntry tip = chain.getByHeight(chain.getHeight());
95+
System.out.println("Tip Block:");
96+
System.out.println("Height: " + tip.getHeight());
97+
System.out.println("Hash: " + bytesToHex(tip.getBlockHash().getHash()) + "\n");
98+
}
99+
100+
// Iterate through the chain
101+
System.out.println("Chain blocks:");
102+
int count = 0;
103+
for (BlockTreeEntry entry : chain) {
104+
System.out.println("Block " + entry.getHeight() + ": " +
105+
bytesToHex(entry.getBlockHash().getHash()).substring(0, 16) + "...");
106+
count++;
107+
if (count >= 5) {
108+
System.out.println("... and " + (chain.getHeight() - 4) + " more");
109+
break;
110+
}
111+
}
112+
113+
}
114+
115+
System.out.println("\nCleanup complete");
116+
System.out.println("=".repeat(70));
117+
118+
// Clean up temp directory
119+
deleteDirectory(tempDir.toFile());
120+
}
121+
122+
private static List<byte[]> readBlockData(String filepath) throws IOException {
123+
List<byte[]> blocks = new ArrayList<>();
124+
try (BufferedReader reader = new BufferedReader(new FileReader(filepath))) {
125+
String line;
126+
while ((line = reader.readLine()) != null) {
127+
line = line.trim();
128+
if (!line.isEmpty()) {
129+
blocks.add(hexToBytes(line));
130+
}
131+
}
132+
}
133+
return blocks;
134+
}
135+
136+
private static byte[] hexToBytes(String hex) {
137+
int len = hex.length();
138+
byte[] data = new byte[len / 2];
139+
for (int i = 0; i < len; i += 2) {
140+
data[i / 2] = (byte) ((Character.digit(hex.charAt(i), 16) << 4)
141+
+ Character.digit(hex.charAt(i+1), 16));
142+
}
143+
return data;
144+
}
145+
146+
private static String bytesToHex(byte[] bytes) {
147+
StringBuilder sb = new StringBuilder();
148+
for (byte b : bytes) {
149+
sb.append(String.format("%02x", b));
150+
}
151+
return sb.toString();
152+
}
153+
154+
private static void deleteDirectory(File directory) {
155+
if (directory.isDirectory()) {
156+
File[] files = directory.listFiles();
157+
if (files != null) {
158+
for (File file : files) {
159+
deleteDirectory(file);
160+
}
161+
}
162+
}
163+
directory.delete();
164+
}
165+
}

0 commit comments

Comments
 (0)