You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Unity集成Solidity合约遇Nethereum库函数未找到错误求助

问题:Nethereum集成Unity时提示「Function not found:setSymbol」

我有一个可通过JavaScript在Ganache上正常交互的Solidity合约,现在想将其集成到Unity中,使用Nethereum库实现交互,但合约与C#代码无法通信,出现「Function not found:setSymbol」错误。以下是相关代码及错误信息:

相关C#代码

using UnityEngine;
using Nethereum.Web3;
using Nethereum.Web3.Accounts;
using Nethereum.Contracts;
using System.Threading.Tasks;
using System.Numerics;
using System.Collections.Generic;
using Nethereum.ABI.FunctionEncoding.Attributes;
using Nethereum.Contracts.CQS;
using Nethereum.Util;
using Nethereum.Hex.HexConvertors.Extensions;
using Nethereum.Contracts.Extensions;
using Nethereum.RPC.Eth.DTOs;
public class AuthSymbolInteraction : MonoBehaviour
{
    public string contractAddress = "0xA295faf8F5c5894DA2e782A4A5a7900B037389ac";
    public string contractABI = @"[
        {
            ""inputs"": [
                {
                    ""internalType"": ""uint256"",
                    ""name"": ""userId"",
                    ""type"": ""uint256""
                },
                {
                    ""internalType"": ""uint256"",
                    ""name"": ""symbolId"",
                    ""type"": ""uint256""
                }
            ],
            ""name"": ""setSymbol"",
            ""outputs"": [],
            ""stateMutability"": ""nonpayable"",
            ""type"": ""function""
        },
        {
            ""inputs"": [
                {
                    ""internalType"": ""uint256"",
                    ""name"": ""userId"",
                    ""type"": ""uint256""
                },
                {
                    ""internalType"": ""uint256"",
                    ""name"": ""symbolId"",
                    ""type"": ""uint256""
                }
            ],
            ""name"": ""checkSymbol"",
            ""outputs"": [
                {
                    ""internalType"": ""bool"",
                    ""name"": """",
                    ""type"": ""bool""
                }
            ],
            ""stateMutability"": ""view"",
            ""type"": ""function""
        },
        {
            ""inputs"": [
                {
                    ""internalType"": ""uint256"",
                    ""name"": ""userId"",
                    ""type"": ""uint256""
                }
            ],
            ""name"": ""userExists"",
            ""outputs"": [
                {
                    ""internalType"": ""bool"",
                    ""name"": """",
                    ""type"": ""bool""
                }
            ],
            ""stateMutability"": ""view"",
            ""type"": ""function""
        },
        {
            ""inputs"": [
                {
                    ""internalType"": ""uint256"",
                    ""name"": """",
                    ""type"": ""uint256""
                }
            ],
            ""name"": ""users"",
            ""outputs"": [
                {
                    ""internalType"": ""uint256"",
                    ""name"": ""userId"",
                    ""type"": ""uint256""
                },
                {
                    ""internalType"": ""uint256"",
                    ""name"": ""symbolId"",
                    ""type"": ""uint256""
                },
                {
                    ""internalType"": ""bool"",
                    ""name"": ""exists"",
                    ""type"": ""bool""
                }
            ],
            ""stateMutability"": ""view"",
            ""type"": ""function""
        }
    ]";

    public uint userId = 3;
    public uint symbolId = 3;
    private async void Start()
    {
        var url = "HTTP://127.0.0.1:7545";
        var privateKey = "my private key";
        var account = new Account(privateKey);
        var web3 = new Web3(account, url);
        var contract = web3.Eth.GetContract(contractABI, contractAddress);
        var setSymbolFunction = contract.GetFunction("setSymbol");
        var checkSymbolFunction = contract.GetFunction("checkSymbol");
        var userExistsFunction = contract.GetFunction("userExists");

        var setSymbolReceipt = await setSymbolFunction.SendTransactionAndWaitForReceiptAsync(web3.TransactionManager.Account.Address, null, null, userId.ToString(), symbolId.ToString());

        Debug.Log("setSymbol Transaction Hash: " + setSymbolReceipt.TransactionHash);

        var checkSymbolResult = await checkSymbolFunction.CallAsync<bool>(userId, symbolId);

        Debug.Log("Symbol Exists: " + checkSymbolResult);

        var userExistsResult = await userExistsFunction.CallAsync<bool>(userId);

        Debug.Log("User Exists: " + userExistsResult);
    }
}

错误栈信息

Exception: Function not found:setSymbol
Nethereum.Contracts.ContractBuilder.GetFunctionAbi (System.String name) (at <6bb0d176930b4bd4876aa91ecbf3c219>:0)
Nethereum.Contracts.ContractBuilder.GetFunctionBuilder (System.String name) (at <6bb0d176930b4bd4876aa91ecbf3c219>:0)
Nethereum.Contracts.Contract.GetFunctionBuilder (System.String name) (at <6bb0d176930b4bd4876aa91ecbf3c219>:0)
Nethereum.Contracts.Contract.GetFunction (System.String name) (at <6bb0d176930b4bd4876aa91ecbf3c219>:0)
AuthSymbolInteraction.Start () (at Assets/Scripts/AuthSymbolInteraction.cs:119)
System.Runtime.CompilerServices.AsyncMethodBuilderCore+<>c.<ThrowAsync>b__7_0 (System.Object state) (at <8f02bdf82edc4309b57af878cc7723ff>:0)
UnityEngine.UnitySynchronizationContext+WorkRequest.Invoke () (at /home/bokken/build/output/unity/unity/Runtime/Export/Scripting/UnitySynchronizationContext.cs:153)
UnityEngine.UnitySynchronizationContext.Exec () (at /home/bokken/build/output/unity/unity/Runtime/Export/Scripting/UnitySynchronizationContext.cs:83)
UnityEngine.UnitySynchronizationContext.ExecuteTasks () (at /home/bokken/build/output/unity/unity/Runtime/Export/Scripting/UnitySynchronizationContext.cs:107)

解决方法

1. 修正ABI加载方式,避免字符串转义问题

当前代码使用多行转义字符串存储ABI,容易出现转义错误。建议将ABI保存为单独的JSON文件(命名为ContractABI.json),放在Unity项目的Resources目录下,然后通过加载文件读取ABI:

// 替换原代码中contractABI的赋值逻辑
TextAsset abiText = Resources.Load<TextAsset>("ContractABI");
string contractABI = abiText.text;

2. 检查合约地址与部署实例的一致性

确保Unity代码中contractAddress和Ganache上部署的合约地址完全一致,复制时注意不要遗漏或多打字符。

3. 修正函数调用的参数类型

调用SendTransactionAndWaitForReceiptAsync时,不需要将uint类型转成字符串,直接传递数值类型(转换为BigInteger适配合约的uint256):

// 修改后的交易发送代码
var setSymbolReceipt = await setSymbolFunction.SendTransactionAndWaitForReceiptAsync(
    web3.TransactionManager.Account.Address, 
    null, 
    null, 
    new BigInteger(userId), 
    new BigInteger(symbolId)
);

4. 验证Nethereum版本兼容性

确保使用的Nethereum版本与编译合约的Solidity版本兼容,建议升级到Nethereum最新稳定版。

5. 确认合约函数签名匹配

可以通过Solidity编译器生成的函数签名验证,setSymbol(uint256,uint256)的签名为固定哈希值,也可以直接通过Ganache的合约详情确认函数是否存在且名称完全一致(注意大小写敏感)。


内容的提问来源于stack exchange,提问作者MissReyyo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.16 01:13:11