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

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

web3libdart

pub package

Fork from web3dart 版本 2.3.5

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

特性

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

待办事项

  • 编码所有支持的Solidity类型,虽然目前不支持(u)fixed,这些类型并不常见。

使用

凭证和钱包

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

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

import 'package:web3libdart/web3libdart.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:web3libdart/web3libdart.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 打开该文件。

自定义凭证

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

连接到RPC服务器

库本身不会自行将已签名的交易发送给矿工。相反,它依赖于RPC客户端完成这一操作。您可以使用公共RPC API,例如 Infura,或者设置自己的使用 geth 的RPC服务。如果您只是想测试一下,可以使用 truffle 和 ganache 设置一个私有测试网。所有这些选项都将为您提供一个库可以连接的RPC端点。

import 'package:http/http.dart'; // 您也可以导入浏览器版本
import 'package:web3libdart/web3libdart.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:web3libdart/web3libdart.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价格、发送方和交易nonce),则会在连接的节点上获取这些数据。如果您只需要已签名的交易但不打算发送它,可以使用 client.signTransaction

智能合约

库可以解析智能合约的ABI并发送数据到它。它还可以监听智能合约发出的事件。有关示例,请参阅 此文件

Dart代码生成器

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

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

pub run build_runner build

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

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

如果导入不符合Dart命名约定的合约ABIs,Dart分析器会默认显示警告。 这可以通过排除所有生成文件的分析来缓解。 注意这可能会抑制严重的错误,如果存在的话。(生成的文件应该不会有严重错误)。

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

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

详见 自定义静态分析 了解更多高级选项。

功能请求和错误报告

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


示例代码

import 'package:http/http.dart';
import 'package:web3libdart/web3libdart.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区块链交互插件web3libdart的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

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


web3dart 是一个用于在 Flutter 应用中与以太坊区块链进行交互的 Dart 库。它支持以太坊的 JSON-RPC API,可以用于发送交易、查询区块链数据、与智能合约交互等。

以下是如何在 Flutter 项目中使用 web3dart 的基本步骤:

1. 添加依赖

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

dependencies:
  flutter:
    sdk: flutter
  web3dart: ^2.3.5
  http: ^0.13.3

http 包是 web3dart 用于与以太坊节点进行 HTTP 通信的依赖。

2. 导入库

在你的 Dart 文件中导入 web3darthttp

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

3. 连接到以太坊节点

你需要连接到一个以太坊节点来与区块链进行交互。你可以使用 Infura、Alchemy 或者本地节点。

final String rpcUrl = "https://mainnet.infura.io/v3/YOUR_INFURA_PROJECT_ID";
final Web3Client ethClient = Web3Client(rpcUrl, Client());

4. 查询区块链数据

你可以使用 ethClient 来查询区块链上的数据。例如,查询当前区块号:

Future<void> getBlockNumber() async {
  final blockNumber = await ethClient.getBlockNumber();
  print('Current block number: $blockNumber');
}

5. 发送交易

要发送交易,你需要一个以太坊账户的私钥。你可以使用 Credentials 类来创建交易并发送。

final credentials = EthPrivateKey.fromHex('YOUR_PRIVATE_KEY');

final transaction = Transaction(
  to: EthereumAddress.fromHex('0xRecipientAddress'),
  gasPrice: EtherAmount.inWei(BigInt.one),
  maxGas: 21000,
  value: EtherAmount.fromUnitAndValue(EtherUnit.ether, 1),
);

final transactionHash = await ethClient.sendTransaction(
  credentials,
  transaction,
);
print('Transaction hash: $transactionHash');

6. 与智能合约交互

要与智能合约交互,你需要合约的 ABI 和地址。你可以使用 DeployedContractContractFunction 来调用合约的函数。

final contractAddress = EthereumAddress.fromHex('0xContractAddress');
final contractAbi = [/* 合约的 ABI */];

final contract = DeployedContract(contractAbi, contractAddress);

// 调用合约的只读函数
final balanceFunction = contract.function('balanceOf');
final balance = await ethClient.call(
  contract: contract,
  function: balanceFunction,
  params: [EthereumAddress.fromHex('0xYourAddress')],
);
print('Balance: $balance');

// 调用合约的写入函数
final transferFunction = contract.function('transfer');
final transferTx = await ethClient.sendTransaction(
  credentials,
  Transaction.callContract(
    contract: contract,
    function: transferFunction,
    parameters: [EthereumAddress.fromHex('0xRecipientAddress'), BigInt.from(100)],
  ),
);
print('Transfer transaction hash: $transferTx');

7. 处理错误

在实际应用中,处理错误是非常重要的。你可以使用 try-catch 来捕获并处理可能出现的错误。

try {
  final balance = await ethClient.getBalance(EthereumAddress.fromHex('0xYourAddress'));
  print('Balance: $balance');
} catch (e) {
  print('Error fetching balance: $e');
}

8. 断开连接

在应用退出时,记得断开与以太坊节点的连接。

void dispose() {
  ethClient.dispose();
}
回到顶部