Chromia
Start Building

18 / 20Module 2: The Unity project

Link the client to the blockchain

This lesson connects your Unity application to the Chromia blockchain through the Postchain client. You will initialize the client and write methods that talk to the Tic Tac Toe game running on-chain.

Installation and setup

Your Unity project needs two dependencies before you can integrate with Chromia: the Postchain client and the FT4 client.

Initializing the client

First, create a client that connects to the Chromia blockchain. You supply the blockchain RID or IID, then configure the client to communicate with the network.

c#
using System.Collections.Generic;using System.Threading.Tasks;using Postchain.Client;public class BlockchainManager : MonoBehaviour{    private ChromiaClient client;    private Buffer blockchainRID = Buffer.From("7d565d92fd15bd1cdac2dc276cbcbc5581349d05a9e94ba919e1155ef4daf8f9"); // Replace with your blockchain RID    async void Start()    {        await InitializeClient();    }    private async Task InitializeClient()    {        // Initialize Client        client = await ChromiaClient.Create("http://localhost:7740", blockchainRID);        Debug.Log("Client initialized");        // Additional initialization logic can be added here    }}

Example: using BlockchainService for connection

The steps below show how BlockchainService links your Unity application to the Chromia blockchain.

  1. Initialize the blockchain client: Call BlockchainService.Initialize() and await it. Check that the HOST and CHROMIA_PORT constants point to your blockchain node.

  2. Register an account: Only the open registration strategy is supported at the moment. OpenStrategyRegisterAccount() performs the registration and, if it succeeds, creates an FT4Connection for you to use afterwards.

  3. Interact with the blockchain: Once the FT4Connection exists, run every further blockchain operation through its CurrentSession. To create a new game, for instance:

    c#
    var transactionReceipt = await _blockchainService.Ft4Connection.CurrentSession.Call(new Operation[] { new("create_game") });

BlockchainService code

c#
public class BlockchainService{    public Ft4Connection Ft4Connection => _ft4Connection;    public string UserAccountId => _ft4Connection != null ? _ft4Connection.CurrentSession.Account.Id : string.Empty;    // The HOST and PORT values should be adjusted based on the blockchain's configuration    private const string HOST = "localhost";    private const int CHROMIA_PORT = 7740;    private ChromiaClient _client;    private Ft4Connection _ft4Connection;    public async Task Initialize()    {        var nodeUrl = $"http://{HOST}:{CHROMIA_PORT}/";        var brid = await ChromiaClient.GetBlockchainRID(nodeUrl, 0);        _client = await ChromiaClient.Create(nodeUrl, brid);    }    public async UniTask<StoredAccountData> OpenStrategyRegisterAccount()    {        if (_client == null)        {            Debug.LogError("ChromiaClient has not been initialized.");            return null;        }        // Generate a random private key        var privateKeyBytes = new byte[32];        RandomNumberGenerator.Create().GetBytes(privateKeyBytes);        var privateKey = Buffer.From(privateKeyBytes);        var userSignature = SignatureProvider.Create(privateKey);        // Create the authorization descriptor with account and transfer flags        var userAuthDescriptor = new AuthDescriptor<SingleSignatureArgs>(            new SingleSignatureArgs            {                Flags = new AuthFlag[] { AuthFlag.Account, AuthFlag.Transfer },                Signer = userSignature.PubKey            }        );        // Register the account using the open registration strategy        var transaction = await Account.Register(_client, userSignature, userAuthDescriptor, RegistrationStrategies.Open);        if (transaction.Status == TransactionReceipt.ResponseStatus.Confirmed)        {            await InitializeFt4Connection(userSignature);            return new StoredAccountData            {                AccountId = _ft4Connection.CurrentSession.Account.Id,                PrivateKey = privateKey            };        }        Debug.LogError(transaction.RejectReason);        return null;    }    /// <summary>    /// Authenticates and initializes an <see cref="Ft4Connection"/> with an existing account.    /// </summary>    /// <param name="privateKey">The private key used to authenticate.</param>    /// <returns>True if the login was successful; otherwise, false.</returns>    public async UniTask<bool> LoginWithExistingAccount(Buffer privateKey)    {        if (_client == null)        {            Debug.LogError("ChromiaClient has not been initialized.");            return false;        }        var userSignature = SignatureProvider.Create(privateKey);        await InitializeFt4Connection(userSignature);        return _ft4Connection.CurrentSession.Account != null;    }    /// <summary>    /// Initializes the <see cref="Ft4Connection"/> with the provided signature provider.    /// </summary>    private async UniTask InitializeFt4Connection(SignatureProvider userSignature)    {        _ft4Connection = await Ft4Connection.Create(_client, userSignature);    }}
  • Initialize(): Connects to the Chromia node at the configured HOST and CHROMIA_PORT.
  • OpenStrategyRegisterAccount(): Creates a new account via the open strategy, then initializes the FT4Connection with that account.
  • LoginWithExistingAccount(): Signs in with a private key you already have and creates an FT4Connection.
  • InitializeFt4Connection(): Builds the Ft4Connection from the SignatureProvider you pass in.

Connecting to the blockchain

To have node URLs resolved for you, connect through the Directory System Chain:

c#
private async Task InitializeClientFromDirectory(){    var client = await ChromiaClient.CreateFromDirectory("http://localhost:7750", blockchainRID);    Debug.Log("Client connected through directory");}

Queries

Reading data from the blockchain means defining the query parameters and then invoking the query method. In Tic Tac Toe, you query the game state and the moves each player has made.

c#
public async UniTask<GameData> GetGameById(int gameId){    return await client.Query<GameData>("get_game_by_id", ("id", gameId));}

Transactions

A transaction consists of operations that you sign with a signature provider. You submit transactions through the CurrentSession of the Ft4Connection, which takes care of authorizing them with the right credentials.

c#
public async UniTask<bool> MakeMove(int gameRowId, int slot){    var transactionReceipt =        await _blockchainService.Ft4Connection.CurrentSession.Call(new Operation[]            { new("make_move", gameRowId, slot) });    if (transactionReceipt.Status is TransactionReceipt.ResponseStatus.Confirmed)    {        return true;    }    Debug.LogError(        $"Could not make move for slot {slot} in game {gameRowId}. Reason: {transactionReceipt.RejectReason}");    return false;}

Error handling

Wrap client calls in try-catch blocks. When something goes wrong, the client throws exceptions such as ChromiaException or TransportException. Plan for failures in transaction signing as well as in communication with the client.

c#
private async Task HandleTransactionAsync(){    try    {        await MakeMove("gameId", 1, 1, 'X');    }    catch (ChromiaException ex)    {        Debug.LogError($"ChromiaException: {ex.Message}");    }    catch (TransportException ex)    {        Debug.LogError($"TransportException: {ex.Message}");    }    catch (Exception ex)    {        Debug.LogError($"Exception: {ex.Message}");    }}
Written for this site from Chromia’s public course. Code samples are the course’s own.