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
相关产品推荐
相关产品推荐

