import 'dart:math'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:flutter_wallet/base/YSBase.dart'; import 'package:flutter_wallet/generated/l10n.dart'; import 'package:flutter_wallet/login/view/YSHelpView.dart'; import 'package:flutter_wallet/setting/YSAlwayAddress.dart'; import 'package:flutter_wallet/tools/YSAlertView.dart'; import 'package:flutter_wallet/tools/YSBip.dart'; import 'package:flutter_wallet/tools/YSColors.dart'; import 'package:flutter_wallet/tools/YSNetWork.dart'; import 'package:flutter_wallet/tools/YSTools.dart'; import 'package:flutter_wallet/wallet/YSTansDetail.dart'; import 'package:flutter_wallet/wallet/YSWalletManager.dart'; import 'package:flutter_wallet/wallet/view/YSWalletMineTokenChoose.dart'; import 'package:web3dart/web3dart.dart'; import 'package:http/http.dart'; import '../tools/YSBip2.dart'; import '../tools/YSBtc.dart'; import '../tools/YSSqflite.dart'; import '../tools/YSTron.dart'; class YSWalletTransfer extends StatefulWidget { final String? address; const YSWalletTransfer({Key? key, this.address}) : super(key: key); @override YSWalletTransferState createState() => YSWalletTransferState(); } class YSWalletTransferState extends State { Map _wallet = {}; List _walletArray = []; List _netArray = []; int _selectedIndex = 0; String _address = ''; String _number = ''; double _fee = 0.000021; Map _token = {}; double _gas = 100000; String _hash = ''; @override void initState() { _address = widget.address??''; _getWalletData(); _getTokenData(); super.initState(); } _getGasPrice() async{ if(_token['address']==YSData().wallet['public']){ _gas = 21000; }else{ _gas = 100000; } Web3Client? client = Web3Client(YSData().rpc, Client()); EtherAmount etherAmount = await client.getGasPrice(); double value1 = etherAmount.getValueInUnit(EtherUnit.gwei); double value2 = value1+1; double value3 = value2+1; double numValue1 = value1*_gas/pow(10, 9); double numValue2 = value2*_gas/pow(10, 9); double numValue3 = value3*_gas/pow(10, 9); _netArray = [ {'image':'步行','speed':S.current.MAN,'price':numValue1,'time':'1${S.current.FENZHONG}','dollar':'0.015'}, {'image':'自行车','speed':S.current.TUIJIAN,'price':numValue2,'time':'15${S.current.MIAO}','dollar':'0.030'}, {'image':'飞行','speed':S.current.KUAI,'price':numValue3,'time':'3${S.current.MIAO}','dollar':'0.045'} ]; _fee = _netArray[0]['price']; setState(() {}); } _getWalletData() async{ YSSqflite sqflite = YSSqflite().init(); _walletArray = await sqflite.rawQuery(); if(!mounted)return; if(YSData().wallet.isNotEmpty){ // _wallet = YSData().wallet; // _address = _wallet['public']; // setState(() {}); } } _getTokenData() async{ YSSqflite2 sqflite2 = YSSqflite2().init(); List tokenArray = await sqflite2.rawQuery(); // LogUtil.d('tokenArray======$tokenArray'); // LogUtil.d('contAddress======${YSData().contAddress}'); if(!mounted)return; if(tokenArray.isNotEmpty){ _token = tokenArray.firstWhere((element) => element['address']==YSData().contAddress,orElse: ()=>{}); if(_token.isEmpty){ _token = tokenArray.first; } setState(() {}); _getGasPrice(); } } @override Widget build(BuildContext context) { return YSBase( ysTitle: S.current.ZHUANZHANG, ysChild: Container( height: ysHeight(context)-ysTOP(context)-hsp(75), padding: EdgeInsets.only(left: hsp(20),right: hsp(20),top: hsp(15)), child: Column( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Text(S.current.JIESHOUDIZHI,style: YSColors.contentStyle(context),), GestureDetector( onTap: (){ ysShowBottomAlertView(context, Container( height: hsp(150), width: ysWidth(context), decoration: const BoxDecoration( color: Colors.white, borderRadius: BorderRadius.only(topLeft: Radius.circular(10),topRight: Radius.circular(10)) ), child: Column( children: [ Container( height: hsp(50), alignment: Alignment.center, child: Text('地 址 类 型',style: YSColors.titleStyle(context),), ), SizedBox( height: hsp(100), child: Column( children: [ Divider(height: hsp(1),color: YSColors.lineColor(context),), GestureDetector( onTap: (){ Navigator.pop(context); Navigator.of(context).push( CupertinoPageRoute(builder: (context){ return const YSWalletManager(isChoose: true,); }) ).then((value) { if(value!=null){ _wallet = value; _address = value['public']; _getGasPrice(); setState(() {}); } }); }, behavior: HitTestBehavior.opaque, child: Container( height: hsp(49), alignment: Alignment.center, child: Text('钱包',style: YSColors.contentStyle(context),), ), ), Divider(height: hsp(1),color: YSColors.lineColor(context),), GestureDetector( onTap: (){ Navigator.pop(context); Navigator.of(context).push( CupertinoPageRoute(builder: (context){ return const YSAlwayAddress(isChoose: true,); }) ).then((value) { if(value!=null){ _wallet = value; _address = value['address']; _getGasPrice(); setState(() {}); } }); }, behavior: HitTestBehavior.opaque, child: Container( height: hsp(49), alignment: Alignment.center, child: Text('常用地址',style: YSColors.contentStyle(context),), ), ), ], ), ) ], ), ),isBarr: true); }, behavior: HitTestBehavior.opaque, child: Row( children: [ Text(S.current.XUANZEQIANBAO,style: TextStyle(fontSize: zsp(14),color: const Color(0xFF3D5AFF)),), Icon(Icons.chevron_right,size: hsp(20),color: const Color(0xFF3D5AFF),) ], ), ) ], ), YSInputView(tips: S.current.QINGSHURUHUOXUANZENINDEMUBIAOQIANBAODIZHI,rightWidget: GestureDetector( onTap: () async{ _address = await YSCodeImage.scanCode(); setState(() {}); }, child: Image.asset(YSColors.imageStyle(context, '编组 23'),height: hsp(15),width: hsp(15),), ),valueSetter: (value){ _address = value; },value: _address,), SizedBox( height: hsp(50), child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Text(S.current.ZHUANZHANGSHULIANG,style: YSColors.contentStyle(context),), GestureDetector( onTap: (){ Navigator.of(context).push( CupertinoPageRoute(builder: (context){ return const YSWalletMineTokenChoose(); }) ).then((value){ if(value!=null){ _token = value; _getGasPrice(); setState(() {}); } }); }, behavior: HitTestBehavior.opaque, child: Row( children: [ Text(_token['name']??'',style: YSColors.content3Style(context),), Icon(Icons.chevron_right,size: hsp(20),color: YSColors.shadowColor(context),) ], ), ) ], ), ), Container( decoration: BoxDecoration( color: YSColors.containColor(context), borderRadius: const BorderRadius.all(Radius.circular(10)) ), child: Column( children: [ YSInputView(tips: S.current.QINGSHURUZHUANZHANGSHULIANG,isNumber: true,valueSetter: (value){ _number = value; }), Divider(color: YSColors.lineColor(context),height: hsp(1),indent: hsp(15),endIndent: hsp(15),), if(_token.isNotEmpty)Container( height: hsp(50), padding: EdgeInsets.only(left: hsp(15),right: hsp(15)), child: Row( children: [ Text(S.current.ZHANGHUYUE,style: YSColors.contentStyle(context),), Expanded( child: Container( alignment: Alignment.centerRight, child: _token['address']==YSData().wallet['public']?YSBalanceView( public: YSData().wallet['public'], style: YSColors.content3Style(context), ):YSBalanceView( public: _token['address'], style: YSColors.content3Style(context), type: 1, walletAddress: YSData().wallet['public'], key: Key(_token['address']), ), ) ) ], ), ) ], ), ), SizedBox( height: hsp(40), child: Row( children: [ Text('${S.current.WANGLUOFEI} ',style: YSColors.contentStyle(context),), GestureDetector( onTap: (){}, child: Image.asset(YSColors.imageStyle(context, '说明 (3)'),height: hsp(15),width: hsp(15),), ) ], ), ), Container( padding: EdgeInsets.all(hsp(15)), decoration: BoxDecoration( color: YSColors.containColor(context), borderRadius: const BorderRadius.all(Radius.circular(10)) ), child: GridView.builder( gridDelegate: SliverGridDelegateWithFixedCrossAxisCount( crossAxisCount: 4, childAspectRatio: ((ysWidth(context)-hsp(100))/4)/hsp(85), crossAxisSpacing: hsp(10) ), itemBuilder: (context,index){ Map item = {}; if(index<_netArray.length){ item = _netArray[index]; } return GestureDetector( onTap: (){ if(item.isEmpty){ }else{ _fee = item['price']; _selectedIndex = index; setState(() {}); } }, behavior: HitTestBehavior.opaque, child: Container( alignment: Alignment.center, decoration: BoxDecoration( border: Border.all(color: const Color(0xFFE9EEFF),width: hsp(1)), borderRadius: const BorderRadius.all(Radius.circular(5)) ), padding: EdgeInsets.only(top: hsp(5)), child: item.isEmpty?Center( child: Column( mainAxisSize: MainAxisSize.min, children: [ Image.asset(YSColors.imageStyle(context, '编组 3'),height: hsp(25),width: hsp(25),), Padding( padding: EdgeInsets.only(top: hsp(5)), child: Text(S.current.ZIDINGYI,style: TextStyle(color: YSColors.shadowColor(context),fontSize: zsp(12)),), ) ], ) ):Column( mainAxisSize: MainAxisSize.min, children: [ Image.asset(YSColors.imageStyle(context, item['image']),height: hsp(20),width: hsp(20),), Padding( padding: EdgeInsets.only(top: hsp(2),bottom: hsp(2)), child: SizedBox( height: hsp(10), child: Text(item['speed'],style: TextStyle(color: YSColors.shadowColor(context),fontSize: zsp(8)),), ), ), SizedBox( height: hsp(15),//\n\$${item['dollar']} child: Text('${item['price']}',style: TextStyle(color: YSColors.shadowColor(context),fontSize: zsp(8)),textAlign: TextAlign.center,), ), Container( height: hsp(25), color: Color(_selectedIndex==index?0xFFE9EEFF:0xFFF6F6F6), margin: EdgeInsets.only(top: hsp(4)), alignment: Alignment.center, child: Text(item['time'],style: TextStyle(color: YSColors.shadowColor(context),fontSize: zsp(8)),), ) ], ), ), ); }, shrinkWrap: true, padding: const EdgeInsets.all(0), physics: const NeverScrollableScrollPhysics(), itemCount: _netArray.length, ), ), // Container( // height: hsp(50), // width: ysWidth(context), // alignment: Alignment.centerRight, // child: GestureDetector( // onTap: (){}, // behavior: HitTestBehavior.opaque, // child: Row( // mainAxisSize: MainAxisSize.min, // children: [ // Text('高级模式',style: YSColors.content3Style(context),), // Icon(Icons.chevron_right,size: hsp(20),color: YSColors.shadowColor(context),) // ], // ), // ) // , // ) ], ), GestureDetector( onTap: () { if(_address.isEmpty){ ysFlutterToast('请选择转账地址'); return; } if(_address.isEmpty){ ysFlutterToast('请完善接收地址'); return; } if(_number.isEmpty){ ysFlutterToast('请填写转账数量'); return; } ysShowCenterAlertView(context, YSLoadView(funAction: _transferData,wallet: YSData().wallet,valueSetter: (type){ if(type==1&&_hash.isNotEmpty){ Map map = { 'from_addr':YSData().wallet['public'], 'to_addr':_address, 'hash':_hash, 'status':'2', 'type':'2', 'nonce':'0', 'amount':_number }; if(!mounted)return; Navigator.pop(context); Navigator.of(context).push( CupertinoPageRoute(builder: (context){ return YSTansDetail(item: map,tokenAddress: _token['address'],); }) ); } },),isTrans: false); }, child: Container( height: hsp(50), decoration: BoxDecoration( color: YSColors.buttonColor(context), borderRadius: const BorderRadius.all(Radius.circular(10)) ), alignment: Alignment.center, child: Text(S.current.QUEDING,style: YSColors.buttonStyle(context),), ), ) ], ), ), ); } Future _transferData() async{ Wbe3Api? web = await Wbe3Api().getInstances(); String public = YSData().wallet['public']; String private = YSData().wallet['private']; String tokenAddress = _token['address']; String address = _address; if(public.substring(0,1)=='T'){ if(!mounted) return false; if(tokenAddress==public){ String resultStr = await YSTron.transferData(context, from: public, to: address, private: private, amount: _number,); if(resultStr.isNotEmpty){ Map map = {}; map['public'] = YSData().wallet['public']??''; map['balance'] = await YSTron.getBalance(YSData().wallet['public']); if(!mounted)return false; YSBalanceManager.notifier(context,map); insertTable(resultStr); _hash = resultStr; return true; }else{ return false; } }else{ String resultStr = await YSTron.transferContractData( context, from: public, to: address, private: private, amount: _number, tokenId: _token['hid'], tokenAddress: tokenAddress ); if(resultStr.isNotEmpty){ Map map = {}; map['public'] = YSData().wallet['public']??''; map['balance'] = await YSTron.getBalance(YSData().wallet['public']); if(!mounted)return false; YSBalanceManager.notifier(context,map); insertTable(resultStr); _hash = resultStr; return true; }else{ return false; } } }else if(public.substring(0,1)=='3'){ String resultStr = ''; // LogUtil.d(tokenAddress); // LogUtil.d(public); // return false; if(true){//tokenAddress==public resultStr = await YSBtc.transferData3(from: public, to: address, private: private,amount: _number); }else{ resultStr = await YSBtc.transferContractData3(from: public, to: address, private: private,amount: _number); } if(resultStr.isNotEmpty){ Map map = {}; map['public'] = YSData().wallet['public']??''; map['balance'] = await YSBtc.getBalance(YSData().wallet['public']); if(!mounted)return false; YSBalanceManager.notifier(context,map); insertTable(resultStr); _hash = resultStr; return true; }else{ return false; } }else{ if(tokenAddress==public){ var feeI = _fee*pow(10, 9)/_gas; String feeS = '${feeI * pow(10, 9) ~/1}'; var result = await web?.signETHTransaction(public, address, private, _number,'$_gas',fee: feeS); String resultStr = '$result'; if(resultStr.isNotEmpty){ Map map = {}; map['public'] = YSData().wallet['public']??''; map['balance'] = await Wbe3Api.getBalance(YSData().wallet['public']); if(!mounted)return false; YSBalanceManager.notifier(context,map); insertTable(resultStr); _hash = resultStr; return true; }else{ return false; } }else{ bool? isCheck = await web?.setContaract(tokenAddress,decimal: 18); if(isCheck!){ var feeI = _fee*pow(10, 9)/_gas; String feeS = '${feeI * pow(10, 9) ~/1}'; var result = await web?.tokenTransfer(public, address, private, feeS,_number,'$_gas'); String resultStr = '$result'; if(!mounted)return false; if(resultStr.isNotEmpty){ Map map = {}; map['public'] = tokenAddress; map['balance'] = await Wbe3Api().getTokenBalance(public,tokenAddress); if(!mounted)return false; YSBalanceManager.notifier(context,map); insertTable(resultStr); _hash = resultStr; return true; }else{ return false; } } } } return false; } insertTable(resultStr) async{ String public = YSData().wallet['public']; String address = _address; YSTansTable ysTansTable = YSTansTable().init(); await ysTansTable.rawInsert(from: public, to: address, hash: resultStr, status: '2', type: '2', nonce: '0', amount: _number); } }