Ethereum Unity3D Boilerplate Questions

@vivraan Okay let me know if I can help. For loading you just need the URL for the file and treat it as loading any other resource file from the web.

Regards,

David

1 Like

Is there a way to integrate provably random algorithm using Moralis? Does the SDK provide some functionality which calls some API serving this?

1 Like

Good question and one I do not have a great answer to. The answer is, it depends on what you want to do with the random number. Nothing in software is every truly random.

If you want to randomly display objects in your game’s worldspace you can get by with any random number generator. If you are drawing cards for a multiplayer game you want something not in the client (you could use a cloud function). If you are securing something or trying to generate secure keys you need a solution that cryptographically sound.

The SDK does not specifically offer this as there are other options already available.

For simple sudo randomness you can always use System.Random. However this is unsecure and not really random.

You may find references to RNGCryptoServiceProvider but this is obsolete.

BouncyCastle (used by Nethererum and Wallet Connect has a random number generator but there is some question about it being a software only solution. It is closer to random than plain System.Random.

.NET provides the RandomNumberGenerator. This is supposed to be cryptographically sound but is platform based. Implementations provided for this abstract class are marked with the UnsupportedOsPlatformsAttribute meaning it may not compile for some platforms.

Software only solutions are sudo random but not truly random. Truly random number generation depends on the introducing entropy which is usually provided by a hardware component.

Since Unity generates device specific builds you will need to explore how to implement secure random number generation for every build target you want to deploy to. iOS and Android both have good security.

You have sparked some curiosity in me to see what I else I can find for Unity on this topic.

Regards,

David

In Unity, we use the Random.Range(x,y) and Random.value methods which generate pseudorandom numbers, but my question wasn’t exactly that. Provable provides a service for generating a random number from a provably random source. I was wondering if Moralis also had something similar, but I’ll rely on simple HTTP requests for this I suppose.

1 Like

What’s the way to send an array of bytes over to a Cloud Function? How will that array be treated in JS, as a regular array or a typed UInt8Array?

1 Like

Sorry for the diversion but can someone please take a look at Moralis Cloud Code and Typescript? I have received no responses or even indications about this.

1 Like

I would think serializing an deserializing a normal array using JSON.serialize should would. You could also convert the array to a Base63 string. I will try.

Sorry some has not gotten back to you, I will take a look.

Regards,

David

1 Like

@vivraan,

From your other post:

I am going to need to try to contact someone else about this.

1 Like

I’m trying to use a Moralis Object to save a highscore and then return a list of highscores; I’m having trouble getting the data to actually save though. I think it might be because the SessionToken is null inside of SaveAsync… everything else seems to work - I am able to get the user, do blockchain transactions etc. Do you have any idea what may be causing the SessionToken to be null?

Here’s my code:


public class MyScores : MoralisObject
{
    public string Name;
    public float Seconds;
}

async void SaveScore(float time)
    {
        var user = await MoralisInterface.GetUserAsync();
        var addr = user.authData["moralisEth"]["id"].ToString();
        var ens = MoralisInterface.GetClient().Web3Api.Resolve.ResolveAddress(addr);
        var score = MoralisInterface.GetClient().Create<MyScores>();
        score.Name = !string.IsNullOrEmpty(ens.Name) ? ens.Name : addr;
        score.Seconds = time;
        await score.SaveAsync();
        Debug.Log("SavedScore");
    }
1 Like

Mea Culpa, looks like I broke this with the last release. I pasted your code into the empty demo and had the same result. Looks like it is not session but ClassName that is not set.

I will open a Issue in GitHub and include this fix in the next release which should be in a couple of days.

This is the fix I am going to post. I think handling at this level instead of outside of the base class will make sure these are always populated properly.

Find Moralis / MoralisDotNet / Platform / MoralisObject.cs. Update the default constructor to:

public MoralisObject()
        {
            this.ClassName = this.GetType().Name;//  String.Empty;
            this.objectId = null; // String.Empty;
            this.createdAt = DateTime.Now;
            this.updatedAt = DateTime.Now;
            this.ACL = new MoralisAcl();
            this.IsDirty = false;
            this.SessionToken = string.Empty;
            this.ObjectService = null;
        }

Regards,

David

Thanks David that seems to have resolved the issue of saving my objects!
I’m having another one now though…
I am trying to query for the top 10 scores in that list using:

        var query = MoralisInterface.GetClient().Query<MyScores>()
            .OrderBy("Seconds")
            .Limit(10);
        var results = await query.FindAsync();

Based on the docs here (Queries - Moralis) I think this should work? In unity however I’m getting an error thrown in MoralisService.BuildQueryString because it’s trying to serialize a “where” parameter that wasn’t specified (tries to convert it to a string)?

I messed around trying to fix it by removing where the “where” parameter gets set in MoralisQuery.BuildParameters which allowed the query to go through to the server, but I am still not getting any response

Another issue: I removed the public read right permissions in my scores table and set “Authenticated” to read/write and when I try to query the scores i get a “Permission denied, user needs to be authenticated.” even though the user is authenticated.

In either case though, when there was an error, FindAsync never returns

1 Like

I will be adding another unity test for this one :slight_smile:

For now find Moralis / MoralisDotNet / Platform / Queries / MoralisQuery.cs.

Find the BuildParameters method. For the first conditional:

            if (Filters != null)
                result["where"] = JsonSerializer.Serialize(Filters);//PointerOrLocalIdEncoder.Instance.Encode(Filters, Services);
            else
                result["where"] = new object();

remove the else statement so the first conditional statement should now be:

            if (Filters != null)
                result["where"] = JsonSerializer.Serialize(Filters);//PointerOrLocalIdEncoder.Instance.Encode(Filters, Services);

Hope that helps,

David

Yup it partially fixes it; The query goes through but it still doesn’t return any rows of data from the server for some reason. Do you see anything wrong with that query?

No. I used it against a table in my DB and it returned all 6 rows (just the table was Hero and I ordered by Level).

Make sure names are the same case and the table exists and has rows. I cannot think of anything else that would cause your code to fail.

Figured it out… the save was setting the ACL as “Master Key Only” - I need to add Public Read permission to retrieve them in my game

1 Like

What’s the method of converting to a base64 in the SDK currently? I’ll try a normal array of bytes.

1 Like

For C# or JS (this is a function in the language, not the SDK)?

1 Like

C# in this case.

In my use case, I’ve encrypted the private key to a wallet as a Moralis Server Config var. The wrapping key is provided in the code and the initialisation vector is supplied by the client. Every time the requested Cloud Function is called, the PK is decrypted, the wallet is added, a transaction is created and signed, and then it is removed.

The IV is meant to be an array of bytes (byte[] in C# or UInt8Array in JS).

Btw can I use crypto.subtle in Moralis Cloud Code?

1 Like

I was able to pass in the array as an array. I had forgotten but internally the Moralis SDK serializes byte[] values as Base64 automatically since the Parse server expects this.

This C# code:

byte[] testArray = { 4, 92, 3, 42, 28, 59, 31, 13 };
IDictionary<string, object> pars = new Dictionary<string, object>();
pars.Add("arr1", testArray);

CloudFunctionResult cfResp = await moralis.Cloud.RunAsync<CloudFunctionResult>("myFunction", pars);

byte[] ba1 = JsonConvert.DeserializeObject<byte[]>(cfResp.a1) as byte[];

Calls the Cloud Function below with a byte[] and processes the result to a byte[].

Moralis.Cloud.define("myFunction", async (request) => {
    var a1 = request.params.arr1;
    var sar = [];
    atob(a1).split("").map(function(c) { sar.push(c.charCodeAt(0));});
    sar = sar.sort();
  	var resp = {a1: JSON.stringify(sar)}; 
  	return resp;
}, {
	fields : ['arr1']
});

and here is the result object:

    public class CloudFunctionResult
    {
        public string a1;
    }

Hope this helps,

David

1 Like

Hi @dgoodrich
I’m getting this error while building WebGL build from unity 2021.2.5f. I followed instructions on Github and created a new project with importing the package.