Flutter区块链交互插件web3dart的使用

发布于 1周前 作者 caililin 来自 Flutter

Flutter区块链交互插件web3dart的使用

Flutter应用可以通过web3dart库与Ethereum区块链进行交互。这个库提供了丰富的功能,如连接到以太坊节点、发送交易、与智能合约交互等。以下是关于如何在Flutter项目中使用web3dart的具体说明和一个完整的示例demo。

web3dart简介

pub package likes points popularity license stars forks sdk version

web3dart是一个用于与Ethereum区块链交互的Dart库。它通过连接到以太坊节点来发送交易、调用智能合约等功能。

功能特性

  • 通过RPC API连接到以太坊节点并调用常用方法
  • 发送已签名的以太坊交易
  • 生成私钥,设置新的以太坊地址
  • 调用智能合约函数并监听合约事件
  • 基于智能合约ABI生成代码以便更方便地交互

使用指南

凭证和钱包

为了在以太坊网络上发送交易,需要一些凭证。web3dart支持从私钥或v3钱包文件创建凭证。

从私钥创建凭证

import 'package:web3dart/web3dart.dart';
import 'dart:math';

// 使用私钥创建凭证
Credentials credentials = EthPrivateKey.fromHex("c87509a[...]dc0d3");

// 或者随机生成一个新的私钥
var rng = Random.secure();
Credentials randomCredentials = EthPrivateKey.createRandom(rng);

// 获取地址
var address = credentials.address;
print(address.hex);

使用钱包文件解锁凭证

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

String content = File("wallet.json").readAsStringSync();
Wallet wallet = Wallet.fromJson(content, "testpassword");

Credentials unlockedCredentials = wallet.privateKey;

连接到RPC服务器

web3dart不会自己发送已签名的交易给矿工,而是依赖于RPC客户端。可以使用公共的RPC API(如Infura),或者搭建自己的节点(如geth),也可以使用Truffle和Ganache进行测试。

import 'package:http/http.dart' as http;
import 'package:web3dart/web3dart.dart';

var apiUrl = "http://localhost:7545"; // 替换为你的API地址
var httpClient = http.Client();
var ethClient = Web3Client(apiUrl, httpClient);

// 查询账户余额
EtherAmount balance = await ethClient.getBalance(credentials.address);
print(balance.getValueInUnit(EtherUnit.ether));

发送交易

web3dart支持创建、签名和发送以太坊交易。

await ethClient.sendTransaction(
  credentials,
  Transaction(
    to: EthereumAddress.fromHex('0xC91...3706'),
    gasPrice: EtherAmount.inWei(BigInt.one),
    maxGas: 100000,
    value: EtherAmount.fromUnitAndValue(EtherUnit.ether, 1),
  ),
);

智能合约

web3dart可以解析智能合约的ABI,并发送数据给合约,同时监听合约事件。具体可以参考此文件

Dart代码生成器

通过Dart的构建系统,web3dart可以生成Dart代码来轻松访问智能合约。

  1. 安装web3dart_builders包:

    pub add web3dart_builders --dev
    
  2. 将合约ABI JSON文件放在lib/目录下,文件名必须以.abi.json结尾。

  3. 添加build_runner作为开发依赖,并运行以下命令:

    pub run build_runner build
    
  4. 生成的代码将保存在.g.dart文件中。

忽略生成文件的命名建议

如果导入的合约ABI包含不符合Dart命名规范的函数名,Dart分析器会显示警告。可以在项目的根目录下创建analysis_options.yaml文件,排除生成文件的分析:

analyzer:
  exclude: 
    - '**/*.g.dart'

示例Demo

以下是一个完整的示例,展示了如何在Flutter应用中使用web3dart与以太坊节点交互。

import 'package:flutter/material.dart';
import 'package:http/http.dart';
import 'package:web3dart/web3dart.dart';

const String privateKey =
    'a2fd51b96dc55aeb14b30d55a6b3121c7b9c599500c1beb92a389c3377adc86e';
const String rpcUrl = 'http://localhost:7545';

void main() async {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Web3dart Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(title: 'Web3dart Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key? key, required this.title}) : super(key: key);

  final String title;

  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  late Web3Client client;
  late Credentials credentials;
  String address = '';
  String balance = '';

  @override
  void initState() {
    super.initState();
    initWeb3();
  }

  Future<void> initWeb3() async {
    client = Web3Client(rpcUrl, Client());
    credentials = EthPrivateKey.fromHex(privateKey);
    address = credentials.address.hexEip55;
    balance = (await client.getBalance(credentials.address))
        .getValueInUnit(EtherUnit.ether)
        .toString();

    setState(() {});
  }

  Future<void> sendTransaction() async {
    try {
      await client.sendTransaction(
        credentials,
        Transaction(
          to: EthereumAddress.fromHex(
              '0xC914Bb2ba888e3367bcecEb5C2d99DF7C7423706'),
          gasPrice: EtherAmount.inWei(BigInt.one),
          maxGas: 100000,
          value: EtherAmount.fromInt(EtherUnit.ether, 1),
        ),
      );
      print('Transaction sent!');
    } catch (e) {
      print('Error sending transaction: $e');
    }
  }

  @override
  void dispose() {
    client.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Text('Your Address: $address'),
            SizedBox(height: 20),
            Text('Your Balance: $balance ETH'),
            SizedBox(height: 20),
            ElevatedButton(
              onPressed: sendTransaction,
              child: Text('Send Transaction'),
            ),
          ],
        ),
      ),
    );
  }
}

以上代码展示了一个简单的Flutter应用程序,该应用程序连接到本地运行的以太坊节点(例如Ganache),查询用户的余额,并允许用户发送交易。请确保你有一个可用的以太坊节点正在运行,并且已经配置了正确的RPC URL和私钥。

测试

要运行测试,请执行以下命令:

dart test test

更多详细信息和高级用法,请参阅官方文档。如果你有任何问题或建议,欢迎提交Issue或Pull Request。


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

1 回复

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


当然,以下是一个关于如何在Flutter项目中使用web3dart插件与区块链进行交互的示例代码。web3dart是一个Dart库,用于与以太坊区块链进行交互,支持RPC调用和智能合约交互。

前提条件

  1. 确保你的Flutter开发环境已经配置好。
  2. 添加web3dart依赖到你的pubspec.yaml文件中。
dependencies:
  flutter:
    sdk: flutter
  web3dart: ^2.0.0  # 请根据最新版本进行调整
  1. 获取一个以太坊节点(如Infura、Alchemy或你自己的本地节点)的RPC URL。

示例代码

1. 初始化Web3Client

首先,你需要创建一个Web3Client实例,该实例将用于与以太坊节点进行通信。

import 'package:web3dart/web3dart.dart';

void main() async {
  // 替换为你的以太坊节点RPC URL
  final client = Web3Client('https://mainnet.infura.io/v3/YOUR_PROJECT_ID');

  // 检查连接
  final version = await client.getVersion();
  print('Connected to Ethereum node: $version');

  // 关闭客户端连接(在Flutter中,通常你会在适当的生命周期方法中关闭连接)
  client.dispose();
}

2. 获取账户余额

接下来,你可以使用Web3Client来获取某个账户的余额。

import 'package:web3dart/web3dart.dart';
import 'dart:convert';

void main() async {
  final client = Web3Client('https://mainnet.infura.io/v3/YOUR_PROJECT_ID');

  // 替换为你要查询余额的以太坊账户地址
  final address = EthereumAddress.fromHex('0xYourEthereumAddressHere');

  // 获取余额
  BigInt balance = await client.getBalance(address);

  // 将余额转换为以太币(Wei到Ether)
  final etherBalance = EtherAmount.fromWei(balance);
  print('Balance: ${etherBalance.toString()} ETH');

  client.dispose();
}

3. 与智能合约交互

要与智能合约交互,你需要合约的ABI和地址。以下是一个简单的示例,展示如何调用一个智能合约的函数。

import 'package:web3dart/web3dart.dart';
import 'dart:convert';

void main() async {
  final client = Web3Client('https://mainnet.infura.io/v3/YOUR_PROJECT_ID');

  // 智能合约的ABI和地址
  final contractAddress = EthereumAddress.fromHex('0xYourSmartContractAddressHere');
  final abi = jsonDecode('''
    [
      // 你的智能合约ABI JSON数组
    ]
  ''');
  final contract = ContractAbi(abi, contractAddress);

  // 调用智能合约的函数(假设有一个名为'balanceOf'的函数,接受一个地址作为参数)
  final Function function = contract.function('balanceOf', [
    EthereumAddress.fromHex('0xYourEthereumAddressHere'),
  ]);

  final TransactionReceipt receipt = await client.sendTransaction(
    function,
    from: EthereumAddress.fromHex('0xYourSenderAddressHere'), // 发送者的地址
    privateKey: Uint8List.fromList(hex.decode('YourSenderPrivateKeyHere')), // 发送者的私钥
  );

  // 处理返回结果
  final result = BigInt.parse(receipt.returnValue);
  print('Contract balance: $result');

  client.dispose();
}

注意

  • 在实际开发中,不要在代码中硬编码私钥。你应该使用安全的存储方式,如密钥管理服务(KMS)或硬件钱包。
  • 调用智能合约函数时,确保你的账户有足够的Gas来支付交易费用。
  • 在Flutter应用中,你可能需要在适当的生命周期方法(如dispose)中关闭Web3Client连接。

这个示例展示了如何使用web3dart与以太坊区块链进行基本的交互。根据你的具体需求,你可能需要调整代码来适应不同的智能合约函数和参数。

回到顶部