Technical Architecture

Spend Template

P2WDA uses a P2WSH spend whose script pre-drops a fixed number of stack items (the data slots), then performs a standard single-sig check.

The witness script consists of:

  • 5 consecutive OP_2DROP operations (dropping 10 items total).
  • A 33-byte compressed public key.
  • An OP_CHECKSIG operation.

This creates a script of approximately 40 bytes that validates like any standard single-signature P2WSH spend, but with space for our data payload in the witness stack.

Authentication & Packing

The authentication and packing process ensures data integrity while maximizing compression efficiency. Here's how it works:

Step 1: Prepare the data

  • Start with your uncompressed payload data (application bytes).
  • Get the transaction signature (the DER signature that authorizes spending this input).

Step 2: Create authentication signature

  • Compute a BIP340 Schnorr signature over the hash of (transaction_signature || payload_data).
  • This signature proves authorship and binds the data to this specific spend.

Step 3: Combine and compress

typescript
// Combine the authentication signature with the payload
const combined_bytes = data_signature + payload_data;

// Compress everything using DEFLATE or similar
const compressed_bytes = COMPRESS(combined_bytes);

// Split into chunks of max 80 bytes each
const chunks = SPLIT_INTO_80_BYTE_CHUNKS(compressed_bytes);

// Ensure we don't exceed 10 chunks
if (chunks.length > 10) {
    throw Error("Payload too large")
}

Step 4: Build the witness stack

The witness stack must contain exactly 12 items in this order:

  1. Data slot 0 (up to 80 bytes, or empty).
  2. Data slot 1 (up to 80 bytes, or empty).
  3. ... through Data slot 9.
  4. Transaction signature (DER encoded, ~72 bytes).
  5. Witness script (~40 bytes).

Any unused data slots are filled with empty byte arrays (length 0) to maintain the expected stack structure.

Verification Process for Indexers

When an indexer encounters a P2WDA spend, it:

  1. Extracts and concatenates the first 10 witness items.
  2. Decompresses the result to get (data_signature || original_data).
  3. Verifies the Schnorr signature against hash (tx_signature || original_data).
  4. If valid, passes the original_data to the application layer.

This design ensures that while Bitcoin consensus never inspects the data, any tampering is cryptographically detectable by applications.

Input Placement Rules

To simplify parsing and minimize duplication:

  • All application data must be injected in the first P2WDA input by index (the lowest-index input spending a P2WDA UTXO).
  • Any additional P2WDA inputs in the same tx must supply 10 empty data items (length=0) in their witness.
  • Non-P2WDA inputs are unaffected.
  • If a transaction flagged as InteractionTransactionP2WDA spends no P2WDA UTXOs, throw an error.