Flutter调用startElection函数触发类型转换错误求助
问题:Flutter调用Solidity智能合约时出现类型转换空值异常
在Flutter应用中点击按钮调用startElection函数时,抛出以下错误:
E/flutter (31094): [ERROR:flutter/lib/ui/ui_dart_state.cc(198)] Unhandled Exception: type 'Null' is not a subtype of type 'int' in type cast E/flutter (31094): #0 JsonRPC.call (package:web3dart/json_rpc.dart:53:27) E/flutter (31094): <asynchronous suspension> E/flutter (31094): #1 Web3Client._makeRPCCall (package:web3dart/src/core/client.dart:54:20) E/flutter (31094): <asynchronous suspension> E/flutter (31094): #2 Web3Client.getGasPrice (package:web3dart/src/core/client.dart:175:18) E/flutter (31094): <asynchronous suspension> E/flutter (31094): #3 _fillMissingData (package:web3dart/src/core/transaction_signer.dart:36:16) E/flutter (31094): <asynchronous suspension> E/flutter (31094): #4 Web3Client.signTransaction (package:web3dart/src/core/client.dart:316:26) E/flutter (31094): <asynchronous suspension> E/flutter (31094): #5 Web3Client.sendTransaction (package:web3dart/src/core/client.dart:285:18) E/flutter (31094): <asynchronous suspension> E/flutter (31094): #6 startElection (package:election/services/functions.dart:29:18) E/flutter (31094): <asynchronous suspension> E/flutter (31094): #7 _HomeState.build.<anonymous closure> (package:election/pages/home.dart:53:25) E/flutter (31094): <asynchronous suspension>
该函数通过Infura连接Solidity智能合约启动选举,此前运行正常,目前无法定位报错原因。
相关代码
home.dart
import 'package:election/utils/Constants.dart'; import 'package:flutter/material.dart'; import 'package:http/http.dart'; import 'package:web3dart/web3dart.dart'; import '../services/functions.dart'; import 'Electioninfo.dart'; class Home extends StatefulWidget { const Home({Key? key}) : super(key: key); @override State<Home> createState() => _HomeState(); } class _HomeState extends State<Home> { late Client? httpClient; late Web3Client? ethclient; TextEditingController controller = TextEditingController(); @override void initState() { httpClient = Client(); ethclient = Web3Client(infura_url, httpClient!); super.initState(); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: const Text('Start Election'), ), body: Container( padding: const EdgeInsets.all(14), child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ TextField( controller: controller, decoration: const InputDecoration( filled: true, hintText: 'Enter election name'), ), const SizedBox( height: 10, ), Container( width: double.infinity, height: 45, child: ElevatedButton( onPressed: () async { if (controller.text.isNotEmpty) { await startElection(controller.text, ethclient!); if(!mounted)return; Navigator.push( context, MaterialPageRoute( builder: (context) => ElectionInfo( ethClient: ethclient!, electionName: controller.text, ))); } }, child: const Text('Start Election'))) ], ), ), ); } }
functions.dart
Future<String> startElection(String name,Web3Client ethclient) async{ var response = await callFunction('startElection', [name], ethclient, owner_private_key); print("election started successfully"); return response; } Future<String> callFunction(String funcname,List<dynamic>args,Web3Client ethClient,String privateKey) async{ EthPrivateKey credentials = EthPrivateKey.fromHex(privateKey); DeployedContract contract = await loadcontract(); final ethfunction = contract.function(funcname); final result = ethClient.sendTransaction( credentials,Transaction.callContract(contract: contract, function: ethfunction, parameters: args), chainId: null,fetchChainIdFromNetworkId: true); return result; }
解决方案
修复chainId配置:
不要将chainId设为null,手动指定对应区块链网络的chainId(比如Goerli测试网为5,以太坊主网为1),同时关闭fetchChainIdFromNetworkId:final result = ethClient.sendTransaction( credentials, Transaction.callContract(contract: contract, function: ethfunction, parameters: args), chainId: 5, // 替换为你的目标网络chainId fetchChainIdFromNetworkId: false, );检查Infura连接有效性:
- 确认
infura_url完整且正确(格式应为https://<网络>.infura.io/v3/你的项目ID) - 检查Infura项目是否正常启用,API密钥未过期、无调用额度限制
- 确认
手动指定Gas参数:
若自动获取gasPrice失败,可手动设置gas上限和价格:final result = ethClient.sendTransaction( credentials, Transaction.callContract( contract: contract, function: ethfunction, parameters: args, maxGas: 1000000, // 按需调整gas上限 gasPrice: EtherAmount.inWei(BigInt.from(20000000000)), // 20 Gwei,可根据当前网络调整 ), chainId: 5, );增加空值安全校验:
在调用startElection前,确保ethclient不为null:if (controller.text.isNotEmpty && ethclient != null) { await startElection(controller.text, ethclient!); if(!mounted)return; Navigator.push( context, MaterialPageRoute( builder: (context) => ElectionInfo( ethClient: ethclient!, electionName: controller.text, ))); }
内容的提问来源于stack exchange,提问作者Abhiram
相关产品推荐
相关产品推荐

