Build a Simple Bitcoin Game

Posted by Tyler Julian

Build a Simple Bitcoin Game

Overview

In this tutorial we'll show you how to build and host a simple game of skill using the two1 libraries where users must answer a trivia question correctly to win bitcoin.

Prerequisites

Install 21

You will need the following items:

  • Either a 21 Bitcoin Computer or 21
  • The latest version of the 21 software, obtained by running 21 update

If you've done all that, you are ready to go. Let's get started!

Step 1: create a simple bitcoin-powered game server

Open up a new terminal window. If you use a 21 Bitcoin Computer, ssh into it:

## Only necessary if you use a 21 Bitcoin Computer
ssh twenty@IP_ADDRESS

Set up a folder to house our app:

mkdir trivia-server

Go to that directory, open a file named trivia-server.py in a text editor, and paste in the following code (also downloadable here):

#!/usr/bin/env python3
import random

from flask import Flask
from flask import request

from two1.wallet import Wallet
from two1.bitserv.flask import Payment

app = Flask(__name__)
wallet = Wallet()
payment = Payment(app, wallet)

question_bank = {
    'Who is the inventor of Bitcoin': 'Satoshi Nakamoto',
    'How many satoshis are in a bitcoin': '100000000',
    'What is the current coinbase reward (in BTC) for mining a block': '12.5'
}

question_list = list(question_bank.keys())


# endpoint to get a question from the server
@app.route('/question')
def get_question():
    return random.choice(question_list)


# machine-payable endpoint that pays user if answer is correct
@app.route('/play')
@payment.required(3000)
def answer_question():

    # extract answer from client request
    answer = request.args.get('selection')

    # extract payout address from client address
    client_payout_addr = request.args.get('payout_address')

    # extract question from client request
    client_question = request.args.get('question')

    # check if answer is correct
    if answer.lower() == question_bank[client_question].lower():
        wallet.send_to(client_payout_addr, 8000)
        return "Correct!"
    else:
        return "Incorrect response."

if __name__ == '__main__':
    app.run(host='::', debug=True)

We're all set! This microserver includes our bitcoin payment processor and a flask route with some simple game logic to handle client requests.

Make sure the server has some bitcoin for payouts by running:

21 status

Now run the following command to start the server:

python3 trivia-server/trivia-server.py

Step 2: create a simple bitcoin game client

Open up a new terminal window. If you use a 21 Bitcoin Computer, ssh into it:

## Only necessary if you use a 21 Bitcoin Computer
ssh twenty@IP_ADDRESS
mkdir trivia-client

Let's import our wallet and a BitTransferRequests client for making bitcoin-enabled HTTP requests in a new file called play.py. Then we'll finish out the file with the code to send the request to the server (also downloadable here):

#!/usr/bin/env python3
from two1.wallet import Wallet
from two1.bitrequests import BitTransferRequests

# set up bitrequest client for BitTransfer requests
wallet = Wallet()
requests = BitTransferRequests(wallet)

# server address
server_url = 'http://[::1]:5000/'


def play():
    # get the question from the server
    response = requests.get(url=server_url+'question')
    question = response.text

    ans = input("Question: {}?\n".format(question))
    sel_url = server_url + 'play?question={0}&selection={1}&payout_address={2}'
    answer = requests.get(url=sel_url.format(question, ans, wallet.get_payout_address()))
    print(answer.text)

if __name__ == '__main__':
    play()

That's it! Run the following code to start the game.

python3 trivia-client/play.py

If you get a question right, the client should win some bitcoin (which will show after they're confirmed on the blockchain) and the server will see its bitcoin buffer decrement.

21 status

If you get the following error message, make sure to run 21 flush to get enough on-chain satoshis for the server. The server may also need to wait for a confirmation before sending a second payment.

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
<title>500 Internal Server Error</title>
<h1>Internal Server Error</h1>
<p>The server encountered an internal error and was unable to complete your request.  Either the server is overloaded or there is an error in the application.</p>

Next Steps

You've learned how to build a very simple game in which someone can win or lose bitcoin. Given these fundamentals, you can extend the code to build a trivia game or other game of skill. Here are some ideas on what to build next:

  • Write a simple 2-player game of skill, like checkers or chess, with a prize for the winner. A full list of abstract strategy games for inspiration is here and here.

  • Learn game theory by implementing one of the famous two-player games. A full list is here.

  • Extend this example by creating a database of trivia questions on different topics. You can also reuse or modify existing trivia quiz banks like the ones here or here, though make sure that you have the license to these questions!

  • Make this example high performance by replacing the simple Flask server with a proper deployment on the underlying hardware. See this and this for more information.

If you build anything like this and want to earn some bitcoin for your efforts, write it up and submit it as a bitcoin tutorial. If we decide to publish it on our site, you'll win $200 in BTC!

You can also come to our Slack channel at slack.21.co to find other 21 users to play your game and give feedback. We look forward to seeing you there!


How to send your Bitcoin to the Blockchain

Just as a reminder, you can send bitcoin mined or earned in your 21.co balance to the blockchain at any time by running 21 flush . A transaction will be created within 10 minutes, and you can view the transaction id with 21 log. Once the transaction has been confirmed, you can check the balance in your bitcoin wallet from the command line with wallet balance, and you can send bitcoin from your wallet to another address with wallet sendto $BITCOIN_ADDRESS --satoshis $SATOSHI_AMOUNT --use-unconfirmed. The --satoshis flag allows you to specify the amount in satoshis; without it the sendto amount is in BTC, but this behavior is deprecated and will be removed soon. The --use-unconfirmed flag ensures that you can send even if you have unconfirmed transactions in your wallet.


Ready to sell your endpoint? Go to slack.21.co

Ready to try out your bitcoin-payable server in the wild? Or simply want to browse and purchase from other bitcoin-enabled servers? Head over to the 21 Developer Community at slack.21.co to join the bitcoin machine-payable marketplace hosted on the 21 peer-to-peer network.