#bitcoin #public-key #binary-format #crypto #cryptography

bitcoin-bosd

Rust implementation of a Bitcoin binary output script descriptor (BOSD)

2 unstable releases

new 0.2.0 Jan 19, 2025
0.1.0 Jan 14, 2025
0.0.0 Jan 9, 2025

#203 in #public-key

Download history 107/week @ 2025-01-05 159/week @ 2025-01-12

266 downloads per month

MIT/Apache

70KB
1K SLoC

Bitcoin Output Script Descriptor (BOSD)

License: MIT License: Apache-2.0 ci docs

Features

  • Compact binary representation of standard Bitcoin output types.
  • Zero-copy parsing and validation.
  • Support for P2PKH, P2SH, P2WPKH, P2WSH, P2TR, and OP_RETURN outputs.
  • Implements serde and borsh serialization.
  • Strict validation of Bitcoin addresses and output formats.
  • Direct conversion to bitcoin::ScriptBuf.

Specification

[!NOTE] The full specification is available in the BOSD Specification document.

BOSD uses a simple binary format consisting of a 1-byte type tag followed by a cryptographic payload. The format is designed to be compact and efficiently represent standard Bitcoin output types:

Type Payload Length(s) Payload Interpretation Spend Type Mainnet Address Prefix
0 ..=80 OP_RETURN payload (N/A) (N/A)
1 20 pubkey hash P2PKH 1...
2 20 script hash P2SH 3...
3 20, 32 SegWit v0 hash P2WPKH, P2WSH bc1q...
4 32 SegWit v1 public key P2TR bc1p...

Examples

  • SegWit V0 (P2WPKH) bech32 mainnet address given a 20-byte public key hash: 034d6151263d87371392bb1b60405392c5ba2e3297 $\iff$ bc1qf4s4zf3asum38y4mrdsyq5ujckazuv5hczg979
  • SegWit V1 (P2TR) bech32m mainnet address given a 32-byte X-only public key: 041234123412341234123412341234123412341234123412341234123412341234 $\iff$ bc1pzg6pydqjxsfrgy35zg6pydqjxsfrgy35zg6pydqjxsfrgy35zg6qf6d5se
  • OP_RETURN payload given a hex string that is less than 80 bytes: 00deadbeefcafebabe $\iff$ RETURN PUSHDATA(deadbeefcafebabe)

Usage

use bitcoin::Network;
use bitcoin_bosd::Descriptor;

// Parse from binary
let desc = Descriptor::from_bytes(&[0x04, /* 32 bytes of pubkey */])?;

// Convert to Address
let address = desc.to_address(Network::Bitcoin)?;

// Convert to ScriptBuf
let script = desc.to_script()?;

// Serialize/deserialize
let json = serde_json::to_string(&desc)?;
let serde_bytes = serde_json::to_vec(&desc)?;
let borsh_bytes = borsh::to_vec(&desc)?;

Features

Feature Default? standalone Description
address Adds Bitcoin Address and ScriptBuf functionality
arbitrary needs address Adds Arbitrary to generate random descriptors for fuzzing and property testing
borsh Adds descriptor serialization and deserialization via borsh
serde Adds descriptor serialization and deserialization via serde

Contributing

Contributions are generally welcome. If you intend to make larger changes please discuss them in an issue before opening a PR to avoid duplicate work and architectural mismatches.

For more information please see CONTRIBUTING.md.

License

This work is dual-licensed under MIT and Apache 2.0. You can choose between one of them if you use this work.

Dependencies

~0.5–2.4MB
~41K SLoC