Flutter数字货币处理插件digicoinlib的使用

Flutter数字货币处理插件digicoinlib的使用

Digicoinlib

DigiByte Donate pub.dev

Digicoinlib #

Digicoinlib 是一个简单且模块化的库,用于 DigiByte 和其他类似的加密货币,包括 Taproot 支持。该库允许构建和签署交易以及管理 BIP32 钱包。

安装与使用 #

如果你正在使用 Flutter,请参阅 digicoinlib_flutter 插件。否则,你可以通过以下方式将 digicoinlib 添加到你的项目:

```bash dart pub add digicoinlib ```

如果你在 Web 上使用该库,则库已准备好使用。如果你在 Linux、macOS 或 Windows 上使用该库,请参阅以下部分:

库可以通过以下方式导入:

```dart import 'package:digicoinlib/digicoinlib.dart'; ```

必须在使用任何库之前异步加载库,通过等待 loadDigiCoinlib() 函数完成。

库使用功能风格的面向对象编程(OOP)。除了某些特殊情况外,对象是不可变的。方法返回新修改的对象。例如,签署交易会返回一个新的签名交易对象:

```dart final signedTx = unsignedTx.sign(inputN: 0, key: privateKey); ```

示例可以在 example/ 目录中找到。

为 Linux 构建 #

需要 Docker 或 Podman 来为 Linux 构建库。

可以使用 dart run digicoinlib:build_linux 在你的包的根目录下构建 Linux 共享库,这将在 build/libsecp256k1.so 中生成共享库。也可以在 digicoinlib 的根目录下运行 dart run bin/build_linux.dart

此库可以放在 build 目录下的当前工作目录下,作为系统库安装,或在 $LD_LIBRARY_PATH 中。

为 macOS 构建 #

为 macOS 构建需要使用 Homebrew 安装 autotools:

```bash brew install autoconf automake libtool ```

macOS 动态库必须在运行 Dart 代码时作为 $PWD/build/libsecp256k1.dylib 提供,或者作为一个名为 secp256k1.framework 的系统框架提供。

要构建动态库,运行 dart run digicoinlib:build_macos,这将在 build 目录下放置库。

为 Windows 构建 #

原生 Windows 构建 #

请注意,此部分的原生 Windows 构建有时会在构建过程中冻结。 如果发生这种情况,请参阅 "使用 WSL 跨平台编译 Windows" 部分。

在 Windows 上构建需要 CMake 作为依赖项。

Windows 共享库可以通过 dart run digicoinlib:build_windows 在你的包的根目录下构建,这将在 build/libsecp256k1.dll 中生成共享库。也可以在 digicoinlib 的根目录下运行 dart run bin/build_windows.dart

Windows 构建使用 Visual Studio 17 2022 生成器。更早版本的 Visual Studio 工具链可能通过编辑 bin/build_windows.dart 而工作。

从 Linux 跨平台编译 Windows #

在 Ubuntu 20.04 主机上使用 dart run digicoinlib:build_windows_crosscompile 跨平台编译 secp256k1 DLL。也可以在 digicoinlib 的根目录下运行 dart run bin/build_windows_crosscompile.dart

使用 WSL 跨平台编译 Windows #

可以在 Windows Subsystem for Linux (WSL2) 上完成 Windows 构建。首先,在 WSL(2) 主机上安装以下软件包:

  • autoconf
  • libtool
  • build-essential
  • git
  • cmake
  • mingw-w64

如:

```bash apt-get update -y apt-get install -y autoconf libtool build-essential git cmake mingw-w64 ```

然后,在 Windows 主机上的 Ubuntu 20.04 WSL2 实例上使用 dart run digicoinlib:build_wsldart run bin/build_wsl.dartdigicoinlib 的根目录下进行跨平台编译。也可以在安装 Docker 或 Podman 后完成上述 "在 Linux 上跨平台编译 Windows"。无需在 WSL 中安装 Flutter 即可完成构建。

开发 #

本节仅适用于库的开发者。

绑定和 WebAssembly #

WebAssembly (WASM) 模块是预编译好的,可以直接使用。FFI 绑定也是预生成的。这些只在底层 secp256k1 库更改时才需要更新。

本地库的绑定(不包括 WebAssembly)是从 headers/secp256k1.h 文件使用 dart run ffigen 生成的。

WebAssembly 模块已在 lib/src/secp256k1/secp256k1.wasm.g.dart 中预构建。也可以在 digicoinlib 的根目录下使用 dart run bin/build_wasm.dart 进行重建。

示例代码

import "package:digicoinlib/digicoinlib.dart";

void main() async {

  // 总是记得在 Web 使用时加载库
  // Flutter 应用程序应使用带有 CoinlibLoader 小部件的 digicoinlib_flutter 插件
  await loadDigiCoinlib();

  // 从种子创建 HD 密钥
  final seed = generateRandomBytes(16);
  final wallet = HDPrivateKey.fromSeed(seed);

  // 在 10' 处派生硬化的密钥
  final hardened = wallet.deriveHardened(10);

  // 在 4 处进一步派生密钥
  final key1 = hardened.derive(4);

  // 密钥也可以从路径派生
  final key2 = wallet.derivePath("m/10'/4");

  // 可以比较公钥
  if (key1.publicKey == key2.publicKey) {
    print("派生的密钥匹配");
  }

  // 生成具有主网前缀的 P2PKH 地址
  final address = P2PKHAddress.fromPublicKey(
    key1.publicKey,
    version: Network.mainnet.p2pkhPrefix,
  );
  print("地址: $address");

  // 使用密钥对消息进行签名并使用地址验证

  final msg = "Hello World!";
  final msgSig = MessageSignature.sign(
    key: key1.privateKey,
    message: msg,
    prefix: Network.mainnet.messagePrefix,
  );

  if (
    msgSig.verifyAddress(
      address: address,
      message: msg,
      prefix: Network.mainnet.messagePrefix,
    )
  ) {
    print("消息签名有效: $msgSig");
  }

  // 创建一个花费 P2PKH 输入到前面生成的地址的交易
  // 版本默认设置为 3,锁时间设置为 0。

  print("\nP2PKH 交易");

  // hexToBytes 是一个方便的功能。
  final prevHash = hexToBytes(
    "32d1f1cf811456c6da4ef9e1cb7f8bb80c4c5e9f2d2c3d743f2b68a9c6857823",
  );

  final tx = Transaction(
    inputs: [
      P2PKHInput(prevOut: OutPoint(prevHash, 1), publicKey: key1.publicKey),
    ],
    outputs: [
      Output.fromAddress(BigInt.from(2000000), address),
    ],
  );

  if (!tx.complete) {
    print("未签名交易不完整");
  }

  // 使用私钥签署输入。签名交易作为新的对象返回,因为库中的大多数对象都是不可变的。
  final signedTx = tx.sign(inputN: 0, key: key1.privateKey);

  if (signedTx.complete) {
    print("签名交易完整");
  }

  print("Txid = ${signedTx.txid}");
  print("Tx hex = ${signedTx.toHex()}");

  print("\nTaproot");

  // 使用内部密钥创建 Taproot 对象
  final taproot = Taproot(internalKey: key1.publicKey);

  // 打印 P2TR 地址
  final trAddr = P2TRAddress.fromTaproot(
    taproot, hrp: Network.mainnet.bech32Hrp,
  );
  print("Taproot 地址: $trAddr");

  // 使用密钥路径对 TR 输入进行签名,发送到相同的 TR 输出

  final trOutput = Output.fromProgram(
    BigInt.from(123456),
    P2TR.fromTaproot(taproot),
  );

  final trTx = Transaction(
    inputs: [TaprootKeyInput(prevOut: OutPoint(prevHash, 1))],
    outputs: [trOutput],
  ).sign(
    inputN: 0,
    // 私钥必须由 Taproot 对象调整
    key: taproot.tweakPrivateKey(key1.privateKey),
    prevOuts: [trOutput],
  );

  print("TR Tx hex = ${trTx.toHex()}");
}

更多关于Flutter数字货币处理插件digicoinlib的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter数字货币处理插件digicoinlib的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,以下是如何在Flutter项目中集成和使用digicoinlib插件来处理数字货币的示例代码。digicoinlib是一个假设的Flutter插件,用于处理数字货币操作,如获取余额、发送交易等。由于digicoinlib并非一个真实存在的官方插件,以下代码示例将基于一个假设的API和功能。

步骤 1: 添加依赖

首先,你需要在pubspec.yaml文件中添加digicoinlib作为依赖。

dependencies:
  flutter:
    sdk: flutter
  digicoinlib: ^0.1.0  # 假设版本号

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

步骤 2: 初始化插件

在你的Dart代码中,你需要初始化digicoinlib插件。通常,这会在你的主文件(如main.dart)或某个服务文件中完成。

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

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

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

class MyHomePage extends StatefulWidget {
  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  // 初始化Digicoin客户端
  late DigicoinClient digicoinClient;

  @override
  void initState() {
    super.initState();
    // 假设需要API密钥和钱包地址来初始化客户端
    String apiKey = "your_api_key";
    String walletAddress = "your_wallet_address";
    digicoinClient = DigicoinClient(apiKey: apiKey, walletAddress: walletAddress);
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Digicoin Wallet'),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Text('Checking Balance...'),
            ElevatedButton(
              onPressed: () async {
                try {
                  double balance = await digicoinClient.getBalance();
                  ScaffoldMessenger.of(context).showSnackBar(
                    SnackBar(content: Text("Balance: $balance DIGI")),
                  );
                } catch (e) {
                  ScaffoldMessenger.of(context).showSnackBar(
                    SnackBar(content: Text("Error fetching balance: $e")),
                  );
                }
              },
              child: Text('Get Balance'),
            ),
            SizedBox(height: 20),
            ElevatedButton(
              onPressed: () async {
                try {
                  String recipientAddress = "recipient_wallet_address";
                  double amount = 1.0; // 发送1 DIGI
                  String txId = await digicoinClient.sendTransaction(recipientAddress, amount);
                  ScaffoldMessenger.of(context).showSnackBar(
                    SnackBar(content: Text("Transaction ID: $txId")),
                  );
                } catch (e) {
                  ScaffoldMessenger.of(context).showSnackBar(
                    SnackBar(content: Text("Error sending transaction: $e")),
                  );
                }
              },
              child: Text('Send Transaction'),
            ),
          ],
        ),
      ),
    );
  }
}

// 假设DigicoinClient类的定义如下
class DigicoinClient {
  String apiKey;
  String walletAddress;

  DigicoinClient({required this.apiKey, required this.walletAddress});

  // 获取余额的异步方法
  Future<double> getBalance() async {
    // 这里应该有一个HTTP请求来获取余额
    // 例如使用dio或http库
    // 这是一个假设的返回值
    return 100.0; // 假设余额为100 DIGI
  }

  // 发送交易的异步方法
  Future<String> sendTransaction(String recipientAddress, double amount) async {
    // 这里应该有一个HTTP请求来发送交易
    // 例如使用dio或http库
    // 这是一个假设的交易ID
    return "tx123456789"; // 假设交易ID
  }
}

注意事项

  1. 安全性:在实际应用中,不要将API密钥和钱包地址硬编码在客户端代码中。考虑使用安全存储机制,如Keychain(iOS)或KeyStore(Android)。
  2. 错误处理:示例代码中的错误处理非常基础。在实际应用中,你可能需要更详细的错误处理逻辑。
  3. 依赖管理:确保你使用的库是最新版本的,并且检查其安全性。
  4. 网络请求:示例代码没有实际进行网络请求。在实际应用中,你需要使用HTTP客户端库(如dio或http)来与你的后端服务通信。

由于digicoinlib是一个假设的插件,你需要根据实际的插件文档和API来调整代码。

回到顶部