Flutter比特币签名插件bip340的使用
Flutter比特币签名插件bip340的使用
插件介绍
bip340
是一个用于实现 BIP-340 Schnorr 签名方案的基本签名和验证功能的 Dart 插件。该插件通过了 BIP-340 测试向量(dart test
可以运行这些测试),但请注意,这并不是安全的加密方式,请勿用于存储比特币。
功能说明
bip340
提供了以下三个主要功能:
-
签名 (
sign
)
生成符合 BIP-340 方案的 Schnorr 签名。String sign(String privateKey, String message, String aux)
privateKey
:必须是 32 字节的小写十六进制编码字符串,即 64 个字符。message
:必须是小写十六进制编码的消息哈希(实际消息的哈希)。aux
:必须是 32 字节的随机字节,在签名时生成。- 返回值:返回一个 64 字节的小写十六进制编码的签名字符串,即 128 个字符。
-
验证 (
verify
)
验证一个符合 BIP-340 方案的 Schnorr 签名。bool verify(String publicKey, String message, String signature)
publicKey
:必须是 32 字节的小写十六进制编码字符串,即 64 个字符(如果你有一个 33 字节的公钥,只需去掉第一个字节)。message
:必须是小写十六进制编码的消息哈希(实际消息的哈希)。signature
:必须是 64 字节的小写十六进制编码的签名字符串,即 128 个字符。- 返回值:如果签名有效,返回
true
,否则返回false
。
-
生成公钥 (
getPublicKey
)
从私钥生成公钥。String getPublicKey(String privateKey)
privateKey
:必须是 32 字节的十六进制编码字符串,即 64 个字符。- 返回值:返回一个 32 字节的十六进制编码的公钥字符串。
完整示例 Demo
下面是一个完整的 Flutter 示例,展示了如何使用 bip340
插件进行签名、验证和生成公钥。
1. 添加依赖
首先,在 pubspec.yaml
文件中添加 bip340
依赖:
dependencies:
bip340: ^latest_version
2. 创建主文件 main.dart
import 'package:flutter/material.dart';
import 'package:bip340/bip340.dart';
import 'dart:convert'; // 用于 Base64 编码/解码
import 'dart:math'; // 用于生成随机数
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
[@override](/user/override)
Widget build(BuildContext context) {
return MaterialApp(
title: 'BIP340 Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: BIP340Demo(),
);
}
}
class BIP340Demo extends StatefulWidget {
[@override](/user/override)
_BIP340DemoState createState() => _BIP340DemoState();
}
class _BIP340DemoState extends State<BIP340Demo> {
final TextEditingController _privateKeyController = TextEditingController();
final TextEditingController _messageController = TextEditingController();
final TextEditingController _signatureController = TextEditingController();
final TextEditingController _publicKeyController = TextEditingController();
String _result = '';
// 生成 32 字节的随机辅助数据 (aux)
String generateRandomAux() {
final random = Random.secure();
final bytes = List<int>.generate(32, (index) => random.nextInt(256));
return bytes.map((byte) => byte.toRadixString(16).padLeft(2, '0')).join();
}
// 生成 32 字节的随机私钥
String generateRandomPrivateKey() {
final random = Random.secure();
final bytes = List<int>.generate(32, (index) => random.nextInt(256));
return bytes.map((byte) => byte.toRadixString(16).padLeft(2, '0')).join();
}
// 签名
void signMessage() {
final privateKey = _privateKeyController.text;
final message = _messageController.text;
final aux = generateRandomAux(); // 生成随机辅助数据
if (privateKey.length != 64 || message.length != 64) {
setState(() {
_result = '私钥或消息格式不正确';
});
return;
}
try {
final signature = bip340.sign(privateKey, message, aux);
setState(() {
_signatureController.text = signature;
_result = '签名成功: $signature';
});
} catch (e) {
setState(() {
_result = '签名失败: $e';
});
}
}
// 验证签名
void verifySignature() {
final publicKey = _publicKeyController.text;
final message = _messageController.text;
final signature = _signatureController.text;
if (publicKey.length != 64 || message.length != 64 || signature.length != 128) {
setState(() {
_result = '公钥、消息或签名格式不正确';
});
return;
}
try {
final isValid = bip340.verify(publicKey, message, signature);
setState(() {
_result = isValid ? '签名验证成功' : '签名验证失败';
});
} catch (e) {
setState(() {
_result = '验证失败: $e';
});
}
}
// 生成公钥
void generatePublicKey() {
final privateKey = _privateKeyController.text;
if (privateKey.length != 64) {
setState(() {
_result = '私钥格式不正确';
});
return;
}
try {
final publicKey = bip340.getPublicKey(privateKey);
setState(() {
_publicKeyController.text = publicKey;
_result = '公钥生成成功: $publicKey';
});
} catch (e) {
setState(() {
_result = '生成公钥失败: $e';
});
}
}
[@override](/user/override)
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('BIP340 Demo'),
),
body: Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
children: [
TextField(
controller: _privateKeyController,
decoration: InputDecoration(labelText: '私钥 (64 字节)'),
maxLength: 64,
),
SizedBox(height: 10),
TextField(
controller: _messageController,
decoration: InputDecoration(labelText: '消息哈希 (64 字节)'),
maxLength: 64,
),
SizedBox(height: 10),
TextField(
controller: _signatureController,
decoration: InputDecoration(labelText: '签名 (128 字节)'),
maxLength: 128,
),
SizedBox(height: 10),
TextField(
controller: _publicKeyController,
decoration: InputDecoration(labelText: '公钥 (64 字节)'),
maxLength: 64,
),
SizedBox(height: 20),
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
ElevatedButton(
onPressed: signMessage,
child: Text('签名'),
),
ElevatedButton(
onPressed: verifySignature,
child: Text('验证签名'),
),
ElevatedButton(
onPressed: generatePublicKey,
child: Text('生成公钥'),
),
],
),
SizedBox(height: 20),
Text(
_result,
style: TextStyle(fontSize: 16, color: _result.startsWith('签名') ? Colors.green : Colors.red),
),
],
),
),
);
}
}
更多关于Flutter比特币签名插件bip340的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter比特币签名插件bip340的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
当然,下面是一个关于如何在Flutter项目中使用bip340
(即Taproot/Schnorr签名的BIP 340)进行比特币签名的代码示例。我们将使用dart_bitcoin
库,这是一个流行的Dart比特币工具库,它包含了BIP 340相关的实现。
首先,确保你已经在pubspec.yaml
文件中添加了dart_bitcoin
依赖:
dependencies:
flutter:
sdk: flutter
dart_bitcoin: ^x.y.z # 请替换为最新版本号
然后,运行flutter pub get
来获取依赖。
接下来,是一个简单的示例代码,展示如何使用BIP 340进行比特币签名:
import 'dart:typed_data';
import 'package:dart_bitcoin/dart_bitcoin.dart';
import 'package:dart_bitcoin/src/bip32/bip32.dart';
import 'package:dart_bitcoin/src/bip340/bip340.dart';
import 'package:pointycastle/export.dart';
void main() {
// 私钥(示例,实际使用时请替换为你的私钥)
Uint8List privateKey = Uint8List.fromList(hex.decode('0000000000000000000000000000000000000000000000000000000000000001'));
// 消息(待签名的数据,通常是哈希值)
Uint8List messageHash = Uint8List.fromList(hex.decode('e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855')); // 这是一个空的SHA-256哈希值
// 使用私钥生成公钥
ECPoint publicKey = ECPrivateKey(privateKey).publicKey;
// 创建BIP340签名对象
BIP340Signer signer = BIP340Signer(privateKey);
// 生成签名
BIP340Signature signature = signer.sign(messageHash);
// 打印公钥和签名
print('Public Key: ${publicKey.y.toStringAsFixed(0).padLeft(64, '0')}');
print('Signature: ${signature.r.toStringAsFixed(0).padLeft(64, '0')}${signature.s.toStringAsFixed(0).padLeft(64, '0')}');
// 验证签名
bool isValid = BIP340Signer.verify(signature, messageHash, publicKey);
print('Signature is valid: $isValid');
}
解释:
- 私钥:这里我们用一个示例私钥。在实际应用中,你应该使用安全的私钥管理方式。
- 消息哈希:待签名的消息通常是一个哈希值。在这个例子中,我们使用了一个空的SHA-256哈希值。
- 生成公钥:使用私钥生成相应的公钥。
- 创建BIP340签名对象:使用私钥创建一个BIP340签名器。
- 生成签名:对消息哈希进行签名。
- 打印公钥和签名:输出公钥和生成的签名。
- 验证签名:验证生成的签名是否正确。
注意:
dart_bitcoin
库可能会更新,API可能会有所变化。请查阅最新的文档和源代码以获取最准确的信息。- 实际使用时,私钥管理至关重要,请确保私钥的安全存储和访问。
- 本示例仅用于教育目的,不建议在生产环境中直接使用。
希望这个示例能帮助你理解如何在Flutter项目中使用BIP 340进行比特币签名。