Drops Protocol documentation

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.

Anatomy of a Drops commit and reveal On the left, the commit transaction has one output: a pay to Taproot script of thirty-four bytes, OP_1 followed by a thirty-two byte output key Q. Q is the internal key P tweaked by the merkle root of a script tree that contains the Drops leaf. On the right, the reveal transaction spends that output. Its input witness holds three items: a Schnorr signature of sixty-four or sixty-five bytes, the Drops leaf script, and a control block of thirty-three bytes plus thirty-two bytes per merkle path element. The reveal transaction's output zero becomes the custody outpoint of the recorded artifact. A dashed line connects the leaf in the witness back to the script tree that Q committed to. COMMIT TRANSACTION output 0 OP_1 <32-byte Q> 34 bytes, native P2TR Q = P + taggedHash("TapTweak", P || root)·G root = merkle root of the script tree SCRIPT TREE leaf version 0xc0 <marker> OP_DROP ... OP_CHECKSIG up to 128 sibling hashes may sit alongside it spent by REVEAL TRANSACTION input i, witness stack [0] Schnorr signature, 64 or 65 bytes [1] Drops leaf script [2] control block, 33 + 32n bytes output 0 becomes the custody outpoint of the recorded artifact no annex item is permitted anywhere in the witness The dashed path is the whole point: the leaf in the witness must be a leaf that Q committed to. MUST MATCH Bytes live in the witness, so they are discounted to one weight unit per byte rather than four. Nothing is revealed until the output is spent. An unspent commit output tells an observer nothing. The reveal input index, not any output, gives the artifact its identity.
Commit and reveal, with the commitment check that makes the reveal trustworthy.

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.

Markers carried by the OP_DROP leaf shape
MarkerOwned byCarriesDocumented in
dropsDropsA media-first artifact body with a declared content type.Drops specification
drops-pactDropsA Pact Seed: the agreement identity and the hashes that pin its terms.Drop Pacts
6269703131302d6f702d64726f70 (OP_DROP marker hex)OP_DROPA token event: deploy, mint or transfer.OP_DROP summary, and the OP_DROP repository
Related Pact structures that are not leaf markers
NameWhere it livesPurpose
drops-cellA separate Tapscript leaf in a Pact state outputIdentifies the live state cell of a Pact in the future execution model. Not accepted as a Drop.
DPC1An OP_RETURN anchor outputMarks a candidate Pact state transition. A transition still has to be proved; the anchor alone proves nothing.
Separation is a rule, not a convention

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

Which push opcode is required for which length
Data lengthRequired encodingPrefix bytes
1 byte, value 0x00OP_PUSHBYTES_101
1 byte, value 0x01 to 0x10No data push exists. Invalid as a Drops field.Script folds these to OP_1 to OP_16
1 byte, value 0x81No data push exists. Invalid as a Drops field.Script folds this to OP_1NEGATE
1 byte, any other valueOP_PUSHBYTES_101
2 to 75 bytesOP_PUSHBYTES_N02 to 4b
76 to 255 bytesOP_PUSHDATA14c then one length byte
256 bytesOP_PUSHDATA24d 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.

A dark studio still life of a glass artifact on a metal plinth, with a chain of small illuminated blocks running toward it.
One carrier shape, several registries, each with its own owner and its own rules.