reown-com / reown-dotnet

Toolkits to build onchain UX
https://docs.reown.com/
Apache License 2.0
8 stars 1 forks source link

Unity ReadContractAsync returns always null #14

Closed shekaryf closed 1 minute ago

shekaryf commented 3 weeks ago

Here is my solidity code that I deployed:

contract SimpleStorage {
    // Variable to store a string value
    string private storedData;

    // Function to set the data
    function set(string calldata data) external {
        storedData = data;
    }

    // Function to retrieve the stored data
    function get() external view returns (string memory) {
        return storedData;
    }
}

I put a default value(for example 1234) after deployment(get and set worked fine) .

Writing code works successfully without problems but reading is always null My code in unity:


var rrrr = await AppKit.Evm.WriteContractAsync(contractAddress, abi, "set", new BigInteger(3000000), new object[]
{
writeTxt,
});
Debug.Log(rrrr);
//rrrr result is a long hashcode without any error
var txt = await AppKit.Evm.ReadContractAsync<string>(contractAddress, abi, "get");
Debug.Log(txt);
//txt is always null

The result of txt is always null. My network is Sepolia test network Any help? Thanks

skibitsky commented 3 weeks ago

Hello,

When you call ReadContractAsync, the transaction may not yet be included in a block. To check its status, you'll need to track the transaction using the hash returned from WriteContractAsync. I’ll make a note to add a more convenient API for this in the future, but in the meantime, you can use Nethereum to handle it.

var service = AppKit.Evm as NethereumEvmService;
var transactionReceipt = await service.Web3.Eth.Transactions.GetTransactionReceipt.SendRequestAsync("TX HASH");
if (transactionReceipt == null)
{
    // Transaction is still pending, wait and call GetTransactionReceipt again
}
else
{
    // if transactionReceipt.Status == 1, transaction was successful
    // if transactionReceipt.Status == 0, transaction failed
}
shekaryf commented 3 weeks ago

Nope, After a while I checked the transaction and the result is success:

string rrrr = File.ReadAllText(Application.dataPath + "/../wt.txt");//written Writing Hash on  wt.txt
var service = AppKit.Evm as NethereumEvmService;
var transactionReceipt = await service.Web3.Eth.Transactions.GetTransactionReceipt.SendRequestAsync(rrrr);
if (transactionReceipt == null)
{
    Debug.Log("Transaction is still pending, wait and call GetTransactionReceipt again");
    Notification.ShowMessage($"Transaction is still pending, wait and call GetTransactionReceipt again");
}
else
{

    if (transactionReceipt.Status.Value == 1)
    {
        Debug.Log("Transaction Successfully");
        Notification.ShowMessage($"Transaction Successfully");

    }
    else if (transactionReceipt.Status.Value == 0)
    {
        Debug.Log("transaction failed");
        Notification.ShowMessage($"transaction failed");
    }
}
//RESULT is Transaction Successfully

But ReadContractAsync is still null

skibitsky commented 3 weeks ago

I deployed your contract on Sepolia and then used both set and get methods from Unity with the AppKit without any issues.

Calling set

const string contractAddress = "0xfB92950c506749d666abF6f41590898522Ce3E23";

var nethereumSerice = AppKit.Evm as NethereumEvmService;
var contract = nethereumSerice.Web3.Eth.GetContract(SimpleStorageABi, contractAddress);
var function = contract.GetFunction("set");

var transactionInput = new TransactionInput(function.GetData("Hello"), contractAddress);

var gasLimit = await nethereumSerice.Web3.Eth.Transactions.EstimateGas.SendRequestAsync(transactionInput);

var hash = await AppKit.Evm.WriteContractAsync(contractAddress, SimpleStorageABi, "set", gasLimit, "Hello");
Debug.Log(hash);

Calling get

var txt = await AppKit.Evm.ReadContractAsync<string>(contractAddress, SimpleStorageABi, "get");
Debug.Log("Read contract: " + txt);

Could it be that our ABI strings are different? This's the one I used:

public const string SimpleStorageABi = @"[
{
  ""type"": ""function"",
  ""name"": ""get"",
  ""inputs"": [],
  ""outputs"": [
    {
      ""name"": """",
      ""type"": ""string"",
      ""internalType"": ""string""
    }
  ],
  ""stateMutability"": ""view""
},
{
  ""type"": ""function"",
  ""name"": ""set"",
  ""inputs"": [
    {
      ""name"": ""data"",
      ""type"": ""string"",
      ""internalType"": ""string""
    }
  ],
  ""outputs"": [],
  ""stateMutability"": ""nonpayable""
}
]";
shekaryf commented 3 weeks ago

Yes on your deployment works but no mine.

shekaryf commented 2 weeks ago

Can you check with my contract ?:

        const string contractAddress = "0x358AA13c52544ECCEF6B0ADD0f801012ADAD5eE3";

        const string abi = @"[
    {
        ""inputs"": [
            {
                ""internalType"": ""string"",
                ""name"": ""data"",
                ""type"": ""string""
            }
        ],
        ""name"": ""set"",
        ""outputs"": [],
        ""stateMutability"": ""nonpayable"",
        ""type"": ""function""
    },
    {
        ""inputs"": [],
        ""name"": ""get"",
        ""outputs"": [
            {
                ""internalType"": ""string"",
                ""name"": """",
                ""type"": ""string""
            }
        ],
        ""stateMutability"": ""view"",
        ""type"": ""function""
    }
]";
shekaryf commented 2 weeks ago

I tested with a real and old project that worked past(with sepolia and main net) but still ReadContractAsync returns null Here is another contract and abi:


                string abi2 = "[{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_tokenId\",\"type\":\"uint256\"}],\"name\":\"priceOf\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_id\",\"type\":\"uint256\"}],\"name\":\"buy\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"}]";
                string mainContractAddress = "0xb4400849Def8aa7699fe1BA1B151667e71592892";

                string txt = await AppKit.Evm.ReadContractAsync<string>(mainContractAddress, abi2, "priceOf", new object[]
                {
                    "11233100180",
                });
                Debug.Log($"eee Txt: {txt}");
                //txt is null and output is eee Txt:

Thanks if you check with my two contracts

skibitsky commented 2 weeks ago

Can you check with my contract ?

Your contract 0x358AA13c52544ECCEF6B0ADD0f801012ADAD5eE3 doesn't work with the SimpleStorage ABI indeed. I see that there're 22k with the exactly the same bytecode deployed on Sepolia, is that a proxy contract? Could you please share the exact code of 0x358AA13c52544ECCEF6B0ADD0f801012ADAD5eE3?

FYI, for my deployment at 0xfB92950c506749d666abF6f41590898522Ce3E23 I used the following code:

pragma solidity ^0.8.13;

contract SimpleStorage {
    // Variable to store a string value
    string private storedData;

    // Function to set the data
    function set(string calldata data) external {
        storedData = data;
    }

    // Function to retrieve the stored data
    function get() external view returns (string memory) {
        return storedData;
    }
}

I tested with a real and old project that worked past(with sepolia and main net) but still ReadContractAsync returns null Here is another contract and abi

The address you provided 0xb4400849Def8aa7699fe1BA1B151667e71592892 is an EOA, not a contract.

shekaryf commented 2 weeks ago

The contract 0x358AA13c52544ECCEF6B0ADD0f801012ADAD5eE3 doesn't work! you mean It has error; I'm really sure about writing does completely! here is the result of writing:\ 0xe2c3325ea484621fbd8019fa70c7696ffa3b89b435a88966fe2211466209645c photo_2024-11-05_08-43-31

I deployed 0x358AA13c52544ECCEF6B0ADD0f801012ADAD5eE3 on https://remix.ethereum.org/ with something like this:

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

contract SimpleStorage {
    // Variable to store a string value
    string private storedData = "hiword";

    // Function to set the data
    function set(string calldata data) external {
        storedData = data;
    }

    // Function to retrieve the stored data
    function get() external view returns (string memory) {
        return storedData;
    } 
}

Why writing works fine but reading is always null? No Errors!

Oh! I changed the environment with this contract 0xee2e046371F6de73FBFB07581283c8C394042156 on https://remix.ethereum.org/ and reading worked fine! Screenshot 2024-11-05 101307 Why it doesn't throw any error! Thanks

skibitsky commented 2 weeks ago

I think that 0x358AA13c52544ECCEF6B0ADD0f801012ADAD5eE3 isn't a SimpleStorage contract because there's a transaction that calls Attack method that isn't part of the SimpleStorage contract. Maybe you accidentally deployed a different contract?

Oh! I changed the environment with this contract 0xee2e046371F6de73FBFB07581283c8C394042156 on https://remix.ethereum.org/ and reading worked fine!

Good! Did that solve your issue, can you read the value from Unity?

shekaryf commented 2 weeks ago

Yes, I did thanks