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

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

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

概述

WebThree 是一个用于 Dart 的 web3 库,允许你通过 HTTP 或 WebSocket 与本地或远程以太坊节点进行交互。它支持自定义凭证提供者,如 WalletConnect 和 Metamask。

特性

  • 连接到以太坊节点并调用常见的 RPC 方法
  • 发送已签名的以太坊交易
  • 生成私钥并设置新的以太坊地址
  • 调用智能合约函数并监听合约事件
  • 基于智能合约 ABI 生成 Dart 绑定,以便更轻松地进行交互

待办事项

  • 支持所有 Solidity 类型的编码,尽管目前不常用的一些类型(如 (u)fixed)尚未支持
  • 提高测试覆盖率
  • 添加 Wallet Connect 示例

使用方法

凭证和钱包

为了在以太坊网络上发送交易,需要一些凭证。该库支持原始私钥和 v3 钱包文件。

使用私钥创建凭证

import 'dart:math'; // 用于随机数生成器
import 'package:webthree/webthree.dart';

// 从十六进制字符串创建凭证
Credentials fromHex = EthPrivateKey.fromHex("c87509a[...]dc0d3");

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

// 无论哪种方式,库都可以从私钥派生公钥和地址
var address = credentials.address;
print(address.hex);

使用钱包文件创建凭证

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

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

Credentials unlocked = wallet.privateKey;
// 现在可以使用这些凭证来签名交易或消息

创建钱包文件

Wallet wallet = Wallet.createNew(credentials, "password", random);
print(wallet.toJson());

连接到 RPC 服务器

该库本身不会将已签名的交易发送给矿工,而是依赖于 RPC 客户端来完成这一任务。你可以使用公共 RPC API(如 Infura),设置自己的节点(如 Geth),或者在开发时使用 Hardhat 运行的私有测试网。

import 'package:http/http.dart'; // 也可以导入浏览器版本
import 'package:webthree/webthree.dart';

var apiUrl = "http://localhost:7545"; // 替换为你的 API 地址

var httpClient = Client();
var ethClient = Web3Client(apiUrl, httpClient);

var credentials = EthPrivateKey.fromHex("0x...");
var address = await credentials.address;

// 现在可以调用 RPC 方法,例如查询你拥有的以太币数量
EtherAmount balance = await ethClient.getBalance(address);
print(balance.getValueInUnit(EtherUnit.ether));

发送交易

当然,该库支持创建、签名和发送以太坊交易。

import 'package:webthree/webthree.dart';

/// [...], 你需要指定 URL 和客户端,参见上面的示例
var ethClient = Web3Client(apiUrl, httpClient);

var credentials = ethClient.credentialsFromPrivateKey("0x...");

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

缺少的数据(如 gas 价格、发送者和交易 nonce)将在未明确指定时从连接的节点获取。如果你只需要已签名的交易但不打算发送,可以使用 client.signTransaction

MetaMask 示例

请参见 ./example/metamask/main.dart

WalletConnect V2 示例

请参见 WalletConnectFlutterV2WalletConnect Web3Modal 仓库。

智能合约

该库可以解析智能合约的 ABI 并向其发送数据。它还可以监听智能合约发出的事件。参见 此文件 以获取示例。

Dart 代码生成器

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

要使用此功能,请将合约 ABI JSON 文件放在 lib/ 目录中的某个位置。文件名必须以 .abi.json 结尾。然后,添加对 build_runner 包的 dev_dependency,并运行:

dart run build_runner build

现在你会找到一个包含与合约交互代码的 .g.dart 文件。

可选:忽略生成文件的命名建议

如果导入的合约 ABI 中的函数名称不符合 Dart 的命名约定,Dart 分析器会显示警告。可以通过排除所有生成文件来缓解这一问题。

在项目的根目录中创建一个名为 analysis_options.yaml 的文件:

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

参见 自定义静态分析 以获取更多高级选项。

外部代码集成到 WebThree

功能请求和错误报告

请在 问题跟踪器 中提交功能请求和错误报告。如果你想为本库贡献代码,请提交 Pull Request。

示例代码

import 'package:http/http.dart';
import 'package:webthree/webthree.dart';

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

Future<void> main() async {
  // 创建一个客户端用于发送交易
  final client = Web3Client(rpcUrl, Client());

  final credentials = EthPrivateKey.fromHex(privateKey);
  final address = credentials.address;

  print(address.hexEip55);
  print(await client.getBalance(address));

  await client.sendTransaction(
    credentials,
    Transaction(
      to: EthereumAddress.fromHex('0xC914Bb2ba888e3367bcecEb5C2d99DF7C7423706'),
      gasPrice: EtherAmount.inWei(BigInt.one),
      maxGas: 100000,
      value: EtherAmount.fromInt(EtherUnit.ether, 1),
    ),
  );

  await client.dispose();
}

希望这些信息对你有所帮助!如果有任何问题或需要进一步的帮助,请随时提问。


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

1 回复

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


在Flutter应用中与区块链进行交互,web3dart(作为webthree在Dart中的实现)是一个常用的库。尽管web3dart主要用于与以太坊区块链交互,但它提供了丰富的功能,使得在Flutter应用中集成区块链操作变得相对简单。

以下是一个使用web3dart与以太坊区块链进行基本交互的Flutter代码示例。这个示例展示了如何连接到以太坊节点、获取账户余额以及发送一个简单的交易。

1. 添加依赖

首先,在pubspec.yaml文件中添加web3dart依赖:

dependencies:
  flutter:
    sdk: flutter
  web3dart: ^2.0.0  # 请检查最新版本号

2. 连接到以太坊节点并获取账户余额

接下来,编写一个Dart文件(例如blockchain_service.dart),用于处理与区块链的交互:

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

class BlockchainService {
  final String privateKey;
  final String infuraUrl; // 使用Infura或其他以太坊节点服务
  Client? _client;

  BlockchainService({required this.privateKey, required this.infuraUrl});

  Future<Client> getClient() async {
    if (_client == null) {
      final http.Client httpClient = http.Client();
      _client = Client(infuraUrl, httpClient: httpClient);
    }
    return _client!;
  }

  Future<BigInt> getBalance(String address) async {
    final client = await getClient();
    final balance = await client.getBalance(EthereumAddress.fromHex(address));
    return balance;
  }

  // 发送交易(省略了gas估算和nonce管理,仅作为示例)
  Future<String> sendTransaction(String toAddress, BigInt amount) async {
    final client = await getClient();
    final credentials = EthPrivateKey.fromHex(privateKey);
    final transaction = TransactionBuilder()
        .to(EthereumAddress.fromHex(toAddress))
        .value(EtherAmount.fromUnitAndValue(EtherUnit.wei, amount))
        .gasPrice(EtherAmount.fromUnitAndValue(EtherUnit.gwei, 20)) // 设置gas价格
        .gasLimit(BigInt.fromInt(21000)) // 设置gas上限
        .send();

    final signedTx = await credentials.signTransaction(transaction, chainId: BigInt.fromInt(1)); // 主网chainId为1
    final receipt = await client.sendSignedTransaction(signedTx);
    return receipt.transactionHash.hex;
  }
}

3. 在Flutter应用中使用该服务

在你的Flutter组件中,你可以实例化BlockchainService并使用它的方法来与区块链交互:

import 'package:flutter/material.dart';
import 'blockchain_service.dart';

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

class MyApp extends StatefulWidget {
  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  final BlockchainService _blockchainService = BlockchainService(
    privateKey: '你的私钥', // 注意:不要在生产代码中硬编码私钥
    infuraUrl: 'https://mainnet.infura.io/v3/YOUR_PROJECT_ID',
  );

  String? balance = 'Loading...';
  String? transactionHash;

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

  Future<void> _fetchBalance() async {
    final balanceInWei = await _blockchainService.getBalance('目标地址');
    setState(() {
      balance = '${EtherAmount.fromWei(balanceInWei)} ETH';
    });
  }

  Future<void> _sendTransaction() async {
    final amountInWei = EtherAmount.fromUnitAndValue(EtherUnit.ether, 0.01).inWei; // 0.01 ETH
    transactionHash = await _blockchainService.sendTransaction('接收地址', amountInWei);
    setState(() {});
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('Flutter Blockchain Interaction'),
        ),
        body: Center(
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: <Widget>[
              Text('Account Balance: $balance'),
              SizedBox(height: 20),
              ElevatedButton(
                onPressed: _sendTransaction,
                child: Text('Send 0.01 ETH'),
              ),
              if (transactionHash != null)
                Text('Transaction Hash: $transactionHash'),
            ],
          ),
        ),
      ),
    );
  }
}

注意事项

  1. 私钥管理:不要在代码中硬编码私钥,尤其是在生产环境中。使用安全的密钥管理服务。
  2. Gas管理:示例中省略了gas估算和nonce管理,实际应用中需要处理这些。
  3. 网络选择:确保infuraUrl与你的网络(主网、测试网等)匹配。
  4. 错误处理:添加必要的错误处理逻辑,以处理网络问题、交易失败等情况。

这个示例提供了一个基本的框架,展示了如何在Flutter应用中使用web3dart与以太坊区块链进行交互。根据具体需求,你可能需要扩展和修改这个代码。

回到顶部