Skip to content

OP_RETURN datacarrier classification taxonomy #1

Description

@melvincarvalho

OP_RETURN datacarrier classification taxonomy

This documents how block·health classifies OP_RETURN datacarrier outputs. Every classification is decoded locally in the browser (in validator-worker.js) straight from the raw block bytes — no external indexer or attribution service is trusted.

How it works

  • Classification is per output, not per transaction — a single tx with several OP_RETURNs gets each output labelled independently.
  • The labels are mutually exclusive. classifyOpReturn() checks them in the order below and returns the first match.
  • The coinbase witness commitment (6a24aa21a9ed…) is excluded upstream and counted separately — it is protocol overhead, not datacarrier.
  • Classification is orthogonal to the health metric (OP_RETURN outputs over the historical 80-byte data / 83-byte scriptPubKey standard). A block can be "bloated" and the breakdown tells you what the bloat is.

The classes

Class Detection Confidence Notes
OP_NET scriptPubKey starts 6a 58 (OP_RETURN OP_8) high (marker) OP_NET epoch challenge submissions — SHA-1 proof-of-work solutions. Payload carries the solver's account key + solution preimage.
Alkanes 6a 5d runestone containing Protocol tag 16383; reassemble the 15-byte-chunked protostone and the first LEB128 integer == 1 high Alkanes metaprotocol message riding inside a runestone (invisible to Runes indexers — odd tag).
protostone (other) 6a 5d runestone with tag 16383 but protocol id ≠ 1 high (is a protostone) Non-Alkanes protorunes protocol.
Runes 6a 5d runestone (OP_RETURN OP_13) with no 16383 protocol field high (marker) Plain rune etch / mint / transfer.
ProofOfWork.Me payload begins with an ASCII protocol id: pwt1: / pwm1: / pwid1: / pwr1: high (marker) Social/token/mail system on legacy Bitcoin with 546-sat "proof" payments. pwt1: credits, pwm1: mail/bonds, pwid1: identities, pwr1: registry.
bridge Heuristic: pushed payload ≥ 20 B, ≥ 90% printable ASCII, and contains an EVM-style 0x[0-9a-f]{40,} and/or a depositor= / recipient= / refund= / destination= / bridge / deposit / dest= field heuristic Custodial/bridge deposit memo, e.g. 0x<hex>|depositor=bc1q…|. Recall-limited by design; does not attribute a specific operator.
padding Non-marker OP_RETURN whose pushed payload is ≥ 8 bytes and entirely 0x00 high Zero-filled reservation output (Alkanes txs commonly emit one). Split out so it doesn't inflate the data count; the detail view reports total bytes spent on padding.
plain data anything else Genuinely uncategorised bytes (timestamps, raw commitments, unknown protocols).

Project references

Reference transactions (analysed while building this)

  • Alkanes: d22d4d81be4896f1309fd140a101e0350dbd1b31c19946380fe02c3060078c4e (no-op runestone + protostone), 8bfd8d36c50797e631125e6184a097091c817fdf5ffa7c76b64f8009a7e0bd9f (clean, single OP_RETURN)
  • OP_NET: 658b32af4687d1cb9e5cec6779bcfe74348fd2836a0c009dc868b87280251834 (challenge solution, 6a58)
  • ProofOfWork.Me: bb4a05ad31a9ed0adb82c106a6b74bdc6403f1f83744bb73eac3a758c4dff648 (pwm1:m:incb Inception Bond + attached pwt1:send:<credit-txid>:<amount>:<addr> credit transfer, legacy P2PKH)
  • bridge: d2819802477eeee6d0272d037731f4830e91eaee1958013e75adc6231acc56d0 (0x…|depositor=bc1q…|)
  • padding: 2b530e906449c2f5313a3b674b337431a7c8a85d06ca16025cda600e63159980 (174 B), 301ba4ccc3a700068db90818fcff2e109c9727dede723d2e4f2ba5fc4f45af6e (225 B), 90f47c9913edd98c8e2eeed2b6ecd9338a61ca23db0222067876068c46f57ea0 (1,000 B of zeros — 69% of the transaction)

Known limitations / follow-ups

  • bridge is a heuristic, not a magic byte. It will miss deposit formats that don't use the 0x…/depositor= conventions, and it names no operator (that would require matching receiving addresses against a known-address list).
  • protostone (other) is a catch-all for non-Alkanes protorunes protocols; it does not decode the specific protocol.
  • OP_NET marker: the 6a58 prefix → OP_NET is high-confidence from the payload format matching OP_NET's ChallengeSolution serializer; the exact marker byte being OP_NET's was inferred, not read from their OP_RETURN builder.
  • Ordinals / inscriptions are not classified — they live in the taproot witness, not OP_RETURN, so they're out of scope for this datacarrier scan (a heavier witness-level parse would be needed).
  • Possible additions: an "other runestone-shaped (OP_N)" bucket, per-block "bytes spent on padding" as a first-class stat, and decoding the Alkanes cellpack (target + opcode) best-effort.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions