Learn to use Unity and Smart Contracts
Search
Generic filters

Moralis Projects – Interact with a Smart Contract from Unity

In this week’s Moralis Project we’ll learn how to interact with a Smart Contract from Unity! Using Moralis will make this super fast and simple. 😄

New Moralis Projects drop each Saturday, so make sure to join the Moralis Discord server in order to take part in the challenges! Join in each week to build a killer Web3 portfolio, and bag yourself an exclusive builder’s NFT too.

Let’s get started!

First, we’ll take a general look through the project so you can see the big picture, then dive into the specifics – deploying the smart contract using Hardhat, and calling a function of that contract from Unity. We’ll also learn how to listen to the contract event in Unity.

Finally, we’ll build the project for WebGL. Enjoy!

PRE-REQUISITES

GETTING STARTED

Clone the youtube-tutorials GitHub Repository:

git clone https://github.com/MoralisWeb3/youtube-tutorials.git

Once downloaded, navigate to the unity folder and you’ll find all the unity tutorials. Open unity-web3-smart-contracts with Unity Hub, and you’re ready to go!

VIDEO STRUCTURE

Alright! Let’s summarize the video structure:

  1. First, we’re gonna set up a Moralis Dapp and get the credentials we need to log into Web3
  1. Second, I’m gonna show you how the project is structured so you have a good overview before going into the specific features
  1. Then, using Hardhat we will deploy the smart contract which will contain the “openGates” function
  1. After that, we will learn how to interact with the contract from Unity and listen to the events
  1. Finally, we’ll learn how to build the project for WebGL

1. Setup Moralis Dapp

If you open the Unity project, the first thing that you’ll find is the Moralis Web3 Setup panel:


First up, let’s follow the instructions below the input fields. Go to https://admin.moralis.io/login and log in (sign up if you’re not already registered), then click on Create a new Server:

Next, click on Testnet Server.

Set your server name and your closest region. Now, choose Polygon (Mumbai), as we’re going to be deploying the smart contract to this chain. Finally, click on Add Instance:

The server (Dapp) will now be created!

If you click on View Details, you can find the Server URL and the Application ID. Copy the Server URL, then the Application ID:


Now paste them to the Moralis Web3 Setup panel input fields:


If you close the panel by accident, don’t panic. You can find it in the top toolbar under Window → Moralis → Web3 Unity SDK → Open Web3 Setup.

Now hit Done. Your Moralis Server is set up. Nice!

Finally, we need to add the server (Dapp) information: in the Assets project tab go to Moralis Web3 Unity SDK → Resources and select MoralisServerSettings:

2. Project structure overview

Start off by heading to Assets → _Project.

Here, you’ll find all the assets I created for this particular project, including the scripts and Main Scene. Go to the Main Scene (if you’re not already there), and take a look at the Hierarchy:

As you can see, we’re using the new AuthenticationKit that’s now available thanks to my colleague Sam and the Moralis Unity SDK team (amazing work guys!).

You can find a specific scene showing its functionality under SamplesMoralis Web3 Unity SDKCurrent versionAuthenticationKit:

The AuthenticationKit is a super powerful tool. It can handle the authentication on any platform that we choose to build on with Unity. You can find out exactly how it works by checking out Sam’s video:

https://www.youtube.com/watch?v=3Mw1tDu9gak&t=2s

For now, all you need to know is that the AuthenticationKit has some events you can subscribe to. When it connects or disconnects, for example, we’re going to execute this:

We’ll go deeper into this later, but as you can see we’re basically calling GameManager functions. This is the main script of this project. It takes care of communicating with the smart contract and activates or deactivates these panels depending on the state.

For now, let’s hit Play and see if we can log in. Make sure to have the Mumbai Testnet selected on your MetaMask mobile, topped up with some test Matic. You can get free Testnet MATIC tokens by following this guide.

Click on CONNECT, scan the QR code and you should be logged in:

3. Deploy Smart Contract

Before going deeper into the GameManager, let’s deploy the smart contract that we will be interacting with.

Remember, you need to have MetaMask installed on your browser too, with the Mumbai Testnet imported and with some test MATIC in it. Here’s the guide on how to get free testnet MATIC again.

Next, you need to make sure Node.js is installed before continuing:
https://nodejs.org/en/download/

Alright, now let’s get into it!

Create a folder in your desktop. I’m going to name mine “MoriaGates-Hardhat”, but you can call it whatever you like. Open Visual Studio Code, then open the folder that we just created:


Now we’re going to execute some hardhat commands! Don’t worry, I’ve got some instructions ready for you to make it easy.

Start by going to Unity. Under _Project → SmartContract you’ll find the instructions, along with some other files we’ll need later.

The INSTRUCTIONS.txt are there for you to refer back to whenever you need. Let’s follow them now.

Open the terminal in VS Code, and make sure you’re under the Moria-Hardhat folder. If not, you can move to the desired folder through the cd command.

Now let’s install hardhat by executing these two commands, one after the other:

npm i -D hardhat
npx hardhat

When executing the second command, you’ll need to select Create a basic sample project and hit enter multiple times:


Congrats, you’ve now installed Hardhat and created a basic sample project:


Great! Now it’s time to install the dependencies. Execute all these commands one after another:

npm i -D dotenv
npm i -D @nomiclabs/hardhat-etherscan
npm i -D @nomiclabs/hardhat-waffle
npm install keccak256

Once the dependencies are installed, we need to replace some of the newly created files with the files from the Unity folder under Assets → _Project → SmartContract

Let’s start by replacing the Greeter.sol, which is the sample smart contract that comes with the basic Hardhat project for the MoriaGates.sol.

You can replace the code from MoriaGates.sol to Greeter.sol and then rename it as MoriaGates.sol (or just replace the whole file). Under contracts, just delete Greeter.sol and add the MoriaGates.sol file:

As you can see, MoriaGates.sol has an event called CorrectPassword, a bytes field called magicPassword and an owner address.

In the constructor, we can see that when we deploy the contract, it will need a bytes32 parameter that will be saved as the magicPassword and the owner will be the wallet that deploys it:

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.7;
contract MoriaGates {
    event CorrectPassword(bool result);
    bytes32 private _magicPassword;
    address owner;
    constructor(bytes32 magicPassword) {
        _magicPassword = magicPassword;
        owner = msg.sender;
    }

Now let’s find the OpenGates function, which is the one we’ll call from Unity.

It needs a string parameter, and we’ll make it public without requiring being an owner. This is because we want to call this function from our mobile MetaMask wallet, which won’t be the one deploying the contract. This also means it is NOT a production-ready contract, so keep that in mind!

Here’s how we do it:

function openGates(string memory password) public {  
        //DISCLAIMER -- NOT PRODUCTION READY CONTRACT
        //require(msg.sender == owner);
        if (hash(password) == _magicPassword)
        {
            emit CorrectPassword(true);
        }
        else
        {
            emit CorrectPassword(false);
        }
    }  
    function hash(string memory stringValue) internal pure returns(bytes32) {
        return keccak256(abi.encodePacked(stringValue));
    }
}

Ok! This function converts the string parameter that will come from Unity to a hash using the hash function and compare it to the magic password. We’ll then trigger the CorrectPassword event passing a true or false value depending on if the password is correct or not.

Now it’s time to replace the sample-script.js under scripts for the deploy.js under the Unity folder under Assets → _Project → SmartContract:

This is the script that we’ll execute through a command later to deploy the MoriaGates.sol contract, so that’s exactly what it does. First, we’re hashing a string parameter that will be the magicPassword when the contract is constructed. In this case, I used “Mellon” which is the elvish word for “Friend”:

const hre = require("hardhat");
async function main() {
  const hashing = require('keccak256');
  var hashedPassword = hashing('Mellon');

Then we deploy the contract passing this hashed password:

  const MoriaGates = await hre.ethers.getContractFactory("MoriaGates");
  const moriaGates = await MoriaGates.deploy(hashedPassword);

After that, we wait for the contract to be deployed so we can finally verify it, and see the whole code and events on PolygonScan:

  await moriaGates.deployed();
  console.log("Contract address: ", moriaGates.address);
  console.log("Hashed password: ", hashedPassword);
  await moriaGates.deployTransaction.wait(5);
  // We verify the contract
  await hre.run("verify:verify", {
    address: moriaGates.address,
    constructorArguments: [
      hashedPassword,
    ],
  });
}
// We recommend this pattern to be able to use async/await everywhere
// and properly handle errors.
main()
  .then(() => process.exit(0))
  .catch((error) => {
    console.error(error);
    process.exit(1);
  });

Great! Now it’s time to create a .env file, so we can fill it with some credentials that we need to deploy and verify the contract. You could create the file, but for now, you can just copy it from the Unity folder Assets → _Project → SmartContract. Copy it to the root of MoriaGates-Hardhat:

We’ll start by filling POLYGON_MUMBAI which needs to be the RPC Node URL of the Mumbai Testnet. Head to the Moralis Admin Panel (https://admin.moralis.io/servers), where we created the server, then go to Speedy Nodes Polygon Network Endpoints and copy the Mumbai one:

Paste it on POLYGON_MUMBAI under .env and it should look like this:

Next, let’s enter the API_KEY.

This needs to be the PolygonScan API key, so go to PolygonScan and create an account if you don’t have one. Then, under “YourAccountName” → API Keys you can create the API Key you need.

Once you’ve got the API Key, copy it to the .env file:

Finally, we need to add the PRIVATE_KEY, which is the private key of your browser MetaMask wallet.

REMEMBER: Never give your private key to anybody!!

Check out this blog on how to get your private key. Once you have it, paste it into the .env file:

Alright! The last thing we need to do before deploying the contract is to replace the hardhat.config.js file with the one under our Unity folder. Do that, and you’ll see it in the module.exports section we use the fields that we just filled on the .env file:


Now it’s time to deploy the contract! We just need to run these commands one after another:

npm hardhat clean
npm hardhat compile
npx hardhat run scripts/deploy.js –network mumbai

And voilà! After a minute or so, we have our MoriaGates.sol contract deployed and verified! If we copy the contract address that appears as a log in the terminal and paste it on PolygonScan we should see the contract there:


4. Unity & Smart Contract interaction

As mentioned earlier, GameManager.cs is the main script in this project.

It takes care of the interaction with the contract. Open it, and you’ll see that it needs the contract address and the contract ABI, so let’s add that in:

Take the deployed contract address and paste it under ContractAddress. For the ContractAbi, go to PolygonScan, search for your contract address and under Contract → Code you will find the ABI, which looks like this:


Now, before pasting the value in GameManager.cs, we need to format it.

Head to https://jsonformatter.org/. Paste the ABI on the left side, then click on Minify/Compact:

Next, click on the right side, press Ctrl + F and type

We need to replace for \”

Click on All to replace it in all the text:


 Ok, now copy the formatted ABI, go back to GameManager.cs, and paste it into ContractAbi:


Great job! 

Before continuing with the GameManager, we need to set up something very important in the Moralis Admin Panel, which is listening in to the CorrectPassword event of the contract.

Go to the Admin PanelView DetailsSyncAdd New SyncSync and Watch Contract Events

Here’s a full guide on how to sync and index smart contract events, but basically these are the values you need to fill in for our contract:

  • ChainId Select Mumbai
  • Description Any description you want
  • Sync_historical False
  • Topic CorrectPassword(bool)
  • Abi {“anonymous”:false,”inputs”:[{“indexed”:false,”internalType”:”bool”,”name”:”result”,”type”:”bool”}],”name”:”CorrectPassword”,”type”:”event”}
  • Address Your contract address
  • Filter Nothing (leave it empty)
  • TableName MoriaGatesEvent

Click on confirm when you’re ready, and your database will be updated with a new MoriaGatesEvent object, created every time the contract emits the CorrectPassword event:


Now go to the beginning of GameManager.cs, and you’ll see we have a MoralisObject called MoralisGatesEvent.

We’ll get notified in Unity whenever a new MoriaGatesEvent gets created in the database, thanks to the SubscribeToDatabaseEvents() function:


private async void SubscribeToDatabaseEvents()

{

   

_getEventsQuery = await Moralis.

GetClient

().Query<MoriaGatesEvent>();
   _queryCallbacks = new MoralisLiveQueryCallbacks<MoriaGatesEvent>();
   _queryCallbacks.OnUpdateEvent += HandleContractEventResponse;
   MoralisLiveQueryController.

AddSubscription

<MoriaGatesEvent>("MoriaGatesEvent", _getEventsQuery, _queryCallbacks);

}

We do that by subscribing to the onUpdateEvent of the queryCallbacks and we call HandleContractEventResponse() which basically activates the right UI panel based on if we guessed the correct password:


private void HandleContractEventResponse(MoriaGatesEvent newEvent, int requestId)
{
   if (!_listening) return;
   if (newEvent.result)
   {
       correctPanel.SetActive(true);
       Debug.

Log

("Correct password");
   }
   else
   {
       incorrectPanel.SetActive(true);
       Debug.

Log

("Incorrect password");
   }
   statusLabel.text = string.

Empty

;
   _listening = false;
   StartCoroutine(DoSomething(newEvent.result));
}

Remember that the event CorrectPassword in the smart contract passes a bool, so the MoriaGatesEvent object we receive in Unity, by being subscribed to the onUpdateEvent, also carries this bool value.

Now for the most important part of this tutorial!

How do we send the password that we type in the game to the contract, so it can check if it’s correct or not?

Like this: Go to Unity, hit Play and log in.

You’ll see that the passwordPanel gets activated. This happens because AuthenticationKit calls the StartGame() function in GameManager.cs every time it connects successfully. StartGame() then activates the passwordPanel:


Then, when we click the ENTER button, we call a GameManager.cs function called OpenGates():

OpenGates() calls CallContractFunction() and passes the input field text (the password that we enter) as a parameter:


public async void

OpenGates

()

{

   

statusLabel.text = "Please confirm transaction in your wallet";
   var response = await CallContractFunction(passwordPanel.passwordInput.text);
   if (response == null)
   {
       statusLabel.text = "Contract call failed";
       return;
   }
   statusLabel.text = "Waiting for contract event...";
   passwordPanel.gameObject.SetActive(false);
   _listening = true;

}

And here’s where the Moralis magic comes!

In CallContractFunction(), we create a parameters object with the password entered, a default gas estimate, and we call ExecuteContractFunction() passing the ContractAddress, the ContractAbi, the name of the contract function that we want to call (openGates in this case), the parameters object, and the gas estimate values:


private async UniTask<string> CallContractFunction(string inputPassword)

{

   

object[] parameters = {
       inputPassword
   };
   // Set gas estimate
   HexBigInteger value = new HexBigInteger(0);
   HexBigInteger gas = new HexBigInteger(0);
   HexBigInteger gasPrice = new HexBigInteger(0);
   string resp = await Moralis.

ExecuteContractFunction

(

ContractAddress

, 

ContractAbi

, "openGates", parameters, value, gas, gasPrice);
   return resp;

}

And just like that, we will be calling the openGates() function in our deployed contract. The contract will emit the CorrectPassword event which we will listen to in Unity, and we have the ability to do whatever we want depending on that. Nice!

5. Build the project in WebGL

Now it’s time to test this on WebGL. On the top toolbar go to File → Build Settings and switch to WebGL platform:


After that, make sure you have the Main scene added to Scenes In Build and click on Build And Run. Select a folder and wait for the build process to end:


Keep in mind building a Unity project to WebGL takes some time, especially the first time you build it. After about 5 to 10 minutes you should have it in the browser like so:


You can now try logging in with different passwords and see what you get as a response. Remember that the correct password is Mellon, so type that and wait for the event to emit. Using Mellon you should be getting the CORRECT response:


Congratulations!

You have completed the Unity & Smart Contracts tutorial. Well done! 😀

May 27, 2022
Build Web3 Projects
Level up your web3 development skills by building weekly projects.
Moralis 
Hackathons
Search
Generic filters
NFT Whale Watching Dapp
Related Articles
Become a Web3 Expert
Subscribe to our newsletter and get our E-book Web3 Speed run for FREE