2. Creation of the client game functionality in javascript

Javascript is absolutely essential to have an interactive application where users are playing and updating their balances. We’ll use javascript for the following purposes:

To generate encrypted, signed messages with the bets and calls of each player

To exchange messages between players using the real-time socket library

To update the player state after each game

Start by creating an empty game.js file. It will have the functionality of those points above.

These are the main functions that we will develop in a moment:

The functions are explained with comments as you can see. I always recomment programmers to write a small comment on top of the function to clarify what it should do before completing the function.

Which function do you think it’s the most important of those ones?

If you said “placeBet” then you are right. Because that function is the one that will receive the user input, execute the generateHash function and signMessage all in one.

The point is to create a function that will do all the calculations when the user clicks on “Place Bet”. So let’s start by creating that one:

When we place a bet we want to do these things:

First check if the user has enough balance to bet for this game. We use a new function called getGameBalance() which just returns the balance of the current player so if this is the player 1, it will return the balance of the player 1 and the other way around. Below you’ll see those helper functions in detail.

which just returns the balance of the current player so if this is the player 1, it will return the balance of the player 1 and the other way around. Below you’ll see those helper functions in detail. Then we check if the bet in Ether that you’re trying to make, is not exceeding the balance of the other player since it’s him who will pay for the loses.

We then check that the bet is smaller than your escrow.

After that we want to generate a signedMessage() which is just a long string with your bet, your selected dice, your balance, a random number called nonce and a counter called sequence.

We need the nonce to make sure the message is unique to add security to the encryption. The nonce is just a 16 length number.

Then we generate the hash with those parameters. The activeDice variable is a global variable with your selected dice face. Sequence is also a global variable that starts at 1 that we need to identify each game. Since each game needs a counter to know which game we are playing.

variable is a global variable with your selected dice face. Sequence is also a global variable that starts at 1 that we need to identify each game. Since each game needs a counter to know which game we are playing. Then we generate a data object with all the information. This is important because it is what the server will receive. We use the function socket.emit() to send information to the real-time socket server.

to send information to the real-time socket server. Finally we increase the sequence.

That was quite a bit of code! What you see is the completed placeBet() function which could be confusing. If you are creating a similar application by yourself I recommend you to start with the checks at the top, the main code after that and the final changes at the bottom.

You see, each game is just a big javascript object with these parameters:

We need the contract address, the address of both players, the socket IDs which is just an identificator of the player’s computer, the escrows, the balances, a sequence for the game counter, the signed messages with all the encrypted information, the bets, the calls which is just the dice faces selected and the nonces used.

This game object is actually being used in the server. The server will store all the game objects in an array called games = [] . The server is very important since it will work as the container of all the games facilitating the communication between players.

Continuing with what we were doing, these are the helper functions that I used inside the placeBet() function so that you know how they work. They are called helper functions because they don’t do anything by themselves, they just help other functions with key information so that they can work better:

These are pretty straightforward. They just return basic information depending on who’s playing.

After that we have to define some important variables at the start of our file, we’ll need them later for placing bets:

The game object is the same that you saw earlier but it’s empty until the players start playing games. Also the server will store that information. It will act as the main source of data.

Now it comes the important part: the signing and hashing of the information for the state channels.

State channels are based on the fact that you can’t modify encrypted information, basically you take all your parameters and you combine them together in an encrypted string that can only be read by having the original parameters.

In other words, an encrypted string that can be used to see if the parameters originally used are valid.

Let’s say that you have these parameters:

true, false, 2, 5

Those could be the ones defining a game. So when you encrypt them with a special function you get this:

0xlk87afkdsy2b4ky237423sdfdfaidf62343

As you can see it doesn’t make sense, but the data is in there. So how do you know that that string contains those variables? Btw that string is called a “hash”.

Well, you generate another encrypted string with your variables and if it gives you the exact same code, it is valid.

Is this message valid?

0xlk87afkdsy2b4ky237423sdfdfaidf62343

We encrypt these parameters that we got earlier:

Encrypt(true, false, 2, 5)

And if we get 0xlk87afkdsy2b4ky237423sdfdfaidf62343, then the message is valid and the parameters can be trusted. Note that the Encrypt() function doesn’t exist, it’s just pseudocode so that you understand the concept more clearly. The genuine Encrypt() function is generateHash() in our dapp:

Using the ethereumjs library you can generate encrypted hashes. In this case I’m using a random number called nonce, a call, a bet, the balance and the sequence of the game.

That’s how state channels work. You exchange those encrypted messages off-chain for free as long as you want with the updated game information. Because they are encrypted and stored on the server, you can verify that the information is valid.

We also want another extra layer of security. We want to make sure that those hashes are coming from the right user to avoid external people from intefiering in the game.

That’s why we need to sign them. Signing a message is just putting your ethereum address on top. The address of the signer can be extracted later for verification purposes:

With web3.personal.sign you generate signed messages. In this case we are signing the hash with your main address.

You need to do this to gurantee that the hash is coming from the other player and not someone random. It’s the best way to identify information on the blockchain.

We can now place bets with the placeBet function since we have all the required helper functions.

Finally what we need is to communicate with the server to send those messages there, then receive other messages and update the game information. I did exactly that in these functions:

So there’s a start function that initializes the server socket real-time connection and while executing setListeners() , which is the function used to communicate with the server by emmiting and receiving messages. Here’s the breakdown:

When you connect to the server, you emit your address and socket identification to the server so that it says “Ok, I see that you have this address and your computer has this ID, I’ll need that later”

Each message that the server sends to the players can be read with the event listener socket.on(messageName) the message can also include data.

the message can also include data. We need the initial-game-data , error and received-both-messages event listeners. They are basically used to update your local game data and show updated information to the user.

, and event listeners. They are basically used to update your local data and show updated information to the user. Finally I added 2 javascript event listeners for when you click on a dice and when you click on the button ‘Place Bet’ to execute the relevant functions.

Here’s how the entire server file looks like: