<p>Real Satoshi dice uses the <a href="https://code.google.com/p/bitcoinj/" rel="nofollow">bitcoinj</a> library. </p>

CC BY-SA 3.0
2013-10-06T19:55:14.717Z
2013-10-06T19:55:14.717Z
yossarian
<p>You could easily write a piece of software that runs on the same machine as a bitcoin daemon and let it use the JSON-RPC API from the local bitcoin daemon.</p>

<p>There are JSON-RPC <a href="https://en.bitcoin.it/wiki/API_reference_%28JSON-RPC%29" rel="nofollow">implementation examples</a> for all popular programming languages like Python and Java.</p>

<p>This piece of software will poll for new transactions, validate them and applying your game rules, and again making new transactions.
Note that a server with such a piece of software needs only to have it's bitcoin port open to the internet, while the RPC port can be limited to local connections for safety.</p>

CC BY-SA 3.0
2013-04-09T05:54:39.677Z
Well, after attempting to implement it through Bitcoin API, I ran into the problem that since 0.8 and the new database system, bitcoind does not have all information on old transactions, so finding out the sender of a given transaction can be problematic.
ThePiachu
CC BY-SA 3.0
2013-04-11T20:24:17.343Z
How is an "old" transaction defined? SatoshiDice acts fast, right? I guess transaction details should be kept several blocks at least, no?
Steven Roose
CC BY-SA 3.0
2013-04-11T22:08:27.447Z
Well, in order to determine the issuing address using the API, you need to look to a transaction previous to the one gambling, which can be arbitrarily old.
ThePiachu
CC BY-SA 3.0
2013-06-08T19:07:28.360Z
You could keep track of previous transactions in a database, and then query that if it's older in the blockchain.
Dominic Tancredi
CC BY-SA 3.0
2013-04-09T00:40:32.833Z
2013-04-09T00:40:32.833Z
Steven Roose
<p>Creating a SatoshiDice-like game is rather easy.  Below are the high level steps involved in making such a game.</p>

<p>For each incoming transaction...</p>

<p><strong>Get the customer amount and payment address</strong>  </p>

<ol>
<li><p>Call <code>bitcoind getrawtransaction [The incoming transaction ID] 1</code>.  The 1 at the end will return the data in "verbose mode", which essentially the raw data in JSON format.</p></li>
<li><p>From the raw transaction details, take the <code>txid</code> and <code>vout</code> from the <code>vin</code> object.  With this transaction, again call <code>bitcoind getrawtransaction</code> on the <code>txid</code>.</p></li>
<li><p>From these raw transaction details find the <code>vout</code> object, referenced by the <code>vout</code> index from step #2.  Within this <code>vout</code> object, there should be a list of payment recipient addresses.  Take and store the first address.</p></li>
</ol>

<p><strong>Determine the Win/Loss state of the round and return the results</strong>  </p>

<ol>
<li><p>Hash the <code>txid</code>+<code>vout</code> index of the transaction.  Seed your hash function with a secret key.  As an aside note, you will need to provide your secret key on a periodic basis.  Without updating and providing your secret keys, there is no way for your players to verify your fairness.</p></li>
<li><p>Compare the last four bytes of your hash to determine the win/loss condition.</p></li>
</ol>

<p><strong>In case of a loss...</strong>  </p>

<ol>
<li><p>Call <code>bitcoind createrawtransaction</code>.  You must pass in the originating <code>txid</code> and <code>vout</code> of your customers payment.  With the customers address, include a small, fractional value to send back to the customer.  This informs them that they've lost the round.  Also, include a second payment address that will receive the remaining portion of bitcoins from the customers originating payment.  This should be an address within your wallet.</p></li>
<li><p>Call <code>bitcoind signrawtransaction</code> to sign the transaction.  If it returns a value of <code>complete=true</code>, your transaction is valid.</p></li>
<li><p>Call <code>bitcoind sendrawtransaction</code> and include the above constructed raw transaction.</p></li>
</ol>

<p><strong>In case of a win</strong></p>

<ol>
<li><p>Calculate the customers winning amount.</p></li>
<li><p>Call <code>bitcoind listunspent</code>.  This will return a list of inputted transactions that have not been spent by your wallet.</p></li>
<li><p>Create a list of transactions to process as payments.  First, include the customer's originating <code>txid</code> and <code>vout</code> index of their payment.  Next, append to the list any number of unspent transactions (from step #1) that are necessary to pay your customer their winnings. </p>

<p>Remember to include an additional payment address that will receive the remaining portion of bitcoins from the final unspent transaction that may contain overages above the player's winnings.</p></li>
<li><p>Call <code>bitcoind createrawtransaction</code>, passing in all of the transactions accumulated in step #3.</p></li>
<li><p>Call <code>bitcoind signrawtransaction</code> to sign the transaction.</p></li>
<li><p>Call <code>bitcoind sendrawtransaction</code> and include the above constructed raw transaction.</p></li>
</ol>

<hr>

<p>That's it!  That's a very simplistic, SatoshiDice processor.  You may want to add more validation, cache your transactions, monitor orphaned blocks and just integrate some other administrative routines.</p>

<p>It is worth mentioning that you always include a portion of the customers original payment with all of your return transactions.  This is because if their payment is orphaned, or is marked as invalid, you want to be sure that your transaction is also removed from the block-chain.  </p>

<p>Using this method you can actually respond near-instantaneously and there is no need for confirmations.  If their transaction is malformed and rejected by the network, your transaction will also be thrown out by the network since it is a child of their original transaction.</p>

CC BY-SA 3.0
2013-12-01T03:09:31.113Z
I guess to get "For each incoming transaction...", you would just call listtransactions?
kristianp
CC BY-SA 3.0
2013-12-04T14:30:11.883Z
Yes, or `listsinceblock`.
RLH
CC BY-SA 3.0
2013-10-25T21:16:47.033Z
2013-10-26T02:52:52.320Z
2013-10-26T02:52:52.320Z
RLH
<p>Everyone knows what SatoshiDice is. Their core mechanic is gambling through the use of Bitcoin transactions with the payout being directly linked to the transaction that fuelled the bed to avoid double-spend attacks. My question is, how to implement such a mechanism? Can it be done in the Standard Client, or does it need some extra software to pick the exact inputs of a transaction?</p>

<client><development><satoshidice><gambling>
How to implement a game like SatoshiDice?
ThePiachu
# How to implement a game like SatoshiDice?

(Asked by: username_0 on 2013-01-30)

Everyone knows what SatoshiDice is. Their core mechanic is gambling through the use of Bitcoin transactions with the payout being directly linked to the transaction that fuelled the bed to avoid double-spend attacks. My question is, how to implement such a mechanism? Can it be done in the Standard Client, or does it need some extra software to pick the exact inputs of a transaction?

**Tags:** client, development, satoshidice, gambling


---

## 3 answers

### Answer by username_4 on 2013-10-25. Score: 8 | Accepted answer

Creating a SatoshiDice-like game is rather easy. Below are the high level steps involved in making such a game.

For each incoming transaction...

**Get the customer amount and payment address**

1. Call `bitcoind getrawtransaction [The incoming transaction ID] 1`. The 1 at the end will return the data in "verbose mode", which essentially the raw data in JSON format.
2. From the raw transaction details, take the `txid` and `vout` from the `vin` object. With this transaction, again call `bitcoind getrawtransaction` on the `txid`.
3. From these raw transaction details find the `vout` object, referenced by the `vout` index from step #2. Within this `vout` object, there should be a list of payment recipient addresses. Take and store the first address.

**Determine the Win/Loss state of the round and return the results**

1. Hash the `txid`+`vout` index of the transaction. Seed your hash function with a secret key. As an aside note, you will need to provide your secret key on a periodic basis. Without updating and providing your secret keys, there is no way for your players to verify your fairness.
2. Compare the last four bytes of your hash to determine the win/loss condition.

**In case of a loss...**

1. Call `bitcoind createrawtransaction`. You must pass in the originating `txid` and `vout` of your customers payment. With the customers address, include a small, fractional value to send back to the customer. This informs them that they've lost the round. Also, include a second payment address that will receive the remaining portion of bitcoins from the customers originating payment. This should be an address within your wallet.
2. Call `bitcoind signrawtransaction` to sign the transaction. If it returns a value of `complete=true`, your transaction is valid.
3. Call `bitcoind sendrawtransaction` and include the above constructed raw transaction.

**In case of a win**

1. Calculate the customers winning amount.
2. Call `bitcoind listunspent`. This will return a list of inputted transactions that have not been spent by your wallet.
3. Create a list of transactions to process as payments. First, include the customer's originating `txid` and `vout` index of their payment. Next, append to the list any number of unspent transactions (from step #1) that are necessary to pay your customer their winnings.

   Remember to include an additional payment address that will receive the remaining portion of bitcoins from the final unspent transaction that may contain overages above the player's winnings.
4. Call `bitcoind createrawtransaction`, passing in all of the transactions accumulated in step #3.
5. Call `bitcoind signrawtransaction` to sign the transaction.
6. Call `bitcoind sendrawtransaction` and include the above constructed raw transaction.

---

That's it! That's a very simplistic, SatoshiDice processor. You may want to add more validation, cache your transactions, monitor orphaned blocks and just integrate some other administrative routines.

It is worth mentioning that you always include a portion of the customers original payment with all of your return transactions. This is because if their payment is orphaned, or is marked as invalid, you want to be sure that your transaction is also removed from the block-chain.

Using this method you can actually respond near-instantaneously and there is no need for confirmations. If their transaction is malformed and rejected by the network, your transaction will also be thrown out by the network since it is a child of their original transaction.

> **Comments:**
> **username_5**: I guess to get "For each incoming transaction...", you would just call listtransactions?  
> **username_4**: Yes, or `listsinceblock`.  

---

### Answer by username_1 on 2013-10-06. Score: 3

Real Satoshi dice uses the [bitcoinj](https://code.google.com/p/bitcoinj/) library.


---

### Answer by username_2 on 2013-04-09. Score: 0

You could easily write a piece of software that runs on the same machine as a bitcoin daemon and let it use the JSON-RPC API from the local bitcoin daemon.

There are JSON-RPC [implementation examples](https://en.bitcoin.it/wiki/API_reference_%28JSON-RPC%29) for all popular programming languages like Python and Java.

This piece of software will poll for new transactions, validate them and applying your game rules, and again making new transactions.
Note that a server with such a piece of software needs only to have it's bitcoin port open to the internet, while the RPC port can be limited to local connections for safety.

> **Comments:**
> **username_0**: Well, after attempting to implement it through Bitcoin API, I ran into the problem that since 0.8 and the new database system, bitcoind does not have all information on old transactions, so finding out the sender of a given transaction can be problematic.  
> **username_2**: How is an "old" transaction defined? SatoshiDice acts fast, right? I guess transaction details should be kept several blocks at least, no?  
> **username_0**: Well, in order to determine the issuing address using the API, you need to look to a transaction previous to the one gambling, which can be arbitrarily old.  
> **username_3**: You could keep track of previous transactions in a database, and then query that if it's older in the blockchain.  

---

