Flutter Web3交互插件dart_web3gas的使用

Flutter Web3交互插件dart_web3gas的使用

dart_web3gas 是一个基于 Dart 语言计算区块链 Gas 的库(参考 Metamask 的计算逻辑)。为了防止 web3dart 的代码更新过快,部分代码被包含并进行了修改。

web3dart

pubspec.yaml 文件中添加以下依赖:

dependencies:
  web3dart: ^2.6.1

可以在 pub.dev 上找到更多关于 web3dart 的信息。

示例代码

以下是一个完整的示例代码,展示了如何使用 dart_web3gas 插件进行 Web3 交互。

import 'dart:io';
import 'package:dart_web3gas/web3dart/web3dart.dart';
import 'package:dart_web3gas/dart_web3gas.dart';

Future<void> main() async {
  var http = HttpClient();
  http.connectionTimeout = const Duration(seconds: 2);

  // 创建 Web3 客户端实例
  var web3 = Web3Client.custom(
      JsonRPCHttp('https://polygon-mumbai-bor.publicnode.com', http));

  // 获取 Gas 费用估计数据
  var gas = await GasFeeController.fetchGasFeeEstimateData(web3);
  var max = gas?.gasFeeEstimates?.medium.suggestedMaxFeePerGas;
  var priority = gas?.gasFeeEstimates?.medium.suggestedMaxPriorityFeePerGas;

  // 打印钱包地址
  final wallet = EthPrivateKey.fromHex(
      'ae349e5dc27fe2b001ebbfe865c871e15a84929dbf42a9391941f3f7bc8f42fb');
  print('${wallet.address.hex} ');

  // 创建交易对象
  var transaction = Transaction(
    from: wallet.address,
    to: EthereumAddress.fromHex('0x7459e6df1f70820788809d5d25882acd3f9be3c3'),
    value: EtherAmount.fromBigInt(EtherUnit.finney, BigInt.one),
  );

  // 估算 Gas
  var basefee = await web3.estimateGas(
    sender: transaction.from,
    to: transaction.to,
    value: transaction.value,
  );

  if (max != null && priority != null) {
    print('basefee: $basefee');
    print(
        'max:${double.parse(max) * basefee.toDouble()} pri:${double.parse(priority) * basefee.toDouble()}');
  }

  // 获取当前 Gas 价格
  var gasprice = await web3.getGasPrice();
  print('gasprice: $gasprice');

  // 创建 EIP-1559 交易对象
  final transaction0 = transaction.copyWith(
    maxFeePerGas: BigInt.from(
        double.parse(eip1559GasFee.suggestedMaxFeePerGas) *
            BigInt.from(10).pow(9).toDouble()),
    maxPriorityFeePerGas: BigInt.from(
        double.parse(eip1559GasFee.suggestedMaxPriorityFeePerGas) *
            BigInt.from(10).pow(9).toDouble()),
    gasPrice: gasprice,
  );

  // 计算总 Gas 费用
  var total = getGasFee(transaction0, gas, basefee);
  print('total:$total');
  
  // 发送交易
  await web3.sendTransaction(wallet, transaction0, chainId: 80001);

  // 创建基础交易对象
  final transaction1 = transaction.copyWith(
    from: wallet.address,
    to: EthereumAddress.fromHex('0x7459e6df1f70820788809d5d25882acd3f9be3c3'),
    value: EtherAmount.fromBigInt(EtherUnit.finney, BigInt.one),
    maxGas: basefee,
    gasPrice: EtherAmount.fromBigInt(EtherUnit.gwei, BigInt.from(30)).getInWei,
  );

  // 计算总 Gas 费用
  total = getGasFee(transaction1, gas, basefee);
  print('total:$total');
  
  // 发送交易
  await web3.sendTransaction(wallet, transaction1, chainId: 80001);
}

// 计算 Gas 费用
BigInt getGasFee(
    Transaction? transaction, GasFeeCalculations? gasFee, BigInt? maxFee) {
  final gasPrice = transaction?.gasPrice;
  final gasLimit = transaction?.maxGas;
  if (gasPrice != null && gasLimit != null) {
    return (gasPrice * gasLimit);
  }
  return _getEip1159EthGasFee(gasFee, maxFee);
}

// 计算 EIP-1559 Gas 费用
BigInt _getEip1159EthGasFee(GasFeeCalculations? gasFee, BigInt? maxFee) {
  ///  (base fee + priority fee) x units of gas used
  BigInt total = BigInt.zero;
  BigInt? gasPrice = gasFee?.gasPrice;

  Eip1559GasFee? eip1559Gas = gasFee?.gasFeeEstimates?.medium;
  if (eip1559Gas != null) {
    double baseFee = double.parse(eip1559Gas.suggestedMaxFeePerGas);
    double priorityFee = double.parse(eip1559Gas.suggestedMaxPriorityFeePerGas);
    gasPrice = BigInt.from(
        (baseFee + priorityFee) * BigInt.from(10).pow(9).toDouble());
    print('==== base:$baseFee priority:$priorityFee  max:$maxFee');
  }

  if (gasPrice != null && maxFee != null) {
    total += gasPrice * maxFee;
  }

  return total;
}

更多关于Flutter Web3交互插件dart_web3gas的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter Web3交互插件dart_web3gas的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


dart_web3 是一个用于在 Dart 应用中与以太坊区块链进行交互的库。它允许你连接到以太坊节点、发送交易、调用智能合约等。在使用 dart_web3 时,gas 是一个关键概念,因为它决定了交易的执行成本和优先级。

1. 安装 dart_web3

首先,你需要在 pubspec.yaml 文件中添加 dart_web3 依赖:

dependencies:
  dart_web3: ^4.0.0

然后运行 flutter pub get 来安装依赖。

2. 连接到以太坊节点

使用 dart_web3 连接到以太坊节点,通常是通过 Infura 或其他以太坊节点提供商。

import 'package:dart_web3/dart_web3.dart';

void main() async {
  final ethClient = Web3Client('https://mainnet.infura.io/v3/YOUR_INFURA_PROJECT_ID', Client());
  
  // 获取当前最新的区块号
  final blockNumber = await ethClient.getBlockNumber();
  print('Latest Block Number: $blockNumber');
}

3. 发送交易

发送交易时,你需要指定 gasLimitgasPrice

import 'package:dart_web3/dart_web3.dart';

void main() async {
  final ethClient = Web3Client('https://mainnet.infura.io/v3/YOUR_INFURA_PROJECT_ID', Client());
  
  final credentials = EthPrivateKey.fromHex('YOUR_PRIVATE_KEY');
  
  final transaction = Transaction(
    to: EthereumAddress.fromHex('0xRecipientAddress'),
    gasPrice: EtherAmount.inWei(BigInt.from(20000000000)), // 20 Gwei
    maxGas: 21000, // Gas limit
    value: EtherAmount.fromUnitAndValue(EtherUnit.ether, 1), // 1 ETH
  );
  
  final transactionHash = await ethClient.sendTransaction(credentials, transaction);
  print('Transaction Hash: $transactionHash');
}

4. 调用智能合约

调用智能合约时,你也需要指定 gasLimitgasPrice

import 'package:dart_web3/dart_web3.dart';

void main() async {
  final ethClient = Web3Client('https://mainnet.infura.io/v3/YOUR_INFURA_PROJECT_ID', Client());
  
  final credentials = EthPrivateKey.fromHex('YOUR_PRIVATE_KEY');
  
  final contractAddress = EthereumAddress.fromHex('0xYourContractAddress');
  final contract = DeployedContract(
    ContractAbi.fromJson('[YOUR_CONTRACT_ABI_JSON]', 'YourContractName'),
    contractAddress,
  );
  
  final function = contract.function('yourFunctionName');
  
  final transaction = Transaction.callContract(
    contract: contract,
    function: function,
    parameters: [/* your function parameters */],
    gasPrice: EtherAmount.inWei(BigInt.from(20000000000)), // 20 Gwei
    maxGas: 100000, // Gas limit
  );
  
  final transactionHash = await ethClient.sendTransaction(credentials, transaction);
  print('Transaction Hash: $transactionHash');
}

5. 估计 Gas 费用

你可以使用 estimateGas 方法来预估交易或合约调用所需的 Gas。

import 'package:dart_web3/dart_web3.dart';

void main() async {
  final ethClient = Web3Client('https://mainnet.infura.io/v3/YOUR_INFURA_PROJECT_ID', Client());
  
  final credentials = EthPrivateKey.fromHex('YOUR_PRIVATE_KEY');
  
  final transaction = Transaction(
    to: EthereumAddress.fromHex('0xRecipientAddress'),
    gasPrice: EtherAmount.inWei(BigInt.from(20000000000)), // 20 Gwei
    value: EtherAmount.fromUnitAndValue(EtherUnit.ether, 1), // 1 ETH
  );
  
  final estimatedGas = await ethClient.estimateGas(credentials: credentials, transaction: transaction);
  print('Estimated Gas: $estimatedGas');
}

6. 动态调整 Gas Price

你可以使用 eth_gasPrice 方法获取当前网络推荐的 Gas 价格,并动态调整。

import 'package:dart_web3/dart_web3.dart';

void main() async {
  final ethClient = Web3Client('https://mainnet.infura.io/v3/YOUR_INFURA_PROJECT_ID', Client());
  
  final gasPrice = await ethClient.getGasPrice();
  print('Current Gas Price: ${gasPrice.getInWei} Wei');
}
回到顶部