Exploring Bitcoin BDK with Rust code – Part 2

Introduction : Rather than reinvent the wheel, let’s look at a tutorial available on YouTube and then once we know about descriptors we’ll do the “hello world” BDK tutorial, so this is really a curated page of links, code, and screenshots of what you should see if you are successful.

Why BDK?

The simplest way to integrate Bitcoin wallet features into any application

Note, the BDK tutorial doesn’t show the successful output so what you will see here is a nice reassurance if you are ‘new’ 😊

https://youtu.be/md-ecvXBGzI?si=Gn2rUgqchfhxbG81

Webdock – Fast Cloud VPS Linux Hosting

What is a descriptor??

I wanted to know exactly what a wallet descriptor is as it seems to be a key feature with BDK

This is a good description ~ https://bitcoindevkit.org/descriptors/#examples

Descriptors are a compact and semi-standard way to easily encode, or “describe”, how scripts (and subsequently, addresses) of a wallet should be generated

https://bitcoindevkit.org/descriptors/#descriptors

So they’re like a recipe yeah?

“they create a common language to describe a full bitcoin script that developers can use”

They’re human readable as well, or at least recognisable.

Not every wallet implements every feature of descriptors though**

https://youtu.be/wsQIZRY2BD0?si=PkTi21B3RMnmk6YV&t=74

An output descriptor describes all of the output scripts that your wallet can spend to, or from

Tutorial on BitcoinDevKit

https://bitcoindevkit.org/blog/2020/12/hello-world/

create a wallet, get balance, print balance

We now have some output :

Generated Address: tb1q7w0t936xp5p994qx506xj53gjdcmzjr2mkqghn
Wallet balance in SAT: { immature: 0, trusted_pending: 0, untrusted_pending: 0, confirmed: 1555 }

Create transaction and broadcast (test network)

Ok, so I’m going to skip ahead a bit now as there is no point me just replicating the BDK tutorial, but pay attention to the code, I had to alter line 43 by adding payload

faucet_address.payload.script_pubkey(),

Full code :


Webdock – Fast Cloud VPS Linux Hosting

View the actual transaction details here:

https://blockstream.info/testnet/tx/f8d27f184c4076f3c3a28e9e998985c17a19289cae748fd63a2f1171090287df?expand

Conclusion

From the BDK tutorial I typed in the code rather than copy and paste as I tend to remember it more if I type it in.

We made a wallet, got the balance, made a transaction, signed it, and broadcast it, and saw the result on the Blockstream page. Nice!

If you want to know more about what a PSBT is – check out this article

https://docs.rs/bdk/latest/bdk/wallet/tx_builder/index.html

We effectively sent balance /2 in this example, but for a more realistic example, we would specify the amount, and the change amount :

    .add_recipient(to_address.script_pubkey(), 50_000)
    // With a custom fee rate of 5.0 satoshi/vbyte
    .fee_rate(bdk::FeeRate::from_sat_per_vb(5.0))
    // Only spend non-change outputs
    .do_not_spend_change()
TX Bullder

Next:

we’ll look into using a database (sled) rather than “in memory”

#![allow(unused)]
use bdk::bitcoin::Network;
use bdk::blockchain::ElectrumBlockchain;
use bdk::database::Database;
use bdk::Wallet;

fn main() {
    // Set the network to Bitcoin testnet
    let network = Network::Testnet;
    let db: sled::Db = sled::open("my_db").unwrap();

    // insert and get
    let x = db.insert(b"yo!", b"v12").unwrap();

    // Retrieving and printing the value associated with the key "yo!"
    if let Some(value) = db.get(b"yo!").unwrap() {
        if let Ok(value_str) = std::str::from_utf8(&value) {
            println!("Retrieved value for 'yo!': {}", value_str);
        } else {
            println!("Failed to convert retrieved bytes to UTF-8 string");
        }
    } else {
        println!("No value found for 'yo!'");
    }

}