UsdtWalletService.php 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705
  1. <?php
  2. // +----------------------------------------------------------------------
  3. // | LARAVEL8.0 框架 [ LARAVEL ][ RXThinkCMF ]
  4. // +----------------------------------------------------------------------
  5. // | 版权所有 2017~2021 LARAVEL研发中心
  6. // +----------------------------------------------------------------------
  7. // | 官方网站: http://www.laravel.cn
  8. // +----------------------------------------------------------------------
  9. // | Author: laravel开发员 <laravel.qq.com>
  10. // +----------------------------------------------------------------------
  11. namespace App\Services;
  12. use App\Models\CoinLogModel;
  13. use App\Models\MemberModel;
  14. use App\Services\Api\MemberService;
  15. use App\Services\Common\CoinLogService;
  16. use BitWasp\Bitcoin\Address\AddressCreator;
  17. use BitWasp\Bitcoin\Address\PayToPubKeyHashAddress;
  18. use BitWasp\Bitcoin\Bitcoin;
  19. use BitWasp\Bitcoin\Crypto\Random\Random;
  20. use BitWasp\Bitcoin\Key\Factory\HierarchicalKeyFactory;
  21. use BitWasp\Bitcoin\Key\Factory\PrivateKeyFactory;
  22. use BitWasp\Bitcoin\Mnemonic\Bip39\Bip39Mnemonic;
  23. use BitWasp\Bitcoin\Mnemonic\Bip39\Bip39SeedGenerator;
  24. use BitWasp\Bitcoin\Mnemonic\MnemonicFactory;
  25. use BitWasp\Bitcoin\Script\WitnessProgram;
  26. use GuzzleHttp\Client;
  27. use IEXBase\TronAPI\Tron;
  28. use Tron\Api;
  29. use Tron\TRC20;
  30. use Tron\TRX;
  31. use Web3\Personal;
  32. use Web3\Web3;
  33. use Web3p\EthereumUtil\Util;
  34. /**
  35. * USDT链管理-服务类
  36. * Class UsdtWalletService
  37. * @package App\Services
  38. */
  39. class UsdtWalletService extends BaseService
  40. {
  41. protected $apiUrl = '';
  42. protected $config = [];
  43. protected $apiUrls = [
  44. 'usdt_trx2_transfer_log' => '/v1/accounts/%s/transactions/trc20?limit=%s&only_to=%s&only_from=%s&only_confirmed=true&contract_address=TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t'
  45. ];
  46. /**
  47. * 构造函数
  48. * UsdtWalletService constructor.
  49. */
  50. public function __construct()
  51. {
  52. $this->memberModel = new MemberModel();
  53. $this->coinModel = new CoinLogModel();
  54. $this->config = ConfigService::make()->getConfigOptionByGroup(4);
  55. $this->apiUrl = isset($this->config['usdt_api_url']) ? $this->config['usdt_api_url'] : '';
  56. if (empty($this->config) || empty($this->apiUrl)) {
  57. return false;
  58. }
  59. }
  60. /**
  61. * 静态入口
  62. * @return UsdtWalletService|null
  63. */
  64. public static function make()
  65. {
  66. return parent::make(); // TODO: Change the autogenerated stub
  67. }
  68. /**
  69. * 获取TRC2.0钱包地址
  70. * @throws \Tron\Exceptions\TronErrorException
  71. */
  72. public function getTrxAddress()
  73. {
  74. $api = new Api(new Client(['base_uri' => $this->config['tron_api_url']]));
  75. $trxWallet = new TRX($api);
  76. $addressData = $trxWallet->generateAddress();
  77. $addressData = (array)$addressData;
  78. return ['wif' => $addressData['privateKey'], 'hexAddress' => $addressData['hexAddress'], 'address' => $addressData['address']];
  79. }
  80. /**
  81. * 获取TRC2.0钱包地址
  82. * @throws \Tron\Exceptions\TronErrorException
  83. */
  84. public function getTrxAddress1($userId = 0)
  85. {
  86. $api = new Api(new Client(['base_uri' => $this->config['tron_api_url']]));
  87. $trxWallet = new TRX($api);
  88. $addressData = $trxWallet->generateAddress();
  89. }
  90. /**
  91. * trx 转账
  92. * @param $to 进账账户
  93. * @param $amount 转账金额
  94. * @throws \Tron\Exceptions\TransactionException
  95. * @throws \Tron\Exceptions\TronErrorException
  96. */
  97. public function trxTransfer($to, $amount, $from='')
  98. {
  99. if ($amount <= 0) {
  100. $this->error = '2205';
  101. return false;
  102. }
  103. if (empty($this->config['tron_api_url'])) {
  104. $this->error = '2206';
  105. return false;
  106. }
  107. $headers = ["TRON-PRO-API-KEY" => $this->config['tron_api_key']];
  108. $api = new Api(new Client(['base_uri' => $this->config['tron_api_url'], 'headers' => $headers]));
  109. $trxWallet = new TRX($api);
  110. // 获取钱包参数
  111. try {
  112. $otcAddress = ConfigService::make()->getConfigByCode('trc_out_address');
  113. $otcAddressPrivate = ConfigService::make()->getConfigByCode('trc_out_private_key');
  114. if (empty($otcAddress) || empty($otcAddressPrivate)) {
  115. $this->error = '2203';
  116. return false;
  117. }
  118. $tron = new Tron();
  119. // 获取平台钱包hex
  120. $tron->setAddress($otcAddress);
  121. $otcAddress = $tron->getAddress();
  122. $tron->setAddress($to);
  123. $toAddress = $tron->getAddress();
  124. $from = new \Tron\Address($otcAddress['base58'], $otcAddressPrivate, $otcAddress['hex']);
  125. $to = new \Tron\Address($toAddress['base58'], '', $toAddress['hex']);
  126. $result = $trxWallet->transfer($from, $to, $amount);
  127. return $result;
  128. } catch (\Exception $exception) {
  129. $message = $exception->getMessage();
  130. $this->error = $message;
  131. return false;
  132. }
  133. }
  134. /**
  135. * usdt-trc2.0 转账
  136. * @param $to 进账账户
  137. * @param $amount 转账金额
  138. * @param $from 转账账户
  139. * @param $fromPrivate 转账账户私钥
  140. * @throws \Tron\Exceptions\TransactionException
  141. * @throws \Tron\Exceptions\TronErrorException
  142. */
  143. public function usdtTrcTransfer($to, $amount, $from='', $fromPrivate='')
  144. {
  145. if ($amount <= 0) {
  146. $this->error = '2205';
  147. return false;
  148. }
  149. if (empty($this->config['tron_api_url'])) {
  150. $this->error = '2206';
  151. return false;
  152. }
  153. $headers = ["TRON-PRO-API-KEY" => $this->config['tron_api_key']];
  154. $api = new Api(new Client(['base_uri' => $this->config['tron_api_url'], 'headers' => $headers]));
  155. $trxWallet = new TRC20($api, ['contract_address' => $this->config['tron_contract_address'], 'decimals' => 6]);
  156. // 获取钱包参数
  157. try {
  158. // 用出账钱包转账
  159. $otcAddress = $from? $from : ConfigService::make()->getConfigByCode('trc_out_address');
  160. $otcAddressPrivate = $from? $fromPrivate : ConfigService::make()->getConfigByCode('trc_out_private_key');
  161. if (empty($otcAddress) || empty($otcAddressPrivate)) {
  162. $this->error = '2203';
  163. return false;
  164. }
  165. $tron = new Tron();
  166. // 获取平台钱包hex
  167. $tron->setAddress($otcAddress);
  168. $otcAddress = $tron->getAddress();
  169. // 获取收款钱包hex
  170. $tron->setAddress($to);
  171. $toAddress = $tron->getAddress();
  172. $from = new \Tron\Address($otcAddress['base58'], $otcAddressPrivate, $otcAddress['hex']);
  173. $to = new \Tron\Address($toAddress['base58'], '', $toAddress['hex']);
  174. $result = $trxWallet->transfer($from, $to, $amount);
  175. return $result;
  176. } catch (\Exception $exception) {
  177. $message = $exception->getMessage();
  178. $this->error = $message;
  179. return false;
  180. }
  181. }
  182. /**
  183. * usdt-trc2.0 归集
  184. * @throws \Tron\Exceptions\TransactionException
  185. * @throws \Tron\Exceptions\TronErrorException
  186. */
  187. public function usdtTrcTrigger($force = false)
  188. {
  189. if (empty($this->config['tron_api_url'])) {
  190. $this->error = '2206';
  191. return false;
  192. }
  193. $headers = ["TRON-PRO-API-KEY" => $this->config['tron_api_key']];
  194. $api = new Api(new Client(['base_uri' => $this->config['tron_api_url'], 'headers' => $headers]));
  195. $trcWallet = new TRC20($api, ['contract_address' => $this->config['tron_contract_address'], 'decimals' => 6]);
  196. $trxWallet = new TRX($api, ['contract_address' => $this->config['tron_contract_address'], 'decimals' => 6]);
  197. // 获取钱包参数
  198. try {
  199. // 用收账钱包归集
  200. $otcAddress = ConfigService::make()->getConfigByCode('trc_address');
  201. $otcAddressPrivate = ConfigService::make()->getConfigByCode('trc_private_key');
  202. // 出账手续费钱包
  203. $otcOutAddress = ConfigService::make()->getConfigByCode('trc_out_address');
  204. $otcOutAddressPrivate = ConfigService::make()->getConfigByCode('trc_out_private_key');
  205. $triggerMin = ConfigService::make()->getConfigByCode('trade_trigger_min');
  206. $triggerTime = ConfigService::make()->getConfigByCode('trade_trigger_time');
  207. $triggerFree = ConfigService::make()->getConfigByCode('trade_trigger_free');
  208. $triggerFree = $triggerFree > 0 ? $triggerFree : 8;
  209. $triggerMin = $triggerMin > 0 ? $triggerMin : 0.1;
  210. $triggerTime = $triggerTime > 0 ? $triggerTime * 86400 : 86400;
  211. if (empty($otcAddress) || empty($otcAddressPrivate)) {
  212. $this->error = '2203';
  213. return false;
  214. }
  215. // 出账钱包
  216. if (empty($otcOutAddress) || empty($otcOutAddressPrivate)) {
  217. $this->error = '2203';
  218. return false;
  219. }
  220. $page = RedisService::get("caches:wallet:transferPage");
  221. $page = $page ? $page : 1;
  222. // 归集时间段为凌晨0点-5点
  223. if ((date('H:i') >= '05:00') && !$force) {
  224. $this->error = '不在归集时间段';
  225. return false;
  226. }
  227. if(RedisService::get("caches:wallet:triggerLock:{$page}")){
  228. $this->error = '不要频繁操作,30秒后重试';
  229. return false;
  230. }
  231. // 上锁
  232. RedisService::set("caches:wallet:triggerLock:{$page}", 1, rand(10, 30));
  233. $addrList = MemberService::make()->getTriggerAddressList($triggerMin, $page, 200);
  234. if (empty($addrList)) {
  235. RedisService::set("caches:wallet:transferPage", 1, 600);
  236. $this->error = '1019';
  237. return false;
  238. }
  239. // 平台钱包地址
  240. $count = 0;
  241. $failedCount = 0;
  242. $tron = new Tron();
  243. $tron->setAddress($otcAddress);
  244. $otcAddress = $tron->getAddress();
  245. $otcAddressData = new \Tron\Address($otcAddress['base58'], $otcAddressPrivate, $otcAddress['hex']);
  246. // 平台出账钱包地址
  247. $tron->setAddress($otcOutAddress);
  248. $otcOutAddress = $tron->getAddress();
  249. $otcOutAddressData = new \Tron\Address($otcOutAddress['base58'], $otcOutAddressPrivate, $otcOutAddress['hex']);
  250. $cacheKey = "caches:wallet:trigger:";
  251. foreach ($addrList as $v) {
  252. try {
  253. // 获取子钱包TRC-USDT余额
  254. $userId = isset($v['id']) ? $v['id'] : 0;
  255. $address = isset($v['trc_address']) ? $v['trc_address'] : '';
  256. $hexAddress = isset($v['trc_hexaddress']) ? $v['trc_hexaddress'] : '';
  257. $addressPrivate = isset($v['trc_wif']) ? $v['trc_wif'] : '';
  258. $triggerAddress = new \Tron\Address($address, $addressPrivate, $hexAddress);
  259. // 可归集的USDT余额
  260. $triggerUsdt = $trcWallet->balance($triggerAddress);
  261. // USDT 余额低于归集金额,则不归集
  262. if ($triggerUsdt < $triggerMin) {
  263. $failedCount++;
  264. $error = ['data' => $v, 'usdt' => $triggerUsdt, 'triggerMin' => $triggerMin, 'error' => '用户余额不足归集', 'date' => date('Y-m-d H:i:s')];
  265. RedisService::set($cacheKey . "U_{$userId}:error", $error, 7200);
  266. continue;
  267. }
  268. // 获取子钱包TRX余额
  269. $triggerTrx = $trxWallet->balance($triggerAddress);
  270. // 获取平台出账钱包TRX余额
  271. $otcOutTrxTotal = $trxWallet->balance($otcOutAddressData);
  272. // 如果子钱包和平台钱包TRX余额不足手续费,则不归集
  273. if ($triggerTrx < $triggerFree && $otcOutTrxTotal < $triggerFree) {
  274. $failedCount++;
  275. $error = ['data' => $v, 'usdt' => $triggerUsdt, 'triggerMin' => $triggerMin,'triggerTrx' => $triggerTrx, 'otcTrx' => $otcOutTrxTotal, 'error' => '平台钱包手续费不足', 'date' => date('Y-m-d H:i:s')];
  276. RedisService::set($cacheKey . "U_{$userId}:error", $error, 7200);
  277. continue;
  278. }
  279. // 如果子钱包TRX不足手续费8个,平台TRX充足则自动充值后下次调用时归集
  280. if ($triggerTrx < $triggerFree) {
  281. $failedCount++;
  282. $result = $this->trxTransfer($address, $triggerFree);
  283. $error = ['data' => $v, 'usdt' => $triggerUsdt, 'triggerMin' => $triggerMin, 'triggerTrx' => $triggerTrx,'transfer'=>$result, 'error' => '归集钱包手续费不足,先充值', 'date' => date('Y-m-d H:i:s')];
  284. RedisService::set($cacheKey . "U_{$userId}:catch", $error, 7200);
  285. continue;
  286. }
  287. // 满足归集条件处理
  288. $result = $trcWallet->transfer($triggerAddress, $otcAddressData, $triggerUsdt);
  289. RedisService::set($cacheKey . "U_{$userId}:result", ['data'=> $v,'result'=>$result,'msg'=>'归集已提交','date' => date('Y-m-d H:i:s')], 7200);
  290. $count++;
  291. } catch (\Exception $exception) {
  292. $failedCount++;
  293. RedisService::set($cacheKey . "U_{$userId}:exception", ['data'=> $v,'msg'=>$exception->getMessage(),'date' => date('Y-m-d H:i:s')], 7200);
  294. }
  295. }
  296. // 超出分页数,下次处理下一页
  297. if(count($addrList) >= 200){
  298. RedisService::set("caches:wallet:transferPage", $page + 1, 600);
  299. }
  300. if ($count > 0) {
  301. return ['success' => $count, 'fail' => $failedCount];
  302. } else {
  303. $this->error = 1021;
  304. return false;
  305. }
  306. } catch (\Exception $exception) {
  307. $this->error = $exception->getMessage();
  308. return false;
  309. }
  310. }
  311. /**
  312. * 监听USDT-TRC2.0转账记录并进账
  313. * @param $userId 用户ID
  314. * @param $address 用户钱包地址
  315. * @param int $coinType 币种:1-usdt
  316. * @param int $limit 转账记录数,最新的
  317. * @return array|false
  318. */
  319. public function getTrc20RechargeLog($userId, $address, $coinType = 1, $limit = 50)
  320. {
  321. if ($userId <= 0 || empty($address)) {
  322. $this->error = '1013';
  323. return false;
  324. }
  325. $url = sprintf($this->apiUrls['usdt_trx2_transfer_log'], $address, $limit, 'true', 'false');
  326. $headers = ["TRON-PRO-API-KEY" => $this->config['tron_api_key']];
  327. RedisService::set("caches:wallets:recharge_temp_{$userId}",['url'=>$this->config['tron_api_url'] . $url], 600);
  328. $result = curl_get($this->config['tron_api_url'] . $url, [], $headers, 10);
  329. $result = $result ? json_decode($result, true) : [];
  330. $datas = isset($result['data']) ? $result['data'] : [];
  331. $status = isset($result['success']) ? $result['success'] : '';
  332. if ($status != true || empty($datas)) {
  333. $this->error = '2207';
  334. return false;
  335. }
  336. $logs = [];
  337. $coinInMin = ConfigService::make()->getConfigByCode('trc_in_limit');
  338. $coinInMin = $coinInMin>0? $coinInMin : 0;
  339. foreach ($datas as $v) {
  340. $amount = isset($v['value']) ? intval($v['value']) : 0;
  341. $amount = moneyFormat($amount / 1000000, 6);
  342. $time = isset($v['block_timestamp']) ? intval($v['block_timestamp']) : 0;
  343. $txid = isset($v['transaction_id']) ? $v['transaction_id'] : '';
  344. if (!CoinLogService::make()->checkExists('txid', $txid) && $time > time() - 6 * 3600) {
  345. $balance = $this->memberModel->where(['id' => $userId])->value('usdt_num');
  346. $log = [
  347. 'user_id' => $userId,
  348. 'change_type' => 1,
  349. 'coin_type' => $coinType,
  350. 'contact_type' => 1,
  351. 'order_no' => get_order_num('OT'),
  352. 'from_address' => isset($v['from']) ? $v['from'] : '',
  353. 'to_address' => isset($v['to']) ? $v['to'] : '',
  354. 'txid' => $txid,
  355. 'num' => $amount,
  356. 'balance' => $balance,
  357. 'create_time' => intval($time / 1000),
  358. 'status' => 2,
  359. 'mark' => 1,
  360. ];
  361. if ($amount >= $coinInMin && $this->memberModel->where(['id' => $userId])->increment('usdt_num', $amount)) {
  362. $this->memberModel->where(['id' => $userId])->increment('trc_usdt', $amount);
  363. $log['status'] = 1;
  364. }
  365. $logs[] = $log;
  366. $this->coinModel->insert($log);
  367. }
  368. }
  369. return $logs;
  370. }
  371. /**
  372. * 监听USDT-TRC2.0充值记录并进账
  373. * @param $userId 用户ID
  374. * @param $address 用户钱包地址
  375. * @param int $coinType 币种:1-usdt
  376. * @param int $limit 转账记录数,最新的
  377. * @return array|false
  378. */
  379. public function getTrc20TransferLog($userId, $address, $coinType = 1, $limit = 50)
  380. {
  381. if ($userId <= 0 || empty($address)) {
  382. $this->error = '1013';
  383. return false;
  384. }
  385. $url = sprintf($this->apiUrls['usdt_trx2_transfer_log'], $address, $limit, 'false', 'true');
  386. $headers = ["TRON-PRO-API-KEY" => $this->config['tron_api_key']];
  387. RedisService::set("caches:wallets:transfer_temp_{$userId}",['url'=>$this->config['tron_api_url'] . $url], 600);
  388. $result = curl_get($this->config['tron_api_url'] . $url, [], $headers, 10);
  389. $result = $result ? json_decode($result, true) : [];
  390. $datas = isset($result['data']) ? $result['data'] : [];
  391. $status = isset($result['success']) ? $result['success'] : '';
  392. if ($status != true || empty($datas)) {
  393. $this->error = '2207';
  394. return false;
  395. }
  396. $logs = [];
  397. $coinOutMin = ConfigService::make()->getConfigByCode('trc_out_limit');
  398. $coinOutMin = $coinOutMin>0? $coinOutMin : 0;
  399. foreach ($datas as $v) {
  400. $amount = isset($v['value']) ? intval($v['value']) : 0;
  401. $amount = moneyFormat($amount / 1000000, 6);
  402. $time = isset($v['block_timestamp']) ? intval($v['block_timestamp']) : 0;
  403. $txid = isset($v['transaction_id']) ? $v['transaction_id'] : '';
  404. if (!CoinLogService::make()->checkExists('txid', $txid) && $time > time() - 6 * 3600) {
  405. $balance = $this->memberModel->where(['id' => $userId])->value('usdt_num');
  406. $log = [
  407. 'user_id' => $userId,
  408. 'change_type' => 2,
  409. 'coin_type' => $coinType,
  410. 'contact_type' => 1,
  411. 'order_no' => get_order_num('OT'),
  412. 'from_address' => isset($v['from']) ? $v['from'] : '',
  413. 'to_address' => isset($v['to']) ? $v['to'] : '',
  414. 'txid' => $txid,
  415. 'num' => $amount,
  416. 'balance' => $balance,
  417. 'create_time' => intval($time / 1000),
  418. 'status' => 2,
  419. 'mark' => 1,
  420. ];
  421. if ($amount>= $coinOutMin && $this->memberModel->where(['id' => $userId])->decrement('usdt_num', $amount)) {
  422. $this->memberModel->where(['id' => $userId])->decrement('trc_usdt', $amount);
  423. $log['status'] = 1;
  424. }
  425. $logs[] = $log;
  426. $this->coinModel->insert($log);
  427. }
  428. }
  429. return $logs;
  430. }
  431. /**
  432. * @param $address
  433. * @return false|float|string
  434. */
  435. public function getTrxBalance($address)
  436. {
  437. $cacheKey = "caches:wallet:balance:{$address}";
  438. if (RedisService::get($cacheKey)) {
  439. return false;
  440. }
  441. if (empty($address)) {
  442. $this->error = '1018';
  443. return false;
  444. }
  445. if (empty($this->config['tron_api_url'])) {
  446. $this->error = '2206';
  447. return false;
  448. }
  449. try {
  450. $headers = ["TRON-PRO-API-KEY" => $this->config['tron_api_key']];
  451. $api = new Api(new Client(['base_uri' => $this->config['tron_api_url'], 'headers' => $headers]));
  452. $trxWallet = new TRX($api, ['contract_address' => $this->config['tron_contract_address'], 'decimals' => 6]);
  453. $tron = new Tron();
  454. $tron->setAddress($address);
  455. $address = $tron->getAddress();
  456. $address = new \Tron\Address($address['base58'], '', $address['hex']);
  457. $result = $trxWallet->balance($address);
  458. return $result ? floatval($result) : '0.00';
  459. } catch (\Exception $exception) {
  460. $this->error = $exception->getMessage();
  461. return false;
  462. }
  463. }
  464. /**
  465. * @param $address
  466. * @return false|float|string
  467. */
  468. public function getUsdtByTrc20($address)
  469. {
  470. $cacheKey = "caches:wallet:balance:{$address}";
  471. if (RedisService::get($cacheKey)) {
  472. return false;
  473. }
  474. if (empty($address)) {
  475. $this->error = '1018';
  476. return false;
  477. }
  478. if (empty($this->config['tron_api_url'])) {
  479. $this->error = '2206';
  480. return false;
  481. }
  482. try {
  483. $headers = ["TRON-PRO-API-KEY" => $this->config['tron_api_key']];
  484. $api = new Api(new Client(['base_uri' => $this->config['tron_api_url'], 'headers' => $headers]));
  485. $trxWallet = new TRC20($api, ['contract_address' => $this->config['tron_contract_address'], 'decimals' => 6]);
  486. $tron = new Tron();
  487. $tron->setAddress($address);
  488. $address = $tron->getAddress();
  489. $address = new \Tron\Address($address['base58'], '', $address['hex']);
  490. $result = $trxWallet->balance($address);
  491. return $result ? floatval($result) : '0.00';
  492. } catch (\Exception $exception) {
  493. $this->error = $exception->getMessage();
  494. return false;
  495. }
  496. }
  497. /**
  498. * 获取ERC2.0钱包地址
  499. * @param string $type
  500. * @throws \BitWasp\Bitcoin\Exceptions\RandomBytesFailure
  501. */
  502. public function getErcAddress()
  503. {
  504. $random = new Random();
  505. $network = Bitcoin::getNetwork();
  506. $privateKeyFactory = new PrivateKeyFactory();
  507. $privateKey = $privateKeyFactory->generateCompressed($random);
  508. $publicKey = $privateKey->getPublicKey();
  509. // p2pkh 格式的地址
  510. $addressService = new PayToPubKeyHashAddress($publicKey->getPubKeyHash());
  511. // 将生成的钱包保存到数据库中
  512. $wif = $privateKey->toWif($network);
  513. $address = $addressService->getAddress();
  514. return ['wif' => $wif, 'hexAddress' => $this->getHash16Address($address), 'address' => $address];
  515. }
  516. /**
  517. * 获取ERC钱包地址
  518. * @throws \BitWasp\Bitcoin\Exceptions\RandomBytesFailure
  519. */
  520. public function getWalletAddress()
  521. {
  522. $math = Bitcoin::getMath();
  523. $network = Bitcoin::getNetwork();
  524. $random = new Random();
  525. // 生成随机数(initial entropy)
  526. $entropy = $random->bytes(Bip39Mnemonic::MIN_ENTROPY_BYTE_LEN);
  527. $bip39 = MnemonicFactory::bip39();
  528. // 通过随机数生成助记词
  529. $mnemonic = $bip39->entropyToMnemonic($entropy);
  530. echo "mnemonic: " . $mnemonic . PHP_EOL . PHP_EOL;// 助记词
  531. $seedGenerator = new Bip39SeedGenerator();
  532. // 通过助记词生成种子,传入可选加密串
  533. $seed = $seedGenerator->getSeed($mnemonic, 'otc');
  534. echo "seed: " . $seed->getHex() . PHP_EOL;
  535. $hdFactory = new HierarchicalKeyFactory();
  536. $master = $hdFactory->fromEntropy($seed);
  537. $util = new Util();
  538. // 设置路径account
  539. $hardened = $master->derivePath("44'/60'/0'/0/0");
  540. echo " - m/44'/60'/0'/0/0 " . PHP_EOL;
  541. echo " public key: " . $hardened->getPublicKey()->getHex() . PHP_EOL;
  542. echo " private key: " . $hardened->getPrivateKey()->getHex() . PHP_EOL;// 可以导入到imtoken使用的私钥
  543. echo " address: " . $util->publicKeyToAddress($util->privateKeyToPublicKey($hardened->getPrivateKey()->getHex())) . PHP_EOL;// 私钥导入imtoken后一样的地址
  544. }
  545. public function getWebAddress($label = '1')
  546. {
  547. $personal = new Personal("https://cloudflare-eth.com");
  548. $personal->batch(true);
  549. $personal->listAccounts();
  550. $personal->newAccount('123456');
  551. $personal->provider->execute(function ($err, $data) {
  552. if ($err !== null) {
  553. // do something
  554. return;
  555. }
  556. // do something
  557. });
  558. }
  559. /**
  560. * 获取HASH钱包地址
  561. * @param $address 钱包地址
  562. * @return \BitWasp\Buffertools\BufferInterface
  563. * @throws \BitWasp\Bitcoin\Exceptions\UnrecognizedAddressException
  564. */
  565. public function getHash16Address($address)
  566. {
  567. $data = WitnessProgram::v0((new AddressCreator())->fromString($address)->getHash());
  568. $buffer = $data->getProgram()->getHex();
  569. return $buffer ? '0x' . $buffer : '';
  570. }
  571. /**
  572. * 获取HASH钱包地址
  573. * @param $address 钱包地址
  574. * @return \BitWasp\Buffertools\BufferInterface
  575. * @throws \BitWasp\Bitcoin\Exceptions\UnrecognizedAddressException
  576. */
  577. public function getHexAddress($address)
  578. {
  579. $data = WitnessProgram::v0((new AddressCreator())->fromString($address)->getHash());
  580. $buffer = $data->getProgram()->getHex();
  581. return $buffer ? '0x' . $buffer : '';
  582. }
  583. /**
  584. * 创建交易参数
  585. * @param $payWif
  586. * @param $address
  587. * @param $amount
  588. * @param string $coin
  589. * @throws \BitWasp\Bitcoin\Exceptions\Base58ChecksumFailure
  590. * @throws \BitWasp\Bitcoin\Exceptions\InvalidPrivateKey
  591. * @throws \BitWasp\Bitcoin\Exceptions\UnrecognizedAddressException
  592. * @throws \BitWasp\Bitcoin\Exceptions\WitnessScriptException
  593. * api: https://services.tokenview.com/vipapi/onchainwallet/{币种简称小写}?apikey={apikey}
  594. */
  595. public function createTrade($payAddress, $address, $amount, $coin = 'etc')
  596. {
  597. $data = [
  598. 'owner_address' => $payAddress,
  599. 'to_address' => $address,
  600. 'amount' => $amount,
  601. 'method' => 'createtransaction',
  602. 'visible' => false,
  603. ];
  604. $this->apiUrl = $this->apiUrl . "/onchainwallet/{$coin}?apikey=" . $this->config['usdt_apikey'];
  605. var_dump($data);
  606. var_dump($this->apiUrl);
  607. $result = curl_api($this->apiUrl, $data, ["Content-Type: application/json"]);
  608. var_dump($result);
  609. }
  610. }