CIP Draft - Instant Lottery

Before I submit the CIP I would like to hear your thoughts

Updated 6/1/2017


Always have an active bet that users can play against and with settlement every few hours.

This is achieved by adding an automated contract addresses…

  • Automated oracle feed that broadcasts a random value based on the blockhash
  • Automated bets placed on “the house” side with a slight edge


Stimulate usage of the Counterparty betting system.

Lotteries will always be available and not require another human to play against, nor a trusted human oracle.

This will solve the chicken-egg problem where no infrastructure, and no usage, has deterred a Counterparty betting ecosystem from developing.

In addition, this proposal will lead to increased demand for XCP from players, and the automated player will accumulate XCP over time, effectively burning it.


The oracle will broadcast a value every 24 blocks (roughly every 4 hours). A wide range of lotteries can be played on this one feed. The probabilites one can play on will be 1/2, 1/4, 1/8, 1/16, etc, up to 1/1,048,576.

The automated player will always bet on the side that gives the lowest payout (and highest probability of winning) in return for a slight edge. This is similar to how the house operates in a casino.

Therefore there will always be an active lottery on Counterparty. A human player only needs to make one bet transaction to participate. Once it confirms it matches instantly, then it takes up to a few hours before the oracle decides the outcome and the protocol pays out winnings.

Economically this will work since many humans, when faced with a potentially high payout, willingly accept a negative expected return. The automated player, on the other hand, will over time accumulate more and more XCP, allowing for larger bets.


The oracle will use a burn address - 1CounterbetXXXXXXXXXXXXXXXXXWhGbTM - the address is valid, yet has no private key.
Every 24 blocks the oracle will broadcast either of the following values (with probabilities):
2 (1/2)
4 (1/4)
8 (1/8)
16 (1/16)
32 (1/32)
64 (1/64)
128 (1/128)
256 (1/256)
512 (1/512)
1024 (1/1024)
2048 (1/2048)
4096 (1/4096)
8192 (1/8192)
16384 (1/16384)
32768 (1/32768)
65536 (1/65536)
131072 (1/131072)
262144 (1/262144)
524288 (1/524288)
1048576 (1/1048576)
1048577 (1/1048576)

The fee will be 0.05% and the time value will be set to the block height (not the block’s timestamp).

The automated player will operate from the same address.
Every 24 blocks the player will place a ‘not equal’ bet on the next broadcast. It will rotate between the values
4, 8, 16, 32, 64, 128, and 1024. It will always wager half its balance but require a counterwager
that gives the human player a 99% expected payout after the fee.

Technical Implementation

For every block, prior to parsing transactions, calculate a = block_height MOD 24

If a = 0 prepare a broadcast.
If a = 1 prepare a bet.

Broadcast will carry parameters source, fee_fraction, text, timestamp, value.

The constant ones are source = 1CounterbetXXXXXXXXXXXXXXXXXWhGbTM, fee_fraction = 0.0005 and text = 'Random'.

The timestamp will be set to the current block_height and the value will be generated as follows:

Find b = block_hash MOD 1048576
If b >= 1048576/2 value = 2
Elseif b >= 1048576/4 value = 4
Elseif b >= 1048576/8 value = 8
Elseif b >= 1048576/524288 value = 524288
Elseif b >= 1048576/1048576 value = 1048576
Elseif b = 0 value = 1048577

The broadcast will be added to the DB as the first transaction of the current block.

Bet will carry parameters source, feed_address, bet_type, deadline, wager_quantity, counterwager_quantity, expiration, target_value, leverage

The constant ones are source = 1CounterbetXXXXXXXXXXXXXXXXXWhGbTM, feed_address = 1CounterbetXXXXXXXXXXXXXXXXXWhGbTM, bet_type = 3, expiration = 22 and leverage = 5040.

The deadline = block_height + 22 and wager_quantity = xcp_balance / 2

The target_value will be set as follows:
Find c = block_height MOD 7
If c = 4 target_value = 4
Elseif c = 0 target_value = 8
Elseif c = 3 target_value = 16
Elseif c = 6 target_value = 32
Elseif c = 2 target_value = 64
Elseif c = 5 target_value = 128
Elseif c = 1 target_value = 1024

The counterwager_quantity is determined the following way:
If target_value = 4 counterwager_quantity = wager_quantity * 0.33761189
If target_value = 8 counterwager_quantity = wager_quantity * 0.14442599
If target_value = 16 counterwager_quantity = wager_quantity * 0.06734949
If target_value = 32 counterwager_quantity = wager_quantity * 0.03257770
If target_value = 64 counterwager_quantity = wager_quantity * 0.01602778
If target_value = 128 counterwager_quantity = wager_quantity * 0.00795018
If target_value = 1024 counterwager_quantity = wager_quantity * 0.00098691

The bet will be added to the DB as the first transaction of the current block.


See further discussions:

Reserving first reply for answering frequent questions and justifying details surrounding the CIP.

Not in this CIP but would be nice …

  • Cheaper, more efficient transaction encoding
  • Support for betting with assets, not just XCP
  • Bets on less/not-less (would enable any probability to be played on)
  • Oracle feed a uniform random value 0-1
  • More frequent oracle feed (maybe every block) - useful for VM contracts

Magic Numbers Should be Debated

  • I chose probabilities 1/2, 1/4, 1/8, etc since they are mathematically “beautiful” but any other set can be chosen as long as they sum to 1. E.g. the following set; 1/2, 1/6, 1/8, 1/10, 1/16, 1/36, 1/100, 1/1000, 1/141.73228 can simulate dice roll, double dice roll, coin flip, triple coin flip, quadruple coin flip and some round number lotteries. The 1/141.73228 case is needed so they sum to 1. Note that when the protocol updates to less/not less (after maybe the next CIP) then the oracle can broadcast a uniform decimal 0-1 and all probabilities can be played on.

  • Similarly, which probabilities should the auto player bet against? I chose the highest to be 1/4. At this probability a miner attack is more expensive than at 1/2, although at 1/2 it is prohibitively expensive anyway. Then it plays on every set up to 1/128 to give wide range of odds and payoffs, and finally 1/1028 just to have one lottery with very high potential payout. Any higher is not practical.

  • A game every 24 blocks (~4 hours) is often enough for there always to be an active game, yet gives enough time for tx to confirm. It’s also set this rare to reduce DB growth. However, it may be worth broadcasting a random number for every block once the VM goes live. It can be used for other contracts too.

  • The fee is set at 0.05%. This means that any game, even those with human-human (it’s not necessary to play against the bot) will have some friction. I chose this partially to make people accustomed to the concept of a fee (more support for raising it later if needed) and partially to prevent miner attack. If the fee were higher it would prohibit games with low probability.

  • The bot plays with half its balance. A higher proportion would give more XCP to play against but would also reduce the XCP amount more whenever the bot loses.

  • 99% expected payout for the player is probably the best in the world! Why not? A slight margin is enough to make the bot’s XCP balance grow.

Understanding the Auto Bet Bot

Initially someone needs to transfer some XCP to the bot address - 1CounterbetXXXXXXXXXXXXXXXXXWhGbTM.

I can do this myself. I’ll transfer a few XCP and start playing. Since it has a small edge, it will accumulate XCP over time.

The bot always takes the side with a large wager relative to the counterwager. E.g. on the 1028x bet, if it wagers 100 XCP, the human on the other side only needs to bet roughly 0.1 XCP.

This will, in the beginning before the bot accumulates more XCP, lead to a shortage of XCP at play. Humans at the other side may be left with unmatched bets that expire.

However, humans can also bet on the same side as the bot; even offer slightly better odds. This is a good thing, as the bot’s role is just to stimulate / kickstart a market. The more humans who play, the more infrastructure that will be deployed.

This is creative and I think it would be used.

I believe it would eventually become profitable for a miner to perform a withholding attack. If the value of the XCP grows somewhere over $100,000 ($200,000?), then I think a miner might start withholding to win a big (1/2) bet. I don’t like the idea that we could be interfering with normal bitcoin blockchain mechanics.

I guess it comes down to whether we want to enhance the protocol in this way. Is this a core feature that we want?

I think it would be interesting to also have an oracle on each block, as there could exist services in the future that could benefit of the added randomness(thinking of randomized contracts).

However, the automated player i don’t quite grasp how it would work, would it need to get xcp deposited to its address to work?

Also, would it be able to bet on any other asset? how about non divisible assets?

@deweller I’ll analyze the economics of miner interference. As with this proposal, I made it more expensive for a miner to do this since the automated player has an edge. But I’ll come up with some maths asap.


  1. Feed on each block would be great, yes. The reason I chose every 24 blocks is to limit DB growth, but I have no idea if that’s a valid concern or not.
  2. Yes, someone needs to send it some XCP initally.
  3. Betting, as it is now, only works with XCP.

Regarding miner manipulation

If a miner finds a losing block, he better withhold it IF the expected XCP payout is more valuable than the BTC block reward.

If the miner has a very high chance of winning (like he risks 97 XCP to profit 3 XCP, i.e. “the house”) then it’s in his best interest to withhold if the XCP is just slightly more valuable than the BTC reward.

If the miner is on the other side of the bet (very low probability of winning) a withholding attack does not make sense. See table below.

Since withholding likely only will happen when the miner has a high probability of winning, and he will only withhold a losing block, a withhold will happen very rare.

See how highlighted cells translate to a negligible 0.8 second expected block delay.

Calculations assume a $30,000 block reward

The CIP outlines an edge to the automated bet address. I see a potential problem and better solution now.

With that small edge, any human party can offer slightly better odds. E.g. the auto address could risk 96 XCP for a 99% chance of a 97 XCP payout (not real numbers, for illustration). Humans could outbid the auto address by risking 96.1 XCP, i.e. offer better odds.

I thought of this as a good way to stimulate investment in infrastructure like bet explorers, wallet support etc.

However, if this attracts miners who are prone to manipulate the probabilities, and if this is the primary concern, a solution may be

  • Place the auto bets at neutral odds (no rational human outbidding)
  • Have the bets and oracle feed come from the same address
  • Have the oracle take a fee, e.g. 3%
  • This fee will accumulate and make for larger bets over time
  • AND the 3% fee will make manipulation even less feasible
  • Not place auto bets on 1/2 and 1/4 (perhaps)

Is there any reason not to make the automatic player place bets for all assets that it holds?

The more I think about this, the more I think it is a really intriguing project idea. But I also think this is a better fit for a smart contract than a core feature of counterparty.

Granted smart contract support might be a loooong ways away…

Only XCP is supported.

If we add support for assets, how will indivisible assets behave? I guess we can test this by betting with a few XCP-satoshis?

Also, should it be possible to wager X amount of asset A against Y amount of asset B?

Another thing - only equal/not-equal bets are enabled. There used to be a larger-than/not-larger-than type for CFDs but it was disabled due to a payout bug. Re-enabling this but with winner takes all can add support for lotteries with any probability. The oracle can then broadcast a uniform random value between 0 and 1.

I did some more (and better, I think) calculations on withholding attack profitability.

The conclusion doesn’t change, so I won’t spam more here, but feel free to study and verify the numbers in another thread.

How do bets with indivisible assets behave now? Are they even supported in Counterparty bets? If not, then the player will just ignore them. If they are supported, then there will probably be a minimum amount (100?) specified by the protocol in order to take a 3% fee.

No. Just wager asset A in order to win asset A. Exchange rates would be way too complicated.

I don’t think any assets are supported. Only XCP.

To anyone interested

Assets are definitely not supported. Only XCP can be used for betting.

If asset betting shall be implemented, one (or two) new parameter(s) must be added to specify asset(s) involved
'bet': ['source', 'feed_address', 'bet_type','deadline', 'wager_quantity', 'counterwager_quantity', 'expiration', 'target_value', 'leverage'],

On the bright side - if we do implement this, I think there won’t be a problem with indivisible assets. And one asset against another shouldn’t add much complexity either.

An example on how it works now is that Alice wagers 10 and demands counterwager 30 on the feed from Oracle A. She’ll win if the value=4 after deadline 25 May 2017 12:00.

Then Bob comes along and wager 30 with counterwager 10 on NOT equal 4 but other parameters are the same.

The protocol matches these two bets, i.e. escrows the amounts, and pays out to the winner after the Oracle’s first broadcast after the deadline. The winner is determined by the broadcast value.

It’s implied that they use XCP for betting.

It shouldn’t be too difficult to add for support any asset, right? And once we’re at that, we can just as well let them specify asset A for wager and asset B for counterwager. If Alice wagers 10 XCP and requires 30 PEPE counterwager, then it will match with Bob’s wager of 30 PEPE against 10 XCP.

The protocol will thus escrow 10 XCP from Alice’s address and 30 PEPE from Bob’s. The winner receives 10 XCP and 30 PEPE.

I found the easiest way to think of betting is as a market (DEX) where odds are equivalent to price

Is this something I should add to this CIP or should I keep the current proposal to auto oracle+bet address only?

IMHO, better to have them on separate cips

I’ve added a Technical Implementation to the draft (see original post).

Here’s justification for my choices

  • prior to parsing transactions … because otherwise the miner who found this block could manipulate the transactions within the block to match / not match bets as he sees fit

  • block_height MOD 24 simply means every 24 blocks

  • a = block_height MOD 24 .. If a = 0 prepare a broadcast. … If a = 1 prepare a bet. … both could maybe be done on the same block, but no harm in waiting one block with placing the bet

  • text = ‘Random’ … didn’t know what to put here but a short text limits DB growth. Can be left empty

  • timestamp will be set to the current block_height … timestamp needs to be an integer to compare times of bets and broadcasts, not any exact times (UNIX timestamp is an integer too, happens to be seconds since 1/1/ 1970). TODO: ensure the blockheight is in allowed range of integers (if not, just add a constant to it)

  • b = block_hash MOD 1048576 … find a random uniform integer in range [0,1048575]

  • If b >= 1048576/2 value = 2 .. Elseif b >= 1048576/4 value = 4 .. etc this ensures each value gets correct probability

  • Elseif b >= 1048576/1048576 value = 1048576 Elseif b = 0 value = 1048577 Both values 1048576 and 1048577 have prob 1/1048576 of occurring

  • Probabilities sum to 1

  • source = 1CounterbetXXXXXXXXXXXXXXXXXWhGbTM, feed_address = 1CounterbetXXXXXXXXXXXXXXXXXWhGbTM TODO: confirm that source and feed can be same address (important for CIP since accumulated fees will be used in bets)

  • bet_type = 3 means NotEqual bet. Must match against a Equal bet (type 2)

  • expiration = 22 if unmatched, can be played on until the last block before broadcast

  • leverage = 5040 is a legacy from CFDs. All bets must have this value

  • deadline = block_height + 22 when the oracle broadcast next block the value will be one higher, thus settle the bet

  • wager_quantity = xcp_balance / 2 as specified in the CIP, bet half the XCP balance

  • c = block_height MOD 7 (runs on every 24 blocks when placing bets)… turns out this equals either 4, 0, 3, 6, 2, 5, 1 periodically in this order. Thus can easily determine which target_value to play on

  • If target_value = 4 counterwager_quantity = wager_quantity * 0.33761189 … is set such that the counterwager has a 99% expected payout. Calculated the following way (1+X)*0.9995*1/4=X*0.99 => X=(0.9995*1/4)/(0.99-0.9995*1/4) where X is the counterwager for each one unit of wager. Replace 1/4 with any probability to find correct counterwager.

  • Example: Bot wagers 100 XCP on value=4. Human’s counterwager is 33.761189 XCP. The total play amount is 133.761189 XCP. The oracle (protocol) takes a 0.05% fee so the payout amount becomes 133.6943 XCP. The human has a 1/4 chance of winning, thus expected payout 1/4 * 133.6943 = 33.42358 XCP. This is exactly 99% of the 33.761189 XCP wagered.

I’m assigning this CIP number 14.

This CIP has been merged in deferred status.

While this proposal is technically well thought out, it carries some liability. The core maintainers do not want to implement this feature at this time.