Unity and Ethereum: Why and How

Ethereum has great potential for gaming. In this tutorial you will learn why Ethereum is interesting for you as a game developer.

Version

  • C# 3.5, Unity 2018.2, Unity

You know about Bitcoin, but do you know about its relative, Ethereum, and the potential it offers for gaming?

In this tutorial, you’ll learn why Ethereum is interesting for game developers and how it works from a game developer’s perspective.

By the end of this tutorial, you’ll know:

  • Why the Ethereum network can disrupt the game industry.
  • How the Ethereum network works at a high level, and how you can interact with it.
  • How a Unity game connects to the Ethereum network using the Nethereum library. You’ll see a demo project store and retrieve high-scores from an Ethereum test network.
Note: This tutorial assumes you’re familiar with Unity, and that you have an intermediate knowledge of C#. If you need need some refreshers, check out our other Unity tutorials. Prior knowledge of Ethereum is unnecessary.

Time to get started!

Why Ethereum Is Interesting

So why should you, as a game developer, care about Ethereum? To understand, you need to consider the game ecosystem. In other words, you need to think about how you play games today and how your data is stored.

The Game Ecosystem Today

Ethereum and Unity: Why and How

When you play a game, you generate all types of data. This data includes game progress, achievements, friends lists, items and many other things. Third parties like PlayStation Network, Xbox Live, Steam and many others store this data for you. This data is about you, but you don’t own it. In most cases, the only way to access this data is on the terms and conditions set down by the third party providers. You must also trust, or rather hope, that these same providers don’t get hacked or close up shop, which happens more often than you may realize – especially once they become profitable.

The Game Ecosystem With Ethereum

Ethereum and Unity: Why and How 

The Ethereum network, on the other hand, requires no third party to run or oversee it, and it’s incredibly secure. Also, by storing your gameplay data in Ethereum, you can reclaim ownership of your data.

However, Ethereum isn’t free. Without third parties paying for the costs, gamers will need to pay small fees to the Ethereum network to store their data. Once you understand what Ethereum can offer, you’ll agree this isn’t such a bad deal.

Opportunities In The Game Ecosystem With Ethereum

Ethereum and Unity: Why and How 

Once your gameplay data is in Ethereum and controlled by you, fantastic opportunities arise. Every game, regardless of its platform, has access to your gameplay data. Imagine an Xbox game offering you a free spaceship because you own an item in another game on the PlayStation!

Even more exciting is that, because you own your items, you can trade them for other items across different games and platforms. You can even sell your items for cash without having to get permission from any third party controlling your data (because there is no third party!). Imagine trading that free spaceship with someone for an item they own in another game, on another platform. 

Before learning more about how Ethereum works, you need to get familiar with the demo project.

Starter Project

Download the starter project for this tutorial using the link at the top or bottom of this page.

Open the project in Unity, and open the scene named main, which is located in Assets\RW\Scenes\.

Note: You’ll get some warnings about unassigned fields. For now, you can ignore these; they’ll be gone by the end of the tutorial.

Review the game object hierarchy:

Ethereum and Unity: Why and How 

  • Main Camera: Camera.
  • EventSystem: Handles events and input.
  • GameplayController: All gameplay logic.
  • UI Gameplay: UI for instructions.
  • HighScoreController: All logic relating to high scores and Ethereum. The only editing you’ll do in this tutorial is on the script attached to this GameObject.
  • UI HighScore: UI for the high score timer, scroll view and refresh button.
  • Arena: Gameplay objects.

Press the Play button.

You play as Ether the Elephant. Your goal is to avoid contact with the other animals. The amount of time you avoid them translates to your score.

Looking at the game’s interface, the playing field is on the left; and on the right, there’s an empty high score table and a refresh button that currently does nothing:

screeen01.jpg 

Throughout the rest of this tutorial, you’ll build up the UI items and integrate the game with an Ethereum test network that stores high scores. But first, you must understand how Ethereum works. You also need to get yourself an Ethereum account.

How Ethereum Works

This section explains the Ethereum network and intentionally avoids using technical terms.

Ethereum is young. It first went live in 2015. Its development stage is akin to how the internet was in the early 1990s. Just like the early internet, Ethereum has critics and challenges ahead of it.

Ethereum uses a network of computers linked together over the internet. Each computer is a node. Simple programs run on these nodes, and they are usually written in a language called Solidity. Solidity is a bit like a subset of JavaScript or C#. Learning Solidity is beyond the scope of this tutorial.

The programs run on the nodes inside a virtual machine. A virtual machine is like a standalone operating system that runs inside the main operating system on the node. This virtual machine is an EVM (Ethereum Virtual Machine). The EVM helps to prevent programs from doing bad things like trying to wipe a node’s hard drive. The EVM also provides a standard environment in which programs run. A node might use Windows or Linux as its main operating system, and in either case, will offer the same standardized EVM:

diagram04.jpg 

The programs must be quite simple. They can talk to each other but should not move vast amounts of data or do huge amounts of processing. Suitable candidates are things like recording ownership of assets, voting, auctions or trading. A good rule of thumb is that a program can be about as sophisticated as a good programmable calculator.

The Ethereum network has a “heartbeat” where every 15 seconds or so, all the eligible programs on the network run and the results get stored.

May You Live In Interesting Times

Nothing happens for free of course. The execution of programs costs the person who wants to execute it a tiny fee. These fees get distributed amongst the people running the nodes. The people who run nodes are called miners and earn fees in return for providing their computing power to the network. This is how the Ethereum network sustains itself.

The nodes on the network are all copies of each other. Each node contains the same programs and the same data as every other node. When a program runs, it runs on every node during that heartbeat.

This makes the network remarkably resilient. If multiple nodes go offline, as long as some survived, the network can continue running as usual. However, the most significant benefit of having every node identical relates to trust.

The Trustless Network

The Ethereum network is not owned or run by any one individual or company. The software behind it is open source. Anyone can contribute to the source code, and can download the software and set up a node.

Does this mean you have to trust everyone who joins the network to behave nicely and not to tamper with your program code or program results? The answer is an emphatic “No!”. The Ethereum network guarantees that your programs will run as you wrote them, with no possibility of tampering. It also guarantees that the program results will get stored exactly as your program produced them. This is the killer feature that Ethereum offers!

The detail behind how this trust feature works is where Ethereum becomes complex and is outside the scope of this tutorial. However, the basic idea is that it uses techniques from a branch of mathematics called cryptography, along with some clever algorithms. Part of the activity miners do is to validate that interactions with the network follow the Ethereum rules.

The amazing result is that there is a network of computers run by strangers with no central authority, yet you can trust the network to run your programs exactly as you coded them with no possibility of tampering!

Fees

The final piece to understand is fees. Simple reads of the network are free. Anything that causes a change to the network’s programs or data costs a fee. This fee must get paid for by whoever (or whatever) wants the change. Executing a program costs a fee broadly related to how many CPU cycles it requires and how much persistent data storage it changes.

The fee varies and depends on many factors, but at the time of this writing, it’s a few cents. The network fees that get given to miners are not paid in dollars. Fees get paid in a virtual currency (think “in-game” currency) called Ether. Ether is an integral part of the Ethereum network, and it gets traded for dollars on many online exchanges.

Some Terminology

The above explanation avoided using technical terminology. When you read other material about Ethereum, you’ll need to know these technical terms.

  • The Ethereum is a decentralised network because it has no central server controlling the network.
  • The method by which the miners agree on what the ouput of programs should be is the consensus mechanism.
  • The network stores all of its data and programs in a blockchain which is a special data structure that prevents tampering.
  • Ether is part of a family of virtual currencies called cryptocurrencies.
  • The programs that run on the network are smart contracts or dApps (short for “distributed applications”).
  • The 15 second network “heartbeat” is the block time.

Enough theory! Time to get your hands dirty adding the Nethereum library to the demo project.

Installing Nethereum

Nethereum is an open source .NET library for Ethereum. It allows Unity to communicate with the Ethereum network.

Go to the Releases page of the Nethereum GitHub project and find the section titled 2.2.1 Unity3d. Download the file named Nethereum.Unity.zip

In your project, under Assets\RW\, create a new folder named Plugins. Unzip the zip file, and copy the contents into the newly created folder. Your project should now look like this:

screen02.jpg 

Now you’ll learn about accounts and transactions, and you’ll get yourself some test Ether.

Ethereum Accounts and Transactions

It’s time to go deeper inside the EVMs you saw back in diagram 4. Inside an EVM are lots of objects called accounts. Accounts can execute code, transfer Ether, maintain an internal data store and talk to each other. All accounts have an address, which is a long hexadecimal number uniquely identifying it. All accounts have a private key, which is also a long hexadecimal number. This private key is the password to access that account.

By default, the EVM is lifeless. Nothing happens unless someone sends a transaction. A transaction is like a message to an account to do something, like transfer Ether or execute code. When the message is received, the Ethereum network comes to life and processes that transaction. A long hexadecimal number uniquely identifies transactions.

Getting An Ethereum Account

The easiest way to get set up is to use a browser plugin named MetaMask. MetaMask works with Chrome, Firefox and Opera. It lets you use the web browser to access the Ethereum network. Unfortunately, there is no MetaMask release for Safari, so if necessary, first install Chrome. To install MetaMask, follow the steps at the MetaMask site.

First, choose the browser extension:

metainstall_screen01.jpg

Then, add it to Chrome:

metainstall_screen02.jpg

Next, confirm adding to Chrome:

metainstall_screen03.jpg

A small fox icon will appear in your browser toolbar; click that icon to start MetaMask:

metainstall_screen04.jpg

Decline the chance to try the new MetaMask beta:

Accept the terms and conditions and privacy notices:

metainstall_screen05.jpg

MetaMask uses the word DEN to mean your collection of Ethereum accounts. On the next screen, enter a new password and confirm it:

metainstall_screen06.jpg

If you ever forget the password you just entered, you can enter your seed phrase to restore your accounts. So if you can’t keep your password safe, at a minimum, keep the seed phrase somewhere safe:

metainstall_screen07.jpg

MetaMask is now ready to use, however, it defaults to the live Main Network. There are several test networks; in this tutorial, you’ll use Rinkeby.

Click the network name at the top:

metainstall_screen08.jpg

Choose the Rinkeby network from the list:

metainstall_screen09.jpg

MetaMask creates your first account for you and shows a balance of zero Ether. If you want to rename the account, hover your mouse over the account name and click edit:

metainstall_screen10.jpg

Woo hoo! You now have MetaMask set up and an Ethereum account on the Rinkeby network. It’s time to tell Unity this good news.

Copy your address from MetaMask by clicking on the triple ellipsis and choosing Copy Address to Clipboard:

screen14a.jpg 

In the main scene, find the game object HighScoreController. In the inspector, change Player Ethereum Account to the value you just copied from MetaMask.

screen13a.jpg 

Copy your private key (sometimes abbreviated to PK) from MetaMask by clicking on the triple elipses and choosing Export Private Key:

screen14b.jpg 

MetaMask asks you to confirm your password. At this point, verify you’re on the Rinkeby test network and not the live network:

screen15a.jpg 

Then, copy the private key:

screen16.jpg 

In the main scene, find the GameObject HighScoreController. In the inspector, change Player Ethereum Account PK to the value you just copied from MetaMask.

screen13b.jpg 

Are you ready to get some Ether into your account?

Getting Some Ether Into Your Ethereum Account

On the live Ethereum network, you buy Ether with normal currency, often using online exchanges. Testing software with real money is not a good idea. To get some free Ether into your test account you use a faucet by following these steps:

  1. Copy your address from MetaMask by clicking on the triple ellipsis and choosing Copy Address to Clipboard just like you did above.

    screen08.jpg

  2. Tweet your address like in this example. You can also make a public Facebook post or a public Google Plus post.

    screen07.jpg

  3. Go to the Rinkeby faucet site and paste in the link to the social media post you just made. Use the dropdown on the right of the screen to choose how much Ether you want to receive:

    screen05.jpg 

After a few seconds, you’ll see an acknowledgement:

screen06.jpg 

  1. Wait for another 20 seconds or so, and then check your balance. You can check your balance in MetaMask; it’s the amount of Ether (ETH) at the bottom left here:

    screen09.jpg 

Reading An Account Balance

You are solvent on the test network! Now you will see how Unity can read your balance. In the HighScoreController.cs file, add some additional using statements to the top of the file:

using System.Numerics;
using Nethereum.Hex.HexTypes;
using Nethereum.JsonRpc.UnityClient;

Replace the contents of GetAccountBalanceCoroutine with this code:

public IEnumerator GetAccountBalanceCoroutine()
{
   var getBalanceRequest = new EthGetBalanceUnityRequest(networkUrl);           // 1
   // Send balance request with player's account, asking for balance in latest block
   yield return getBalanceRequest.SendRequest(playerEthereumAccount, Nethereum.RPC.Eth.DTOs.BlockParameter.CreateLatest());  // 2

   if (getBalanceRequest.Exception == null)                                     // 3
   {
      var balance = getBalanceRequest.Result.Value;                             // 4
      // Convert the balance from wei to ether and round to 8 decimals for display                                
      uiTextEtherBalance.text =
        Nethereum.Util.UnitConversion.Convert.FromWei(balance, 18).ToString("n8");    // 5
   }
   else
   {
      Debug.Log("RW: Get Account Balance gave an exception: " + getBalanceRequest.Exception.Message);
   }
}

The numbered notes in the code above show it performing these steps:

  1. The script creates a new Nethereum request passing in the network you are using.
  2. The script sends the request asynchronously, passing in parameters identifying the player’s Ethereum account and saying what block number you want the balance at. You want the latest, most recent block.
  3. The script checks for an error in the call.
  4. The script extracts the balance.
  5. The Ethereum network generally records Ether values in a unit called Wei. It takes a billion, billion Wei to make up one Ether, so you need to do a unit conversion to get the Ether value to display.

Play the scene. Press the Refresh button and wait a few seconds. The balance gets displayed just underneath the high score table:

screen10.jpg

Preparing To Interact With The High Score Contract

Now you’re going to connect the game to a smart contract that records the top 40 high scores. The smart contract is written in the language Solidity.

Your first step is to create a C# wrapper around the Solidity contract to make it easy to interact within your C# code. In your code editor, open the HighScoreContractWrapper.cs file from the Assets\RW\Scripts folder.

The first comment block is the copyright notice. The second comment block you should uncomment. Remove /* on line 30 and */ at the end of the file. Save the file. The end result will be like this:

/*
 * Copyright (c) 2018 Razeware LLC
...
*/
...
using Nethereum.ABI.Encoders;
using Nethereum.ABI.FunctionEncoding.Attributes;
...
   [Parameter("int256", "score", 2)]
   public BigInteger Score { get; set; }
}

To get an idea of how the contract works, you can browse the contract source code. You can see it stores a public array of high scores and exposes a function to receive a new high score value named setTopScore. The C# wrapper HighScoreContractWrapper.cs provides you with a C# method CreateSetTopScoreTransactionInput that you can use to send a new high score to the smart contract.

Note: Understanding the detail behind the C# wrapper script and the smart contract is beyond the scope of this tutorial. See the links at the end of this tutorial if you’d like to learn more.

Go back to editing HighScoreController.cs again. In the global data part near the top of the file, add two new private variables:

private HighScoreContractWrapper scoreContractService;
private HexBigInteger gasLimit = new HexBigInteger(4712388);

The first is a reference to the C# wrapper; the second one represents the most you want to spend on a transaction. The concept of gas is not covered in this tutorial, but you can think of it as Ether.

At the end of Start, add these lines:

// Service for interaction with high score contract
scoreContractService = new HighScoreContractWrapper();

Ethereum makes use of 256-bit integers, which needs a data type not available in Unity as standard. Find the PrettifyScore method, and change its signature to receive a BigInteger instead of an int:

private string PrettifyScore(BigInteger score) ...

Save everything, switch to Unity and make sure the project compiles.

Next, you’ll read the high score contract.

Retrieve High Scores From Ethereum

Switch back to your code editor. Find the method GetHighScoresCoroutine, and replace its body with:

public IEnumerator GetHighScoresCoroutine()
{
   var topScoreRequest = new EthCallUnityRequest(networkUrl);                         // 1
   // Use the service to create a call input
   var countTopScoresCallInput = scoreContractService.CreateCountTopScoresCallInput();
   // Call request sends and yield for response  
   yield return topScoreRequest.SendRequest(countTopScoresCallInput, 
     Nethereum.RPC.Eth.DTOs.BlockParameter.CreateLatest());                           // 2

   // Decode the top score using the service
   var scores = new List<HighScoreDataTypeDefinition>();
   var count = scoreContractService.DecodeTopScoreCount(topScoreRequest.Result);      // 3
   Debug.Log("RW: High Score count: " + count);
   for (int i = 0; i < count; i++)
   {
      topScoreRequest = new EthCallUnityRequest(networkUrl);                          // 4
      var topScoreCallInput = scoreContractService.CreateTopScoresCallInput(i);
      yield return topScoreRequest.SendRequest(topScoreCallInput, 
        Nethereum.RPC.Eth.DTOs.BlockParameter.CreateLatest());
      scores.Add(scoreContractService.DecodeTopScoreDTO(topScoreRequest.Result));
   }

   var orderedScores = scores.OrderByDescending(x => x.Score).ToList();               // 5
   var topScores = "";
   foreach (var score in orderedScores)                                                       
   {
      string playerAddress = PrettifyAddress(score.Addr);
      string playerSCore = PrettifyScore(score.Score);
      topScores = topScores + playerSCore + " : " + playerAddress + Environment.NewLine;
   }
   uiTextHighScores.text = topScores;
}

The code performs these steps:

  1. The script creates a new Nethereum request.
  2. The script sends the request asynchronously, passing in parameters identifying the smart contract method we want to call.
  3. The script checks to see how many top scores there are.
  4. The script extracts details for each top score one at a time.
  5. The script sorts the score and makes each high score entry a pretty format to display on screen.

Play the scene, press refresh, wait a few seconds and the list of high scores appears:

screen_refresh_01.jpg

Write High Score to Ethereum

Return to your code editor, find the method SubmitHighScoreCoroutine, and replace its body with:

public IEnumerator SubmitHighScoreCoroutine()
{
   // Create the transaction input with encoded values for the function      
   var transactionInput = scoreContractService.CreateSetTopScoreTransactionInput(playerEthereumAccount, contractOwnerAddress, contractOwnerPK, aliveTimeMilliSeconds, gasLimit);

   // Create Unity Request with the private key, url and user address       
   var transactionSignedRequest = new TransactionSignedUnityRequest(networkUrl, playerEthereumAccountPK, playerEthereumAccount); // 1

   // Send request and wait
   yield return transactionSignedRequest.SignAndSendTransaction(transactionInput);

   if (transactionSignedRequest.Exception == null)
   {
      // Get transaction receipt
      Debug.Log("RW: Top score submitted tx: " + transactionSignedRequest.Result);
   }
   else
   {
      Debug.Log("RW: Error submitted tx: " + transactionSignedRequest.Exception.Message);
   }
}

The above code is similar to what you’ve seen before. It prepares a request, sends it and interprets the results. The comment // 1 shows the notable difference where you use the player private key and address to authorize the sending of a transaction. This spends some of the player’s Ether to pay the miners.

Save and play the scene. Press space to start playing and try to get a good score — at least enough to get you into the top 40. When your elephant dies, wait a few seconds. Then, press the refresh button and wait a few more seconds. If your high score made it into the top 40 it should appear in the list:

screen_refresh_03.jpg

You’ll also notice your Ether balance decreased slightly with the cost of the transaction to submit the high score.

Examining Ethereum High Score Transactions

You can see the status of a transaction by using a block explorer. When the game submits a high score, the console shows a message starting RW: Top score submitted tx: followed by a transaction number:

screen_refresh_02.jpg

You can create a URL with the pattern:
https://rinkeby.etherscan.io/tx/[transaction ID here]

And enter it in a browser to see the transaction status like this.

screen_refresh_05.jpg

Whew! That’s been quite a tour! You have now finished the practical part. The next sections wrap up this tutorial, starting with some opinions about the challenges facing Ethereum in games today.

Challenges Facing Ethereum in Games

Steve Wozniak, one of the founders of Apple, said recently that Ethereum could be as influential as Apple in the long term. Remember this technology is just starting!

The main challenges facing Ethereum as it relates to game development include those listed below.

  • Resistance. You will understand that the encumbents who currently store your gameplay data may be reluctant to see other services get involved.
  • Scaling. Ethereum can cope with around 10 transactions a second. This needs to go higher to allow widespread adoption. Casper aims to introduce proof-of-stake to the Ethereum networking. This could make sharding a reality, helping with the scaling problem.
  • Fees. At the time of writing, fees are around a few cents. This is too expensive for some uses.
  • Public Bugs. Using smart contracts on a public blockchain means that bugs are visible to all but you cannot fix them quickly.
Note: Remember nobody acts as police for the Ethereum network. Ethereum itself is secure, but human mistakes occur. If you send real Ether on the live network by mistake, it’s gone forever.

Where to Go From Here?

Download the completed project from the link below. The art in the project is by Kenny.nl.

Learn More About Ethereum and Solidity

Once you’re done playing with the demo project, you may like to explore deeper into Ethereum.

A good place to start learning about Ethereum and Solidity is its official site. A writer and speaker that I recommend is Andreas Antonopoulos who has a book coming out about Ethereum later in 2018.

Learn More About Nethereum

The Nethereum project is open source. Thanks to Juan Blanco whose advice and demo code inspired the samples here. You can join their Gitter and chat with others about the project.

Get Inspired

Take a look at what others have already done with games and Ethereum for more inspiration:

Games

  • CryptoKitties is like a card trading game where you collect and breed digital cats. This game received lots of press because it was at one time so popular it affected the performance of the whole Ethereum network.
  • CryptoCuddles is a card battle game built on top of the CryptoKitties game. You can battle with kitties that you’ve bred in CryptoKitties. This is because the CryptoKitties smart contracts are open for any other developer to use. Very cool!
  • ChainMonsters is very interesting, it is a bit like Pokémon on Ethereum with smart contracts publicly visible.

Services

  • uPort is a project for managing people’s Ethereum identities. uPort will make it easier to use the network without having to enter a long private key.
  • GamerToken wants to be a common in-game currency that any game can use.
  • Ownage wants to be an in-game item trading platform.

We hope you have enjoyed the tutorial, if you have any questions or comments, please join the discussion below.

Contributors

Comments