bitcoin-embed

Crates.iobitcoin-embed
lib.rsbitcoin-embed
version0.1.0
created_at2025-06-17 02:14:31.570382+00
updated_at2025-06-17 02:14:31.570382+00
descriptionA library for embedding arbitrary data and TLV-encoded messages in Bitcoin transactions
homepagehttps://github.com/joshdoman/bitcoin-embed
repositoryhttps://github.com/joshdoman/bitcoin-embed
max_upload_size
id1715105
size73,179
(joshdoman)

documentation

README

bitcoin-embed

A library for embedding arbitrary data and TLV-encoded messages in Bitcoin transactions. Supports OP_RETURN outputs, witness script envelopes, and taproot annexes.

Installation

[dependencies]
bitcoin-embed = "0.1.0"

Features

  • Embedding Extraction: Extract data from Bitcoin transactions with detailed location information. Supports:

    • OP_RETURN outputs
    • Taproot annexes
    • OP_FALSE OP_IF ... OP_ENDIF witness envelopes (supports P2TR and P2WSH)

    Note: P2WSH envelopes require inputs with at least 2 witness elements

  • TLV Message Encoding: Efficiently encode and decode a series of tagged messages

  • Script Embedding: Embed arbitrary data in Bitcoin script using an OP_FALSE OP_IF ... OP_ENDIF script envelope

Message Encoding Scheme

The library implements an efficient binary encoding scheme for tagged messages:

  • Space-Efficient: Tags and message lengths are encoded as LEB128 variable-length integers to minimize bytes
  • Tag Deduplication: Repeated consecutive tags use a special marker (0) instead of repeating the full tag
  • Explicit Termination: The initial LEB128 integer represents 2 * tag + (1 if terminal tag else 0) to efficiently encode the tag and indicate termination
  • Compact Format: The final message doesn't include an explicit length, saving bytes

This encoding scheme is valuable for embedding data in Bitcoin transactions where multiple messages must be encoded in the same location. It allows for up to $2^{127}-1$ unique tags while minimizing the overhead needed to encode.

Basic Usage

Embedding Data

use bitcoin::{Transaction, script::Builder};
use bitcoin_embed::envelope;

// Create an envelope with data
let builder = Builder::new();
let builder_with_data = envelope::append_bytes_to_builder(b"Hello, Bitcoin!", builder);

Extracting Embedded Data

use bitcoin_embed::Embedding;

// Extract all embedded data from a transaction
let tx = /* A Transaction object */;
let embeddings = Embedding::from_transaction(&tx);

for embed in embeddings {
    match embed.location {
        // Handle OP_RETURN data
        EmbeddingLocation::OpReturn { output } => {
            println!("Found OP_RETURN data at output {}: {:?}", output, embed.bytes);
        },
        
        // Handle taproot annex data
        EmbeddingLocation::TaprootAnnex { input } => {
            println!("Found taproot annex data at input {}: {:?}", input, embed.bytes);
        },
        
        // Handle envelope data (P2WSH or Tapscript)
        EmbeddingLocation::WitnessEnvelope { input, index, script_type, .. } => {
            println!("Found envelope data at input {} (index {}): {:?}", 
                     input, index, embed.bytes);
            println!("Script type: {:?}", script_type);
        }
    }
}

Working with Tagged Messages

use bitcoin_embed::message::Message;

// Create a message with a tag and data
let msg = Message::new(42, b"Tagged data".to_vec()).unwrap();

// Encode multiple messages
let msg2 = /** A second message */
let encoded = Message::encode(vec![msg, msg2]);

// Decode messages from bytes
let decoded = Message::decode(&encoded).unwrap();

License

This project is licensed under the CC0-1.0 License.

Author

Joshua Doman joshsdoman@gmail.com

Commit count: 8

cargo fmt