Flutter区块链交互插件web3lib的使用
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
更多关于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'),
],
),
);
}
}
注意事项:
- 替换
YOUR_PROJECT_ID
、YOUR_PRIVATE_KEY
和YOUR_ACCOUNT_ADDRESS
为你的实际值。 - 确保你的私钥和账户地址是安全的,不要将它们硬编码在应用中,特别是在生产环境中。
- 本示例使用Infura作为RPC节点,你可以根据需要替换为其他节点。
- 发送交易时,请确保你有足够的余额和正确的gas设置。
web3lib
库的API可能会随版本变化,请参考最新的文档进行调整。
希望这个示例能帮助你理解如何在Flutter中使用web3lib
与区块链进行交互。