123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228 |
- import 'dart:convert';
- import 'dart:math';
- import 'dart:typed_data';
- import 'package:bs58check/bs58check.dart';
- // import 'package:dartsv/dartsv.dart' as dartsv;
- import 'package:flutter_bitcoin/flutter_bitcoin.dart';
- import 'package:flutter_wallet/tools/YSNetWork.dart';
- import 'package:flutter_wallet/tools/YSTools.dart';
- import 'package:http/http.dart' as http;
- import 'package:web3dart/web3dart.dart' as web3;
- import 'YSAes.dart';
- const baseUrl = 'https://btcscan.org/api/';
- class YSBtc{
- static Future<String> getBalance(String address) async{
- try{
- final utxosRes = await http.get(Uri.parse('https://blockchain.info/unspent?active=$address'));
- double balance = 0.00;
- List utxos = jsonDecode(utxosRes.body)['unspent_outputs']??[];
- for (var element in utxos) {
- balance += element['value']??0.00;
- }
- // final response = await http.get(Uri.parse('https://blockchain.info/q/addressbalance/$address'));
- balance = balance / 100000000;
- LogUtil.d('余额: $balance BTC');
- return '$balance';
- }catch(error){
- LogUtil.d('余额: https://blockchain.info/q/addressbalance/$address BTC');
- return '0.0';
- }
- }
- static Future<String> transferData({required String from,required String to,required String private,required String amount}) async{
- LogUtil.d(YSData().rpc);
- LogUtil.d('transferData======$from====$to====$private====$amount');
- try{
- // transferContractData3(from: from, to: to, private: private, amount: amount);
- // return '';
- // transferData2(from: from, to: to, private: private, amount: amount);
- // return '';
- // 创建一个网络对象
- final network = bitcoin;
- final utxosRes = await http.get(Uri.parse('https://blockchain.info/unspent?active=$from'));
- List utxos = jsonDecode(utxosRes.body)['unspent_outputs']??[];
- if(utxos.isNotEmpty){
- LogUtil.d('transferData======$utxos');
- Map utxo = utxos.first;
- int total = utxo['value'];
- final txb = TransactionBuilder(network: network);
- // int number = (double.parse(amount) * pow(10, 8))~/1;
- // 添加输入(来自哪个地址的比特币)
- txb.addInput(utxo['tx_hash'], 0);
- // LogUtil.d('transferData======$number');
- // 添加输出(要发送到哪个地址)
- Uint8List toList = base58.decode(to);
- // 计算交易费
- const byteCount = 180 + (2 * 34) + 10;
- const feeSatoshis = byteCount * 15;
- // //console.log(feeSatoshis)
- // // 添加输出
- int sendSatoshis = total - feeSatoshis;
- txb.addOutput(toList, sendSatoshis);
- // 创建一个私钥对象
- final keyPair = ECPair.fromWIF(private, network: network);
- // return '';
- // 对交易进行签名
- txb.sign(vin: 0, keyPair: keyPair);
- // 构建交易
- final tx = txb.build();
- // 打印交易的十六进制表示
- LogUtil.d('交易数据: ${tx.ins} ====== ${tx.outs}');
- final rawTx = tx.toHex();
- final url = YSData().rpc;
- final headers = {'Content-Type': 'application/json'};
- final body = jsonEncode({
- 'jsonrpc': '1.0',
- 'id': 'curltest',
- 'method': 'sendrawtransaction',
- 'params': [rawTx]
- });
- final response = await http.post(Uri.parse(url), headers: headers, body: body);
- final data = jsonDecode(response.body);
- LogUtil.d('交易结果: $data');
- if(data['result']!=null){
- return data['result'];
- }else{
- return '';
- }
- }else{
- return '';
- }
- }catch(error){
- LogUtil.d('transferData======$error');
- return '';
- }
- }
- static Future<String> transferData3({required String from,required String to,required String private,required String amount}) async{
- LogUtil.d('transferData3======$from====$to====$private====$amount');
- Map request = {};
- String privateS = YSAes.aesEncode3('${private}_${DateTime.now().microsecond}');
- request['prikey'] = privateS;
- request['to'] = to;
- int number = (double.parse(amount) * pow(10, 8))~/1;
- request['value'] = number;
- Map dict = await YSNetWork.httpNetwork(api: 'bithash', request: request);
- if(dict.isNotEmpty){
- Map data = dict['data']??'';
- final pushTxRes = await http.post(Uri.parse('https://blockchain.info/pushtx'), body: {'tx': data['hex']});
- LogUtil.d('Transaction ID: https://blockchain.info/pushtx ======= ${pushTxRes.body}');
- // Map body = jsonDecode(pushTxRes.body);
- if(pushTxRes.body=='Transaction Submitted'){
- return data['hash']??'';
- }else{
- return '';
- }
- }
- return '';
- }
- static Future<String> transferContractData3({required String from,required String to,required String private,required String amount}) async{
- LogUtil.d('transferContractData3======$from====$to====$private====$amount');
- Map request = {};
- String privateS = YSAes.aesEncode3('${private}_${DateTime.now().microsecond}');
- request['prikey'] = privateS;
- request['to'] = to;
- int number = (double.parse(amount) * pow(10, 8))~/1;
- request['value'] = number;
- Map dict = await YSNetWork.httpNetwork(api: 'bithash', request: request);
- if(dict.isNotEmpty){
- Map data = dict['data']??'';
- final pushTxRes = await http.post(Uri.parse('ttps://api.omniwallet.org/v1/transaction/pushtx/'), body: {'tx': data['hex']});
- LogUtil.d('Transaction ID: ttps://api.omniwallet.org/v1/transaction/pushtx/ ======= ${pushTxRes.body}');
- // Map body = jsonDecode(pushTxRes.body);
- if(pushTxRes.body=='Transaction Submitted'){
- return data['hash']??'';
- }else{
- return '';
- }
- }
- return '';
- // final httpClient = http.Client();
- // final ethClient = web3.Web3Client('https://mainnet.infura.io/v3/YOUR_INFURA_PROJECT_ID', httpClient);
- // final tokenAddress = web3.EthereumAddress.fromHex('TOKEN_CONTRACT_ADDRESS');
- // final tokenAbi = jsonDecode('TOKEN_CONTRACT_ABI');
- // final tokenContract = web3.DeployedContract(web3.ContractAbi.fromJson(tokenAbi, 'Token'), tokenAddress);
- // final transferFunction = tokenContract.function('transfer');
- // final transferArgs = [web3.EthereumAddress.fromHex('RECIPIENT_ADDRESS'), BigInt.from(100)]; // 将100个代币转账给RECIPIENT_ADDRESS
- // final transferTx = await ethClient.sendTransaction(
- // credentials,
- // web3.Transaction.callContract(
- // contract: tokenContract,
- // function: transferFunction,
- // parameters: transferArgs,
- // ),
- // );
- }
- static transferData2({required String from,required String to,required String private,required String amount}) async {
- final config = {
- 'privateKey': private,
- 'network': 'bitcoin', // 更改为主网络
- 'toAddress': to,
- 'fromAddress': from,
- 'satoshisPerByte': double.parse(amount),
- 'fee': 1000,
- };
- final network = config['network'] == 'testnet' ? testnet : bitcoin;
- final keyPair = ECPair.fromWIF('${config['privateKey']}', network: network);
- // final psbt = Psbt(network: network);
- final txb = TransactionBuilder(network: network);
- // 获取UTXO
- final utxosRes = await http.get(Uri.parse('https://blockchain.info/unspent?active=${config['fromAddress']}'));
- final utxos = jsonDecode(utxosRes.body)['unspent_outputs'];//
- LogUtil.d('transferData======$utxos');
- // for (var i = 0; i < utxos.length; i++) {
- // Map value = txb.sign(keyPair: keyPair, vin: i);
- // LogUtil.d('transferData======$value');
- // }
- // return;
- int totalSatoshis = 0;
- for (var utxo in utxos) {
- // final txRes = await http.get(Uri.parse('https://blockchain.info/rawtx/${utxo['tx_hash_big_endian']}?format=hex'));
- // final nonWitnessUtxo = HEX.decode(txRes.body);
- totalSatoshis += txb.addInput(utxo['tx_hash'], utxo['tx_output_n']);
- // txb.addInput(txHash, vout)
- // psbt.addInput({
- // 'hash': utxo['tx_hash_big_endian'],
- // 'index': utxo['tx_output_n'],
- // 'nonWitnessUtxo': nonWitnessUtxo,
- // });
- //
- // totalSatoshis += int.parse('${utxo['value']}');
- }
- //
- // 计算交易费
- final byteCount = (utxos.length * 180) + (2 * 34) + 10;
- final feeSatoshis = byteCount * config['satoshisPerByte'];
- // 添加输出
- final sendSatoshis = totalSatoshis - feeSatoshis;
- txb.addOutput(config['toAddress'], sendSatoshis~/1);
- // psbt.addOutput({
- // 'address': config['toAddress'],
- // 'value': sendSatoshis,
- // });
- // 签名所有的输入
- for (var i = 0; i < utxos.length; i++) {
- txb.sign(vin: i, keyPair: keyPair);
- // psbt.signInput(i, keyPair);
- }
- // 完成交易并将其转换为十六进制
- // psbt.finalizeAllInputs();
- // final txHex = psbt.extractTransaction().toHex();
- //
- // // 广播交易
- // final pushTxRes = await http.post(Uri.parse('https://blockchain.info/pushtx'), body: {'tx': txHex});
- //
- // LogUtil.d('Transaction ID: ${pushTxRes.body}');
- }
- }
|