CIP21 - Dispensers



Address 17XGUUpJpd5FPrHuUcuhMeXjzm5VVPc3uG has been created, assigned to CIP21, and fully funded.


Nice work!

When will it be live?

Can I help test it on the testnet or irl?


It’s being tested rn, however the current implementation goes along with cip6, cip20 and cip21, and there’s an error popping up which i can’t nail quite yet (something about scriptverify flags being enforced, but that was working before… huh)


awesome, I’m really looking forward for this one


Milestone #1 payout (0.125 BTC)

Milestone #2 payout (0.125 BTC)



Amount to dispense ???>> What do I put here ? Just one token ?
Enter the amount of the asset to be dispensed for each main chain amount received.

Amount to escrow - This is how much I want you to excrow for the top amount to dispense before escrow runs out , RIGHT?

“The total quantity to escrow, it’s suggested to be a multiple of the dispenser give amount”<<< this is confusing, shouldn’t it read the amount you want to be dispensed total ?

Main chain rate ? Is this the bitcoin rate per coin or per the total escrowed ? Jaut says “The amount of bitcoin to be received” But for WHAT ? One coin or the total escrowed coins ?

1 Like

Use desktop wallet… every field has a questionmark next to it which you can hover your mouse over to get a detailed description of what the field is expecting… it answers your questions above

Some thoughts on dispenser upgrades…

  • Delayed closing
    Rather than closing the dispenser immediately, all dispenser closing are delayed by 5-10 blocks to prevent a dispenser operator from closing a dispenser with a high fee after buyer sends funds.

  • Close to creation address option
    One pain point with dispensers is after they’re closed you need to send BTC to the dispenser address to be able to send the asset back to yourself. Adding a flag to send the dispenser escrow back to the creation address would alleviate this issue.

  • Allowable address option
    Dispenser will only dispense to a pre-determined address when using this option. This would be the equivalent of leveraging Counterparty as the escrow for an OTC deal in BTC.

  • Expiration option
    Similar to DEX orders, an expiration option would be specified as a number of blocks from creation. This could be used in conjunction with the “close to creation address” option to give users an Opensea-style experience.


Thanks for writing up your thoughts on these great features… All of them sound good to me. Some additional thoughts below.

  • Delayed closing
    Rather than closing the dispenser immediately, all dispenser closing are delayed by 5-10 blocks to prevent a dispenser operator from closing a dispenser with a high fee after buyer sends funds.

I support this idea, but I propose a tweak to this, which is that we only delay closing the dispenser if there is a pending dispense. This would solve the problem of dispenser operators closing dispensers with a pending dispense, but also allow dispenser operators to close their dispenser immediately if there is no pending txs (BTC incoming) to the dispenser address. Thoughts?

I too have been thinking about various features that we could add to the dispensers to make them more usable in various cases. Here are some of my thoughts on additional dispenser upgrades…

  • Use/Reuse any bitcoin address as a dispenser
    Currently Counterparty only allows opening of new dispensers on a different address if that address is a fresh/empty addresses with no transaction history.

    We could update Counterparty to allow opening up of a dispenser on any address, once that address ownership has been verified via a signed message. Perhaps we standardize the message that is to be signed to be the current date in YYYY-MM-DD format like ‘2023-01-23’, then update Counterparty API with a open_address_signature field, which users can provide the message signature. The API would simply verify if the message signature was valid (proving ownership of the open_address), and then would allow opening of the dispenser on the open_address.

  • Allow dispensers to sell ‘packs’ of cards
    Currently Counterparty dispensers only sell one card at a time, and to sell multiple cards at the same time, you need to setup multiple dispensers on the same address.

    We could update counterparty to allow users to specify a list of what assets/tokens/quantity get dispensed when a dispense is triggered. We could have the wallet allow users to provide a simple list of assets to dispense similar to MPMA sends:

    BACON, 1.00000000
    PEPECASH, 1000000.00000000
    XCP, 1.23456789

    In the API we would have the following changes :

    • asset field would change to support array of assets [‘BACON’,‘RAREPEPE’,‘PEPEPCASH’,‘XCP’]
    • give_quantity field would change to support array of quantities [100000000,1,100000000000000,123456789]
    • escrow_quantity field would change to support array of quantities [1000000000,10,1000000000000000,1234567890] (10x dispenses)

The problem here is you can’t do this at a protocol level because the mempool is not the same across nodes. So there’s really no way for counterparty-lib to detect pending dispenses. You could probably be closer to 5 block delay rather than 10 and still get the benefit of preventing scam dispensers. That should be a short enough amount of time that people aren’t inconvenienced too much.

1 Like

Thanks for the clarification. I tend to disagree about the inconvenience… having to wait 1-2 hours to close a dispenser is a long time, especially in cases where the dispenser operator is just trying to change the dispenser price. Or where they opened a dispenser at a bad price by mistake, Now they are supposed to close the dispenser, wait an hour, come back and then re-open the dispenser?.. seems inconvenient.

I support trying to prevent fraud on dispensers, but not sure preventing users from being able to perform actions in a timely manner is the correct path forward… do we have any stats on how often this “close while dispense is pending” is actually happening?

It’s just a trade off to prevent a low cost attack. Personally I think it’s probably worth the minor inconvenience of dispenser closers waiting a few blocks once the cancel tx is confirmed.

At the end of the day, due to the nature of dispensers, we can’t prevent all attacks. A bad actor could always snipe by paying dispenser price with a very high fee and this wouldn’t prevent that.

1 Like

Lots of interesting suggestions. Some thoughts:

Delayed closing
I’m against it. It’s sort of possible already to delay closing by using a low btc fee. Conversely, if you want to close immediately, use a high fee. I think this simplicity/flexibility is good.

And as you mentioned, a bad actor could front-run dispensers anyway.

Close to creation address option
This would be a great feature! My only concern is the length of the message data. Dispensers already use 84 bytes when oracle feed is added. Would be great if this option can fit an 80 byte op_return somehow.

Allowable address option
Great suggestion! Maybe this should be a new message type tho? Unlike dispenser, which require 100% trust (and is currently being used VERY IRRESPONSIBLY), the allowable address option will require no trust.
It should be easy to build infrastructure around such a contract too. I will write a separate post about this. IMO potentially a very useful upgrade to Counterparty.

Expiration option
This is something I want and certainly would use. Again, my only concern is the message data. Maybe bundle several such upgrades to a new tx ID, and make the op_return message more efficient to fit 80 bytes?

Use/Reuse any bitcoin address as a dispenser
Does your suggestion open up for scripts/wallet not using API to put dispensers on any address? A solution on the protocol level could be to let an address send a broadcast to open it up for dispensers. I believe something similar exists, require memo, where an address broadcasts that it only accepts transfers with a memo.

Allow dispensers to sell ‘packs’ of cards
Isn’t this already possible by setting up multiple dispensers on one address? If anything, I’d actually like to allow several dispensers of the same asset on the same address. It opens up for 3 for 2 offers etc. (Would be possible if one dispenser has price 0.1 and the other 0.2).

Two more topics I’d like to discuss:

If partial dispense is detected, reserve token for 12 blocks. If a second tx is made within the deadline, and the amounts sum up, then make the dispense.
This will remove the need to trust the seller. IMO a very high priority should be to add either this feature to dispensers or a new OTC contract.

Random dispense
Send BTC, have a 1/X chance of getting the token. The block hash is a perfect random number. This should probably be a new transaction type under a different name.


Hi all,

The biggest feature I need is the ability to set a max number of tokens to dispense per transaction.

I am trying to do free airdrops to onboard as many users as possible. We can’t do it for free though or you have 1 person claim the entire supply in one transaction. I just tried it today and made it very clear as a request to only claim 1 of my Based Intellectuals stamps to be fair and allow enough people to claim them. The cost was $0.29 each. Out of 99 people who claimed, all but 6 people claimed just 1. These 6 claimed 10, 10, 10, 13, 34, 80.

I’m doing this project for fun to onboard people. I don’t want to make money from it and it could even hurt me or make it look like a cash grab if I start charging. But in order to keep this fair, I might have to raise the price so a couple people can’t break the rules and just claim them all. This might also limit the people who will participate and take away the “fun” part.

So, my goal is to get as many unique users as my collectors as possible for a free dispenser. My solution for this is to have a limit of 1, where the max you can dispense is 1 item no matter how much BTC you send. If you try to send more BTC, you won’t get more, you still get 1. This is very common in Ethereum and Stacks as well. During the start of an NFT mint, there’s a max mint per tx. The goal of this is to give everyone a fair shot at minting so one person doesn’t hog all the supply.

Users can still claim more by sending more tx if they want, that’s fine. Since even if you were to make it 1 per unique wallet address people would just make multiple wallets. I get someone could still submit hundreds of transactions to get them all, it’s an unsolvable problem in that way. The point is not to leave the cookie jar both open AND on the counter.

Thanks for reading!


@TO1 yeah it is def one of the pain points of Dispensers.

In the spirit of Ordinals (shared hallucination that sat serial numbers exist), maybe Counterparty could add something to at least taint tokens that were part of a transaction that did not follow the rules of the dispenser. So while those tokens may have been bought and are owned by someone, they will be forever tainted onchain and the application layer can see which tokens are pure and which are tainted and handle accordingly.

The dispenser could include a taint memo or code with the tx.
Some new tooling such as a tainted token tracker would be useful for monitoring the movement of tainted tokens and maintaining the taint as tokens traverse through the network, allowing the application(s) to always handle them in whatever way is suitable.

This might be overkill but generally it is an interesting concept.

However, the use of many wallets/addresses by one individual to get around dispenser rules persists. Adding friction is all we can do.


Dispense BTC

While BTC cannot be escrowed like Counterparty Assets, I would like to propose a way for Dispensers to return BTC to sender automatically in the same way a dispenser automatically sends tokens upon payment.

It is not possible to do this onchain with Bitcoin unless some covenants are used.

I have a specific use case for this that i’m still working through although I cannot say that this functionality would be generally useful but one possibility could be to enable allowlist by using a sat sent to a dispenser as a signal to add the sender address to an allowlist (which effectively is auto-generated via tx history). A token could be returned as a receipt plus the sat refunded. Then, an airdrop could be initiated (dividends feature perhaps) to all who have the receipt token. But the sat, despite being less than a penny, should be returned. The sat itself could be colored (which bleeds into my use case).

Just a conversation starter.



@TO1 the easiest and fairest way to accomplish your airdrop the way you want it is this:

You create 2 tokens.

The first token is the ‘ airdrop voucher’ which people will buy for the cost of 1 TX.

The second one is the ACTUAL token.

Set your unit price to the usual TX fee you expect.

Now you can either make a big multi-send transaction (if that’s supported?) and choose to charge less for 1 unit or you send one unit of your actual token to everyone who got at least 1 token voucher.

You could choose to not tell people about the 2-tiered system making it less likely for someone to pose as multiple people with multiple addresses :wink: and then stealth-airdrop the ‘true’ one to each address holding at least 1. Refund if someone made a mistake and bought multiple if you want to be extra-fair.

In any case, I would love to receive an airdropped unit too :smiley:


1 Like