UsdtWalletService.php 25 KB

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