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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.16 22:01:17