ICON Workshop — Blackjack Part 1: SCORE

Apr 16 · 12 min read

In this tutorial we’re going to build one of the most classic casino games — blackjack! This tutorial series is broken down into two parts, part 1 focusing on SCORE development and part 2 focusing on web interface and ICONex integration. At the end of this tutorial series you will have a functional blackjack game on a website, and be able to play the game using IRC-2 tokens on the ICON network!

We’ll be building two SCOREs for this game, one token SCORE to mint our custom IRC-2 token to serve as blackjack chips and allow users to exchange with their ICX tokens. We’ll implement another SCORE to handle the game logic, from room creation to in-game rules etc.

Let’s start off with our custom token contract, recall from the tutorial ICON DAPP From A-Z Part 2: SCORE, we learned that to stay IRC-2 compliant, we must implement these 6 methods: name , symbol , decimals , totalSupply , balanceOf , and transfer.

Let’s first initiate a new SCORE

As usual, this will generate a SCORE skeleton with a dummy hello method. Let’s go right ahead and get the IRC-2 methods implemented.

The above should be fairly straight forward with basic IRC-2 methods defined. We’re only doing the most basic checks during a transfer, to see if balance is enough to make the transfer or if the transaction amount is > 0. We will need a few more functions to make this game work, to mint/burn the blackjack tokens and a bet function to transfer balances for bets.

Here we check to see if the caller is from contract address (in ICON that’d be addresses starting with cx…), and not externally owned account (hx…). For the burn function we’ll do some condition checks before doing the actual burn , in a privately accessed function _burn.

Lastly, we’ll implement a bet function to facilitate and simulate the actual betting action and transfer the balances.

IRC-2 is based on ERC-223 standard (for IRC-2, ERC-20, ERC-223 and rationales behind each standard, please read: https://medium.com/@2infiniti/icon-dapp-from-a-z-part-2-score-af5f627e97e8). The transfer function in ERC-223 checks to see whether the receiving address is a contract, if it is, it will assume there’s a tokenFallback method, let’s define the interface

That’s it, we now have a SCORE that allows minting blackjack chips, burning chips, and facilitating bet actions. Here’s the code in its entirety.

Let’s deploy the SCORE to the bicon testnet.

Fill it with testnet configurations,

Then deploy (note iconkeystore3 is a keystore that we created during past tutorials, you can use any wallet you like, just make sure to fill it with some testnet ICX from

As usual, check to see if transaction was successful

Alternatively you can check this on the live testnet tracker

Let’s also take this opportunity to check out the contract features from our official ICONex Chrome extension

First, launch your ICONex, and under ‘Contract’ tab

paste the SCORE address that you just deployed to the testnet, you should see all the external functions

In the past tutorials, we did JSON-RPC calls from tbears CLI for SCORE quests, which can be a bit of a hassle for simple testing purposes. This built-in contract invocation directly from ICONex makes SCOREs much easier to interact with. Let’s do an experiment, we’ll call the bet function from an EOA (Externally Owned Account), see if that throws an error.

Now let’s sign this transaction

Check the tracker to see if this transaction was successful.

As expected, the transaction responded with an error by our built-in check for CA or EOA. Play with the contract calls and become familiar, you can leverage this feature to save some development time in the future.

We now have a functional IRC-2 SCORE to mint, burn and bet blackjack chips. We’re now ready to develop our game SCORE, which will handle our in-game logic, and the ability to create / leave game rooms.

Initiate a new SCORE template,

For the game SCORE, we’ll divide into different packages,

Let’s start with card.py

A card is simply one suit plus one rank.

Now go into deck directory

A deck has 52 cards, 4 suits and 13 ranks each. We’ll fill the deck with all 52 cards on init and a deal function to randomly draw a card.

Next we’ll implement a hand’s logic

We’ll cover the basic case of a blackjack game, without complex logic from hand splitting, doubling, or buying insurance. We’ll deal with “hitting” only, which is to add cards to your hand.

Ace is a special case where it can have a value of 1 or 11, depending on if your hand is over 21 or not, you can arbitrarily use it as 1 or 11.

Now we have the cards logic defined, let’s create a new class for game rooms, where we can host multiple participants in separate rooms.

For game room, we’ll implement join to join a room, escape to leave a room, game_start to start a game and game_top to stop a game. For the sake of this tutorial, we’ll also fix the ante to a fixed amount per game.

We’ll be creating a web interface for the game in part 2 of this tutorial series, for that we’ll need to implement a few functions to accommodate these front-end features.

Let’s first incorporate the Chip SCORE we implemented earlier, we’ll define an interface (interfaceScore) that contains designated methods of Chip SCORE, enabling our game to use methods without repeat implementations. This is done by recording the chip SCORE’s CA via VarDB and the SCORE address to use when referenced.

We’ll demonstrate how to instantiate a new interface score later. Let’s get the basics down first,

This should be fairly intuitive with SCORE initiation and class variables that we need. Next let’s build some functions relating to game rooms, to show the list of rooms, join and escape, ante size, participants info etc.

Let’s inspect the createRoom function, notice

In this initiation, we used the interfaceScore that maps to the varDB holding our chip SCORE. We can then use the functions implemented in the SCORE, in this case we check requester’s chip balance using chip.balanceOf , without implementing balanceOf again.

we can implement this into an external method to query like so

Rest of the game logic include gameStart that checks to see if the room has been filled or if the caller is in another room. A hit function to simulate hit in a hand, for demonstration purposes we’re fixing this up to 4 hits and the player will simply hold. Finally we need a calculate function to determine the winning logic. There are up to 2 participants per room, so the losing hand will simply transfer to the winning hand based on the fixed ante.

Here’s the entire game.py

Now we’re ready to deploy this to the testnet, we need to pass the _tokenAddress parameter, this would be the CA of the chip SCORE that you deployed earlier. Let’s modify the tbears config file,

Replace the _tokenAddress with your chip SCORE, then deploy

and see if the transaction was successful

Let’s try to run our new SCORE, launch ICONex Chrome and go to ‘Contract’ tab, paste the new SCORE address and you should see the external functions. Let’s experiment mintChips ,

Write the transaction first. Go back to the home screen where your wallets are, click on the far right settings button to add the blackjack token

Input your chip SCORE address, the rest should be auto-filled

Add it to your wallet, and see if the BJC balance is reflected from the mintChips.

Voila, you now have plenty of blackjack chips to start gambling! Feel free to experiment other methods to see if each functions properly.

In this tutorial we implemented two SCOREs, one token contract for the blackjack IRC-2 tokens and another SCORE to build the blackjack game logic. We also learned iconscore_interface in order to re-use SCORE functions, and we learned how to invoke contract calls directly from ICONex to avoid JSON-RPC calls every time. In the next tutorial, we’ll be building a web interface for our game using the Django web framework, and allow users to play the game on a website without worrying about the blockchain technology behind! Players will be able to use their IRC-2 tokens from an ICONex wallet to start betting on the ICON network, stay tuned!

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade