Carrier model
The carrier, the transaction, the bytes
Drops does not invent a transaction format. It reuses the Taproot script path exactly as BIP 341 defines it, and adds one rule: the leaf you reveal must be a Drops leaf, and it must be the leaf the output actually committed to.
The carrier model in one paragraph
A carrier is a way of putting bytes into a Bitcoin transaction such that a reader can recover them exactly. The OP_DROP carrier does this with data pushes that are immediately discarded by OP_DROP, leaving a plain single-signature script behind. The bytes are in the witness of the spending transaction, so they cost witness-discounted weight, and they are only revealed when the output is spent. The carrier says nothing about what the bytes mean. That is what a marker is for.
The marker registry
The first push of the leaf is a namespace. One marker means one thing. A parser that accepts a marker it does not own is a parser that will eventually credit the wrong record.
| Marker | Owned by | Carries | Documented in |
|---|---|---|---|
drops | Drops | A media-first artifact body with a declared content type. | Drops specification |
drops-pact | Drops | A Pact Seed: the agreement identity and the hashes that pin its terms. | Drop Pacts |
6269703131302d6f702d64726f70 (OP_DROP marker hex) | OP_DROP | A token event: deploy, mint or transfer. | OP_DROP summary, and the OP_DROP repository |
| Name | Where it lives | Purpose |
|---|---|---|
drops-cell | A separate Tapscript leaf in a Pact state output | Identifies the live state cell of a Pact in the future execution model. Not accepted as a Drop. |
DPC1 | An OP_RETURN anchor output | Marks a candidate Pact state transition. A transition still has to be proved; the anchor alone proves nothing. |
A Drops indexer must reject 6269703131302d6f702d64726f70 (OP_DROP marker hex). An OP_DROP indexer must reject drops and drops-pact. They share a carrier shape and nothing else. An artifact never becomes a token balance, and a token event never becomes an artifact.
Payload encoding
Bitcoin Script has more than one way to push most values. Drops accepts exactly one: the shortest. This removes an entire class of ambiguity, because two scripts that decode to the same fields are byte-identical.
Minimal push encoding
| Data length | Required encoding | Prefix bytes |
|---|---|---|
1 byte, value 0x00 | OP_PUSHBYTES_1 | 01 |
1 byte, value 0x01 to 0x10 | No data push exists. Invalid as a Drops field. | Script folds these to OP_1 to OP_16 |
1 byte, value 0x81 | No data push exists. Invalid as a Drops field. | Script folds this to OP_1NEGATE |
| 1 byte, any other value | OP_PUSHBYTES_1 | 01 |
| 2 to 75 bytes | OP_PUSHBYTES_N | 02 to 4b |
| 76 to 255 bytes | OP_PUSHDATA1 | 4c then one length byte |
| 256 bytes | OP_PUSHDATA2 | 4d then two little-endian length bytes |
Because the fixed-length fields are 32 bytes and the content type is at most 80, only the body can reach the OP_PUSHDATA range. The 256-byte body limit sits exactly one byte past the OP_PUSHDATA1 ceiling, so a maximum-size body is encoded with OP_PUSHDATA2.
A worked leaf, byte by byte
A minimal artifact carrying the eleven ASCII bytes hello drops as text/plain.
field encoding bytes
----------------------------------------------------------------
marker OP_PUSHBYTES_5 05 64726f7073
"drops"
OP_DROP 75
content type OP_PUSHBYTES_10 0a 746578742f706c61696e
"text/plain"
OP_DROP 75
body hash OP_PUSHBYTES_32 20 <32 bytes of SHA256(body)>
OP_DROP 75
body OP_PUSHBYTES_11 0b 68656c6c6f2064726f7073
"hello drops"
OP_DROP 75
creator key OP_PUSHBYTES_32 20 <32-byte x-only pubkey>
OP_CHECKSIG ac
Leaf script length here is 6 + 1 + 11 + 1 + 33 + 1 + 12 + 1 + 33 + 1 = 100 bytes. Paste the assembled hex into the payload decoder to see it broken apart with each field explained.
Computing the tapleaf hash
tag(t) = SHA256(t)
taggedHash(t,m) = SHA256(tag(t) || tag(t) || m)
leafHash = taggedHash("TapLeaf",
0xc0 || compactSize(len(script)) || script)
for each 32-byte sibling h in the control block path:
leafHash = taggedHash("TapBranch", min(leafHash,h) || max(leafHash,h))
tweak = taggedHash("TapTweak", internalKey || leafHash)
Q = internalKey + tweak*G
assert xOnly(Q) == spentOutputKey
assert parity(Q) == controlBlock[0] & 1
A compactSize length prefix is one byte for scripts under 253 bytes, which covers every possible Drops leaf, since the largest is bounded by a 256-byte body and an 80-byte content type.
Weight and fee behaviour
Witness bytes are discounted: one weight unit per byte instead of four. A Drops reveal therefore costs far less than putting the same bytes in an output script, and the commit output stays a plain 34-byte P2TR.
The dominant variable cost is the body. A 256-byte body adds roughly 259 witness bytes once its OP_PUSHDATA2 prefix is counted, which is about 65 virtual bytes. The control block adds 33 bytes plus 32 per merkle sibling, so a deep script tree is the other thing worth watching.
Concrete numbers and a sizing table are in the reference.