private void ContractEventReceived(object sender, EvmChainEventArgs e)
 {
     Debug.LogFormat("Received smart contract event: " + e.EventName);
     if (e.EventName == "OnTileMapStateUpdate")
     {
         OnTileMapStateUpdateEvent onTileMapStateUpdateEvent = e.DecodeEventDto <OnTileMapStateUpdateEvent>();
         Debug.LogFormat("OnTileMapStateUpdate event data: " + onTileMapStateUpdateEvent.State);
     }
 }
        private void EventReceivedHandler(object sender, EvmChainEventArgs e)
        {
            if (e.EventName != "OnTileMapStateUpdate")
            {
                return;
            }

            OnTileMapStateUpdateEvent onTileMapStateUpdateEvent = e.DecodeEventDTO <OnTileMapStateUpdateEvent>();
            JsonTileMapState          jsonTileMapState          = JsonUtility.FromJson <JsonTileMapState>(onTileMapStateUpdateEvent.State);

            this.eventActions.Enqueue(() =>
            {
                TileMapStateUpdated?.Invoke(jsonTileMapState);
            });
        }
    public async void SignIn()
    {
        var privateKey = CryptoUtils.GeneratePrivateKey();
        var publicKey  = CryptoUtils.PublicKeyFromPrivateKey(privateKey);
        var callerAddr = Address.FromPublicKey(publicKey);

        this.statusTextRef.text = "Signed in as " + callerAddr.QualifiedAddress;

        var writer = RpcClientFactory.Configure()
                     .WithLogger(Debug.unityLogger)
                     .WithWebSocket("ws://127.0.0.1:46658/websocket")
                     .Create();

        var reader = RpcClientFactory.Configure()
                     .WithLogger(Debug.unityLogger)
                     .WithWebSocket("ws://127.0.0.1:46658/queryws")
                     .Create();

        var client = new DAppChainClient(writer, reader)
        {
            Logger = Debug.unityLogger
        };

        // required middleware
        client.TxMiddleware = new TxMiddleware(new ITxMiddlewareHandler[]
        {
            new NonceTxMiddleware(publicKey, client),
            new SignedTxMiddleware(privateKey)
        });

        const string abi          = "[{\"constant\":false,\"inputs\":[{\"name\":\"_tileState\",\"type\":\"string\"}],\"name\":\"SetTileMapState\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"GetTileMapState\",\"outputs\":[{\"name\":\"\",\"type\":\"string\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"name\":\"state\",\"type\":\"string\"}],\"name\":\"OnTileMapStateUpdate\",\"type\":\"event\"}]\r\n";
        var          contractAddr = await client.ResolveContractAddressAsync("TilesChain");

        contract = new EvmContract(client, contractAddr, callerAddr, abi);

        // Subscribe to DAppChainClient.ChainEventReceived to receive events from a specific smart contract
        this.contract.EventReceived += (sender, e) =>
        {
            OnTileMapStateUpdateEvent tileMapStateUpdateEvent = e.DecodeEventDto <OnTileMapStateUpdateEvent>();
            Debug.Log(string.Format("Contract Event: {0}, {1}, from block {2}", e.EventName, tileMapStateUpdateEvent.State, e.BlockHeight));
        };
    }