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

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

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

web3lib 是一个用于与以太坊区块链进行交互的 Dart 库。它能够连接到以太坊节点,发送交易,与智能合约进行交互等。

功能

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

待办事项

  • 编码所有支持的 Solidity 类型,目前不支持(u)fixed 类型,因为这些类型不常用。

使用

凭证和钱包

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

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

import 'package:web3lib/web3lib.dart';

// 可以从私钥创建凭证
Credentials fromHex = EthPrivateKey.fromHex("c87509a[...]dc0d3");

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

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

另一种获取库用来签名交易的凭证的方式是使用钱包文件。钱包文件安全地存储了私钥,并需要密码解锁。库对版本 3 的钱包文件提供了实验性支持:

import 'dart:io';
import 'package:web3lib/web3lib.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());

你可以将 wallet.toJson() 写入文件,之后可以使用 MyEtherWallet(选择 Keystore / JSON 文件)或其他以太坊客户端如 geth 打开它。

自定义凭证

如果你想将 web3lib 集成到其他钱包提供商中,可以实现 Credentials 并覆盖适当的方法。

连接到 RPC 服务器

该库不会自行将已签名的交易发送给矿工。相反,它依赖于 RPC 客户端来完成这一操作。你可以使用像 Infura 这样的公共 RPC API,或者设置自己的 RPC 服务器。如果你只是想测试一下,可以使用 Truffle 和 Ganache 创建一个本地测试网。

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

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

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

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

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

发送交易

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

import 'package:web3lib/web3lib.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.fromUnitAndValue(EtherUnit.ether, 1),
  ),
);

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

智能合约

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

Dart 代码生成器

通过使用 Dart 的构建系统,web3lib 可以生成 Dart 代码,以便更方便地访问智能合约。

要使用此功能,将合约 ABI JSON 放置到 lib/ 目录下的某个位置。文件名必须以 .abi.json 结尾。然后,添加 build_runner 包作为开发依赖项并运行:

pub run build_runner build

你现在会发现一个 .g.dart 文件,其中包含与合约交互的代码。

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

如果导入的合约 ABIs 具有不符合 Dart 命名约定的函数名称,Dart 分析器会默认对此表示不满,并显示警告。可以通过排除所有生成的文件来分析它们来缓解这个问题。

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

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

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

功能请求和错误报告

请在 问题跟踪器 中提交功能请求和错误报告。如果想为这个库做出贡献,请提交 Pull Request。


示例代码

以下是一个完整的示例代码:

import 'package:http/http.dart';
import 'package:web3lib/web3lib.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.fromUnitAndValue(EtherUnit.ether, 1),
    ),
  );

  await client.dispose();
}

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

1 回复

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


当然,以下是一个关于如何在Flutter中使用web3lib库与区块链进行交互的代码案例。请注意,web3lib库的具体实现和API可能会有所不同,但以下示例将展示一个基本的交互流程,包括连接到区块链节点、获取账户余额以及发送交易。

首先,确保你已经在pubspec.yaml文件中添加了web3lib的依赖项(假设web3lib是一个有效的Flutter插件):

dependencies:
  flutter:
    sdk: flutter
  web3lib: ^x.y.z  # 替换为实际的版本号

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

接下来,在你的Flutter项目中,你可以创建一个服务类来处理与区块链的交互。以下是一个示例代码:

import 'package:flutter/material.dart';
import 'package:web3lib/web3lib.dart'; // 假设这是正确的导入路径

class BlockchainService {
  late Web3Client web3Client;
  late String privateKey;

  BlockchainService(String rpcUrl, String privateKey) {
    this.privateKey = privateKey;
    this.web3Client = Web3Client(rpcUrl);
  }

  Future<String> getBalance(String address) async {
    try {
      BigInt balance = await web3Client.getBalance(address, 'latest');
      return balance.toString();
    } catch (e) {
      print("Error getting balance: $e");
      return "Error";
    }
  }

  Future<String> sendTransaction(String recipient, BigInt amount) async {
    try {
      Credentials credentials = Credentials.fromPrivateKey(privateKey);
      TransactionReceipt receipt = await web3Client.sendTransaction(
        credentials,
        recipient,
        amount,
        Transaction.defaultGasPrice,
        '0x162e40' // 默认gas limit,可以根据需要调整
      );
      return receipt.transactionHash.toHexString();
    } catch (e) {
      print("Error sending transaction: $e");
      return "Error";
    }
  }
}

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('Flutter Blockchain Interaction'),
        ),
        body: BlockchainInteractionScreen(),
      ),
    );
  }
}

class BlockchainInteractionScreen extends StatefulWidget {
  @override
  _BlockchainInteractionScreenState createState() => _BlockchainInteractionScreenState();
}

class _BlockchainInteractionScreenState extends State<BlockchainInteractionScreen> {
  final String rpcUrl = 'https://mainnet.infura.io/v3/YOUR_PROJECT_ID'; // 替换为你的Infura项目ID或其他RPC URL
  final String privateKey = 'YOUR_PRIVATE_KEY'; // 替换为你的私钥
  final String accountAddress = 'YOUR_ACCOUNT_ADDRESS'; // 替换为你的账户地址
  BlockchainService? blockchainService;
  String? balance;
  String? transactionHash;

  @override
  void initState() {
    super.initState();
    blockchainService = BlockchainService(rpcUrl, privateKey);
    _fetchBalance();
  }

  Future<void> _fetchBalance() async {
    setState(() {
      balance = await blockchainService!.getBalance(accountAddress!);
    });
  }

  Future<void> _sendTransaction() async {
    BigInt amount = BigInt.parse('1000000000000000000'); // 发送1个以太币
    setState(() {
      transactionHash = await blockchainService!.sendTransaction(accountAddress!, amount);
    });
  }

  @override
  Widget build(BuildContext context) {
    return Padding(
      padding: const EdgeInsets.all(16.0),
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          Text('Account Address: $accountAddress'),
          SizedBox(height: 16),
          Text('Balance: $balance'),
          SizedBox(height: 32),
          ElevatedButton(
            onPressed: _sendTransaction,
            child: Text('Send 1 ETH'),
          ),
          SizedBox(height: 16),
          if (transactionHash != null)
            Text('Transaction Hash: $transactionHash'),
        ],
      ),
    );
  }
}

注意事项

  1. 替换YOUR_PROJECT_IDYOUR_PRIVATE_KEYYOUR_ACCOUNT_ADDRESS为你的实际值。
  2. 确保你的私钥和账户地址是安全的,不要将它们硬编码在应用中,特别是在生产环境中。
  3. 本示例使用Infura作为RPC节点,你可以根据需要替换为其他节点。
  4. 发送交易时,请确保你有足够的余额和正确的gas设置。
  5. web3lib库的API可能会随版本变化,请参考最新的文档进行调整。

希望这个示例能帮助你理解如何在Flutter中使用web3lib与区块链进行交互。

回到顶部