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 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 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 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 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}'); } }