.NET Core+Ganache调用合约Payable函数报错:eth_feeHistory不支持
问题:调用Payable合约方法时抛出
eth_feeHistory不支持异常 我用.NET Core开发Web3分布式应用,测试阶段采用Ganache私链。通过Nethereum的Web3对象调用已部署智能合约时,查询函数getCount可正常返回结果,EstimateGasAsync也能正常执行,但调用Payable函数addNewRecords的SendTransactionAndWaitForReceiptAsync方法时,抛出RpcResponseException: Method eth_feeHistory not supported.: eth_feeHistory异常。
.NET Core相关代码
var contractAddress = "0x5c2d640027901a19B94ee0f9EEFFdc1cB660898a"; var abi = @"[{"inputs": [],"stateMutability": ..... Complete ABI"; var contract = web3.Eth.GetContract(abi, contractAddress); var getFunction = contract.GetFunction("getCount"); var addfunction = contract.GetFunction("addNewRecords"); // 我的账户地址 var senderAddress = account.Address; // 此方法正常运行 var result_1 = await getFunction.CallAsync<int>(); // 此方法正常运行 var gas = await addfunction.EstimateGasAsync(senderAddress, null, null, "Umer", "FAll2022", "umar@gmail.com"); // 此处抛出异常 var result = await addfunction.SendTransactionAndWaitForReceiptAsync(senderAddress, gas, null, null, "Umer", "FAll2022", "umar@gmail.com");
Solidity合约代码
function addNewRecords(string memory _name, string memory _email, string memory _rollNumber) public payable returns(bool) { // 计数加1 stdCount = stdCount + 1; // 存储学生信息 std_Records[int(stdCount)] = Student(_name,_email,_rollNumber); return true; } function getCount() public view returns(uint){ return stdCount; }
完整错误栈
RpcResponseException: Method eth_feeHistory not supported.: eth_feeHistory Nethereum.JsonRpc.Client.ClientBase.HandleRpcError(RpcResponseMessage response, string reqMsg) Nethereum.JsonRpc.Client.ClientBase.SendInnerRequestAsync<T>(RpcRequestMessage reqMsg, string route) Nethereum.JsonRpc.Client.ClientBase.SendRequestAsync<T>(RpcRequest request, string route) Nethereum.RPC.Fee1559Suggestions.TimePreferenceFeeSuggestionStrategy.SuggestFeesAsync() Nethereum.RPC.Fee1559Suggestions.TimePreferenceFeeSuggestionStrategy.SuggestFeeAsync(Nullable<BigInteger> maxPriorityFeePerGas) Nethereum.RPC.TransactionManagers.TransactionManagerBase.SetTransactionFeesOrPricingAsync(TransactionInput transaction) Nethereum.Web3.Accounts.AccountSignerTransactionManager.SignTransactionRetrievingNextNonceAsync(TransactionInput transaction) Nethereum.Web3.Accounts.AccountSignerTransactionManager.SignAndSendTransactionAsync(TransactionInput transaction) Nethereum.Web3.Accounts.AccountSignerTransactionManager.SendTransactionAsync(TransactionInput transactionInput) Nethereum.RPC.TransactionReceipts.TransactionReceiptPollingService.SendRequestAndWaitForReceiptAsync(Func<Task<string>> transactionFunction, CancellationToken cancellationToken) BlockChainAppWeb.Controllers.HomeController.IndexAsync(Category c) in HomeController.cs + var result_2 = await addfunction.SendTransactionAndWaitForReceiptAsync(senderAddress, gas, null, null, "Umer", "Farooq", "Abc"); Microsoft.AspNetCore.Mvc.Infrastructure.ActionMethodExecutor+TaskOfIActionResultExecutor.Execute(IActionResultTypeMapper mapper, ObjectMethodExecutor executor, object controller, object[] arguments) System.Threading.Tasks.ValueTask<TResult>.get_Result() System.Runtime.CompilerServices.ValueTaskAwaiter<TResult>.GetResult() Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeActionMethodAsync>g__Awaited|12_0(ControllerActionInvoker invoker, ValueTask<IActionResult> actionResultValueTask) Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeNextActionFilterAsync>g__Awaited|10_0(ControllerActionInvoker invoker, Task lastTask, State next, Scope scope, object state, bool isCompleted) Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Rethrow(ActionExecutedContextSealed context) Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Next(ref State next, ref Scope scope, ref object state, ref bool isCompleted) Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeInnerFilterAsync>g__Awaited|13_0(ControllerActionInvoker invoker, Task lastTask, State next, Scope scope, object state, bool isCompleted) Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeNextResourceFilter>g__Awaited|25_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, object state, bool isCompleted) Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Rethrow(ResourceExecutedContextSealed context) Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Next(ref State next, ref Scope scope, ref object state, ref bool isCompleted) Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeFilterPipelineAsync>g__Awaited|20_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, object state, bool isCompleted) Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeAsync>g__Awaited|17_0(ResourceInvoker invoker, Task task, IDisposable scope) Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeAsync>g__Awaited|17_0(ResourceInvoker invoker, Task task, IDisposable scope) Microsoft.AspNetCore.Routing.EndpointMiddleware.<Invoke>g__AwaitRequestTask|6_0(Endpoint endpoint, Task requestTask, ILogger logger) Microsoft.AspNetCore.Authorization.AuthorizationMiddleware.Invoke(HttpContext context) Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.Invoke(HttpContext context)
解决方案
异常核心原因是Ganache默认不支持EIP-1559标准的eth_feeHistory RPC方法,而Nethereum新版本默认使用EIP-1559的费用策略发送交易,导致调用了Ganache不支持的方法。
方法1:禁用EIP-1559,使用传统Gas价格模式
可以通过两种方式实现:
- 创建Web3实例时指定使用传统交易管理器:
var web3 = new Web3(account, "http://localhost:7545", new LegacyTransactionManager()); - 发送交易时手动指定GasPrice:
var gasPrice = await web3.Eth.GasPrice.SendRequestAsync(); var result = await addfunction.SendTransactionAndWaitForReceiptAsync( senderAddress, gas, gasPrice, // 手动传入GasPrice null, "Umer", "FAll2022", "umar@gmail.com" );
方法2:升级Ganache并启用EIP-1559支持
如果需要使用EIP-1559,可升级到最新版Ganache并开启支持:
- 图形界面:在Ganache设置的「Chain」选项中开启「EIP-1559」开关
- 命令行:启动时添加
--eip1559参数,例如ganache --eip1559
修改后重新运行代码,SendTransactionAndWaitForReceiptAsync即可正常发送交易并返回收据。
内容的提问来源于stack exchange,提问作者Umar Farooq
相关产品推荐
相关产品推荐

