Friday Night Challenge: Worst case DUST

Only for the cool kids.

The challenge: What’s the worst case DUST needed to cover a relay-valid output (i.e. ignoring things that only miners can do)?

The motivation for the question is if you have a contract that needs to enforce output amounts, what is a very safe DUST that will cover 99.9% of cases.

The estimate to beat here (from discussion on BCHN slack which will eventually sink under the threshold of slack free tier).

Libauth provides a readable basis for the underlying rules here.


Didn’t we figure it out already? 1332.

I’ll add the explanation here for future reference.

Formula is implemented here, and can be rearranged to: (output_size_in_bytes)*3 + 444.

So the question is: what’s the biggest output acceptable by network relay rules?

Recall the token output format:

Field Length Format Description
value 8 bytes unsigned integer(LE) The number of satoshis to be transferred.
token prefix and locking script length variable variable length integer The combined size of full token prefix and the locking script in bytes.
PREFIX_TOKEN 1 byte constant Magic byte defined at codepoint 0xef (239) and indicates the presence of a token prefix.
token category ID 32 bytes bytes After the PREFIX_TOKEN byte, a 32-byte “token category ID” is required, encoded in OP_HASH256 byte order.
token bitfield 1 byte bitfield A bitfield encoding two 4-bit fields is required.
[NFT commitment length] variable variable length integer The size of the NFT commitment in bytes. Present only if token bitfield bit 0x40 is set.
[NFT commitment] variable bytes The contents of the NFT commitment. Present only if token bitfield bit 0x40 is set.
[FT amount] variable variable length integer An amount of fungible tokens, present only if token bitfield bit 0x10 is set.
locking script variable bytes(BE) The contents of the locking script.

From this, we can work out the biggest output:

  • satoshi amount is always 8 bytes
  • The token prefix and locking script length can be 1 or 3 bytes, depending on combined length of token payload and locking script.
  • The biggest token payload is easy to work out, it is 84 bytes (fungible token amount >= 4294967296 so it requires 9-byte encoding, and NFT commitment of 40 bytes).
  • The biggest locking script require us to recall standard locking script patterns (see below) and it will be the M of 3 “bare” multisig (P2MS), giving us 201 bytes.

Total will then be 201+84+3+8 == 296 bytes, and plugging it into dust limit formula we get (296*3)+444 == 1332 bytes.

For reference, transaction with such output mined on testnet4: [TEST4] - Transaction 5325145f86ff4544bfedd628f6a7dee5877e86825da3a7bbca145d56f9eebb15

What are the possible locking bytecode sizes?

Only the 6 locking bytecode patterns are acceptable:

  1. P2PK: OP_DATA_X {pubkey} OP_CHECKSIG. The pubkey can be 33 or 65 bytes, depending on whether compressed or uncompressed public key is used, so these will have locking bytecode of 35 or 67 bytes (2 + {33|65}).
  2. P2PKH: OP_DUP OP_HASH160 OP_DATA_20 {pubkeyHash} OP_EQUALVERIFY OP_CHECKSIG. The pubkeyHash is constant 20, so the whole locking bytecode will be constant 25.
  3. P2SH20: OP_HASH160 OP_DATA_20 {redeemScriptHash20} OP_EQUAL. The redeem script hash is constant 20, so the whole locking bytecode will be constant 23.
  4. P2SH32: OP_HASH256 OP_DATA_32 {redeemScriptHash32} OP_EQUAL. The redeem script hash is constant 32, so the whole locking bytecode will be constant 35. (note that docs haven’t yet been updated with this one, see the P2SH32 CHIP for details).
  5. P2MS: OP_M {OP_DATA_X {pubkey_n}}{x1-3} OP_N OP_CHECKMULTISIG. Here the key can be 33 or 65 bytes, so the total size can vary between (3 + 1*34) and (3 + 3*66), i.e. between 37 and 201 bytes.
  6. OP_RETURN {data pushes} with total size limited to 223.

OP_RETURN is the biggest but it doesn’t have a dust limit because it’s provably unspendable so never becomes part of UTXO set. The next biggest is P2MS of 201, then P2PK of 67, then P2SH32 of 35, then P2PKH of 25, then P2SH20 of 23.

We can easily calculate biggest dust limits for each type:

  • P2PK: 67+84+1+8 == 160 bytes, dust limit 924 (672 if no tokens)
  • P2PK compressed: 35+84+1+8 == 128 bytes, dust limit 828 (576 if no tokens)
  • P2PKH: 25+84+1+8 == 118 bytes, dust limit 798 (546 if no tokens)
  • P2SH20: 23+84+1+8 == 116 bytes, dust limit 792 (540 if no tokens)
  • P2SH32: 35+84+1+8 == 128 bytes, dust limit 828 (576 if no tokens)
  • P2MS: 201+84+3+8 == 296 bytes, dust limit 1332 (1080 if no tokens)
  • P2MS compressed: 105+84+1+8 == 198 bytes, dust limit 1038 (786 if no tokens)

I think you did. And also thank you for explaining it here in great detail!!

However, the discussion that led to the answer was surprisingly fresh. I thought it would be an old road, traveled many times and well documented. This is an opportunity for someone to snipe the answer with something surprising.

… your post here probably belongs in the BCH specification as an exploration of the boundaries.