Flutter以太坊签名工具插件eth_sig_util的使用

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

Flutter以太坊签名工具插件eth_sig_util的使用

eth_sig_util 是一个从JavaScript移植而来的Ethereum签名工具库。这个库源自我们项目的需求,受到Dart版ethereum_util的启发,但后者不再活跃并且尚未支持V1和V4版本。

功能

  • 签署类型化消息(遵循EIP712标准)
  • 签署个人类型化消息(遵循EIP712标准)
  • 签署消息
  • 签署个人消息
  • 从签名中恢复公共地址(personal_ecRecover)

使用示例

以下是一个完整的Flutter示例代码,演示如何使用eth_sig_util插件进行不同类型的消息签署和恢复公共地址:

import 'package:eth_sig_util/eth_sig_util.dart';
import 'dart:convert';

void main() {
  // 示例私钥
  final String privateKey = '4af...bb0'; // 替换为实际的私钥

  // 示例JSON数据,用于类型化消息签署
  final Map<String, dynamic> typedData = {
    "types": {
      "EIP712Domain": [
        {"name": "name", "type": "string"},
        {"name": "version", "type": "string"},
        {"name": "chainId", "type": "uint256"},
        {"name": "verifyingContract", "type": "address"}
      ],
      "Person": [
        {"name": "name", "type": "string"},
        {"name": "wallet", "type": "address"}
      ],
      "Mail": [
        {"name": "from", "type": "Person"},
        {"name": "to", "type": "Person"},
        {"name": "contents", "type": "string"}
      ]
    },
    "primaryType": "Mail",
    "domain": {
      "name": "Ether Mail",
      "version": "1",
      "chainId": 1,
      "verifyingContract": "0xCcCCccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC"
    },
    "message": {
      "from": {
        "name": "Cow",
        "wallet": "0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826"
      },
      "to": {
        "name": "Bob",
        "wallet": "0xbBbBBBBbbBBbbbBBb.bbBbbBBbBBBbbBBbB"
      },
      "contents": "Hello, Bob!"
    }
  };

  // 将JSON数据转换为字符串
  final String jsonData = jsonEncode(typedData);

  // 签署类型化消息
  String signatureTypedData = EthSigUtil.signTypedData(
    privateKey: privateKey,
    jsonData: jsonData,
    version: TypedDataVersion.V4, // 使用V4版本
  );
  print('Signed Typed Data Signature: $signatureTypedData');

  // 签署个人类型化消息
  String signaturePersonalTypedData = EthSigUtil.signPersonalTypedData(
    privateKey: privateKey,
    jsonData: jsonData,
    version: TypedDataVersion.V4,
  );
  print('Signed Personal Typed Data Signature: $signaturePersonalTypedData');

  // 简单消息签署
  final List<int> message = utf8.encode('Hello, Ethereum!');
  String signatureMessage = EthSigUtil.signMessage(
    privateKey: privateKey,
    message: message,
  );
  print('Signed Message Signature: $signatureMessage');

  // 个人消息签署
  String signaturePersonalMessage = EthSigUtil.signPersonalMessage(
    privateKey: privateKey,
    message: message,
  );
  print('Signed Personal Message Signature: $signaturePersonalMessage');

  // 恢复公共地址
  String recoveredAddress = EthSigUtil.recoverSignature(
    signature: signatureMessage,
    message: message,
  );
  print('Recovered Address from Signature: $recoveredAddress');

  // 恢复个人消息的公共地址
  String recoveredPersonalAddress = EthSigUtil.recoverPersonalSignature(
    signature: signaturePersonalMessage,
    message: message,
  );
  print('Recovered Personal Address from Signature: $recoveredPersonalAddress');
}

更多关于Flutter以太坊签名工具插件eth_sig_util的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter以太坊签名工具插件eth_sig_util的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,以下是一个关于如何在Flutter中使用eth_sig_util插件进行以太坊签名的代码案例。eth_sig_util 是一个用于处理以太坊签名的实用工具库,通常用于验证消息的签名或生成签名。

首先,确保你的Flutter项目中已经添加了eth_sig_util依赖。在pubspec.yaml文件中添加以下依赖:

dependencies:
  flutter:
    sdk: flutter
  eth_sig_util: ^x.y.z  # 请将 x.y.z 替换为最新版本号

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

以下是一个完整的Flutter应用示例,展示如何使用eth_sig_util进行消息签名和验证签名:

import 'package:flutter/material.dart';
import 'package:eth_sig_util/eth_sig_util.dart';
import 'package:convert/convert.dart';
import 'dart:typed_data';
import 'dart:math';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('Ethereum Signature Utility Demo'),
        ),
        body: Center(
          child: SignAndVerifyDemo(),
        ),
      ),
    );
  }
}

class SignAndVerifyDemo extends StatefulWidget {
  @override
  _SignAndVerifyDemoState createState() => _SignAndVerifyDemoState();
}

class _SignAndVerifyDemoState extends State<SignAndVerifyDemo> {
  String privateKey =
      '0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef'; // 示例私钥
  String message = 'Hello, Ethereum!';
  String signature = '';
  bool isVerified = false;

  @override
  Widget build(BuildContext context) {
    return Column(
      mainAxisAlignment: MainAxisAlignment.center,
      children: <Widget>[
        Text('Message: $message'),
        SizedBox(height: 20),
        ElevatedButton(
          onPressed: () async {
            setState(() {
              signature = await signMessage(privateKey, message);
            });
          },
          child: Text('Sign Message'),
        ),
        SizedBox(height: 20),
        Text('Signature: $signature'),
        SizedBox(height: 20),
        ElevatedButton(
          onPressed: () async {
            setState(() {
              isVerified = await verifySignature(
                  privateKey, message, signature);
            });
          },
          child: Text('Verify Signature'),
        ),
        SizedBox(height: 20),
        Text('Is Verified: $isVerified'),
      ],
    );
  }

  Future<String> signMessage(String privateKey, String message) async {
    final address = ethAddress(hexToUint8List(privateKey.substring(2)));
    final hash = keccak256(utf8.encode(message));
    final signedHash = sign(hexToUint8List(privateKey), hash);
    return rlpEncodeList([address, signedHash.r, signedHash.s]).toHex();
  }

  Future<bool> verifySignature(String privateKey, String message, String signature) async {
    final address = ethAddress(hexToUint8List(privateKey.substring(2)));
    final hash = keccak256(utf8.encode(message));
    final sig = rlpDecode(Uint8List.fromList(hex.decode(signature))).cast<List<int>>();
    final recoveredAddress = recover(hash, sig[1], sig[2]);
    return recoveredAddress == address;
  }
}

// Helper functions to convert hex to Uint8List and vice versa
Uint8List hexToUint8List(String hex) {
  return Uint8List.fromList(hex.replaceAll('0x', '').allMatches('.{2}').map((match) {
    return int.parse(match[0], radix: 16);
  }).toList());
}

String Uint8ListToHex(Uint8List list) {
  return '0x' + list.map((e) => e.toRadixString(16).padLeft(2, '0')).join();
}

注意事项:

  1. 私钥管理:在真实应用中,请务必安全地管理私钥,不要硬编码在客户端代码中。
  2. 依赖版本:请确保使用最新版本的eth_sig_util库,以避免已知的问题和获得最新的功能。
  3. 错误处理:在实际应用中,请添加适当的错误处理逻辑,以处理可能的异常情况,例如无效的私钥或签名。

这个示例展示了如何在Flutter应用中使用eth_sig_util进行以太坊消息的签名和验证。你可以根据实际需求进一步扩展和修改这个示例。

回到顶部