MonitorWalletBlockV2.php 31 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519
  1. <?php
  2. namespace App\Task;
  3. use App\Model\Monitor\MonitorWallet;
  4. use App\Library\Log;
  5. use App\Service\Bus\TronServices;
  6. class MonitorWalletBlockV2
  7. {
  8. public function execute()
  9. {
  10. try {
  11. $data = MonitorWallet::from('monitor_wallet as a')
  12. ->Join('telegram_bot as b','a.bot_rid','b.rid')
  13. ->where('a.status',0)
  14. ->whereNotNull('a.monitor_wallet')
  15. ->where('a.chain_type','trc')
  16. ->select('a.monitor_wallet','a.tg_notice_obj','b.bot_token','a.comments','a.monitor_usdt_transaction','a.monitor_trx_transaction','a.monitor_approve_transaction','a.monitor_multi_transaction','a.monitor_pledge_transaction')
  17. ->get()
  18. ->toArray();
  19. if(!empty($data)){
  20. $api_key = config('apikey.gridapikey');
  21. $apikeyrand = $api_key[array_rand($api_key)];
  22. //波场接口API
  23. $TronApiConfig = [
  24. 'url' => 'https://api.trongrid.io',
  25. 'api_key' => $apikeyrand,
  26. ];
  27. $tron = new TronServices($TronApiConfig,'1111111','222222');
  28. $tronres = $tron->getBlock(null);
  29. if(!empty($tronres['transactions'])){
  30. $currentblock = $tronres['block_header']['raw_data']['number'];
  31. $blocktimestamp = $tronres['block_header']['raw_data']['timestamp'];
  32. #该区块和redis比对,如果漏了则记录漏的区块号单独查,并更新redis最新区块号
  33. $redisblock = json_decode(getRedis('newestblock'),true) ?? [];
  34. #区块已查过,则不继续查了
  35. if (in_array($currentblock, $redisblock)) {
  36. return '';
  37. }
  38. if(empty($redisblock)){
  39. $minblock = 0;
  40. $maxblock = $currentblock;
  41. }else{
  42. $minblock = min($currentblock,max($redisblock));
  43. $maxblock = max($currentblock,max($redisblock));
  44. }
  45. //更新已查询的block,只保留最新10个block
  46. if(count($redisblock) > 10){
  47. array_shift($redisblock);
  48. }
  49. $redisblock[] = $currentblock;
  50. $redisblock = array_unique($redisblock);
  51. setRedis('newestblock',json_encode($redisblock));
  52. if(count($redisblock) > 0 && $minblock + 1 <> $maxblock && $minblock != $maxblock){
  53. $lostblock = json_decode(getRedis('lostblock'),true);
  54. $add = 0;
  55. #把不连续的block插入到redis
  56. for ($i = $minblock + 1; $i < $maxblock; $i++) {
  57. $lostblock[] = $i;
  58. //最多只插入20个漏的块
  59. $add++;
  60. if($add >= 20){
  61. break;
  62. }
  63. }
  64. if(!empty($lostblock)){
  65. $lostblock = array_unique($lostblock);
  66. }
  67. //删除已查找过的block
  68. foreach ($lostblock as $key => $value) {
  69. if (in_array($value, $redisblock)) {
  70. unset($lostblock[$key]);
  71. }
  72. }
  73. //只保留漏查20个block
  74. if(count($lostblock) > 20){
  75. array_shift($lostblock);
  76. }
  77. setRedis('lostblock',json_encode($lostblock));
  78. }
  79. //区块的交易详细
  80. foreach ($tronres['transactions'] as $x => $y) {
  81. //如果是合约事件
  82. if($y['raw_data']['contract'][0]['type'] == 'TriggerSmartContract'){
  83. $dataaa = $y['raw_data']['contract'][0]['parameter']['value']['data'];
  84. $contract_address = $y['raw_data']['contract'][0]['parameter']['value']['contract_address']; //USDT:41a614f803b6fd780986a42c78ec9c7f77e6ded13c
  85. //取合约的transfer方法
  86. if(in_array(mb_substr($dataaa,0,8),['d73dd623','a9059cbb','095ea7b3']) && $contract_address == '41a614f803b6fd780986a42c78ec9c7f77e6ded13c'){
  87. $toaddress = $tron->addressFromHex('41' . mb_substr($dataaa,32,40));
  88. $fromaddress = $tron->addressFromHex($y['raw_data']['contract'][0]['parameter']['value']['owner_address']);
  89. $amount = $tron->dataAmountFormat(mb_substr($dataaa,72,64));
  90. //转入地址是否在监控列表
  91. $isto = array_search($toaddress,array_column($data,'monitor_wallet'));
  92. $isfrom = array_search($fromaddress,array_column($data,'monitor_wallet'));
  93. //如果是转入
  94. if(($isto !== false && $amount > 0 && mb_substr($dataaa,0,8) == 'a9059cbb') || ($isto !== false && mb_substr($dataaa,0,8) != 'a9059cbb')){
  95. $contractret = $y['ret'][0]['contractRet'];
  96. $found_obj = $data[$isto];
  97. $type = mb_substr($dataaa,0,8) == 'a9059cbb' ?'1':($amount == 0 ?'11':'12');
  98. //判断功能开关
  99. if(($type == 1 && mb_substr($found_obj['monitor_usdt_transaction'],0,1) == 'Y' && $amount >= 0.01) || ($type == 11 && mb_substr($found_obj['monitor_approve_transaction'],1,1) == 'Y') || ($type == 12 && mb_substr($found_obj['monitor_approve_transaction'],0,1) == 'Y')){
  100. $this->sendTgMessage($contractret,$toaddress,$type,$fromaddress,$toaddress,'TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t',$amount,$currentblock,$blocktimestamp,$y['txID'],$found_obj['tg_notice_obj'],$found_obj['bot_token'],$found_obj['comments']);
  101. }
  102. }
  103. //如果是转出
  104. if(($isfrom !== false && $amount > 0 && mb_substr($dataaa,0,8) == 'a9059cbb') || ($isfrom !== false && mb_substr($dataaa,0,8) != 'a9059cbb')){
  105. $contractret = $y['ret'][0]['contractRet'];
  106. $found_obj = $data[$isfrom];
  107. $type = mb_substr($dataaa,0,8) == 'a9059cbb' ?'2':($amount == 0 ?'21':'22');
  108. //判断功能开关
  109. if(($type == 2 && mb_substr($found_obj['monitor_usdt_transaction'],1,1) == 'Y' && $amount >= 0.01) || ($type == 21 && mb_substr($found_obj['monitor_approve_transaction'],1,1) == 'Y') || ($type == 22 && mb_substr($found_obj['monitor_approve_transaction'],0,1) == 'Y')){
  110. $this->sendTgMessage($contractret,$fromaddress,$type,$fromaddress,$toaddress,'TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t',$amount,$currentblock,$blocktimestamp,$y['txID'],$found_obj['tg_notice_obj'],$found_obj['bot_token'],$found_obj['comments']);
  111. }
  112. }
  113. //取合约的transferFrom方法
  114. }elseif(mb_substr($dataaa,0,8) == '23b872dd' && $contract_address == '41a614f803b6fd780986a42c78ec9c7f77e6ded13c'){
  115. $toaddress = $tron->addressFromHex('41' . mb_substr($dataaa,96,40));
  116. $fromaddress = $tron->addressFromHex('41' . mb_substr($dataaa,32,40));
  117. $amount = $tron->dataAmountFormat(mb_substr($dataaa,136,64));
  118. //转入地址是否在监控列表
  119. $isto = array_search($toaddress,array_column($data,'monitor_wallet'));
  120. $isfrom = array_search($fromaddress,array_column($data,'monitor_wallet'));
  121. //如果是转入
  122. if($isto !== false && $amount >= 0.01){
  123. $contractret = $y['ret'][0]['contractRet'];
  124. $found_obj = $data[$isto];
  125. //判断功能开关
  126. if(mb_substr($found_obj['monitor_usdt_transaction'],0,1) == 'Y' && $amount >= 0.01){
  127. $this->sendTgMessage($contractret,$toaddress,3,$fromaddress,$toaddress,'TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t',$amount,$currentblock,$blocktimestamp,$y['txID'],$found_obj['tg_notice_obj'],$found_obj['bot_token'],$found_obj['comments']);
  128. }
  129. }
  130. //如果是转出
  131. if($isfrom !== false && $amount >= 0.01){
  132. $contractret = $y['ret'][0]['contractRet'];
  133. $found_obj = $data[$isfrom];
  134. //判断功能开关
  135. if(mb_substr($found_obj['monitor_usdt_transaction'],1,1) == 'Y' && $amount >= 0.01){
  136. $this->sendTgMessage($contractret,$fromaddress,4,$fromaddress,$toaddress,'TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t',$amount,$currentblock,$blocktimestamp,$y['txID'],$found_obj['tg_notice_obj'],$found_obj['bot_token'],$found_obj['comments']);
  137. }
  138. }
  139. }
  140. // trx交易
  141. }elseif($y['raw_data']['contract'][0]['type'] == 'TransferContract'){
  142. $toaddress = $tron->addressFromHex($y['raw_data']['contract'][0]['parameter']['value']['to_address']);
  143. $fromaddress = $tron->addressFromHex($y['raw_data']['contract'][0]['parameter']['value']['owner_address']);
  144. $amount = calculationExcept($y['raw_data']['contract'][0]['parameter']['value']['amount'],6);
  145. //转入地址是否在监控列表
  146. $isto = array_search($toaddress,array_column($data,'monitor_wallet'));
  147. $isfrom = array_search($fromaddress,array_column($data,'monitor_wallet'));
  148. //如果是转入
  149. if($isto !== false && $amount >= 0.01){
  150. $contractret = $y['ret'][0]['contractRet'];
  151. $found_obj = $data[$isto];
  152. //判断功能开关
  153. if(mb_substr($found_obj['monitor_trx_transaction'],0,1) == 'Y'){
  154. $this->sendTgMessage($contractret,$toaddress,1,$fromaddress,$toaddress,'TRX',$amount,$currentblock,$blocktimestamp,$y['txID'],$found_obj['tg_notice_obj'],$found_obj['bot_token'],$found_obj['comments']);
  155. }
  156. }
  157. //如果是转出
  158. if($isfrom !== false && $amount >= 0.01){
  159. $contractret = $y['ret'][0]['contractRet'];
  160. $found_obj = $data[$isfrom];
  161. //判断功能开关
  162. if(mb_substr($found_obj['monitor_trx_transaction'],1,1) == 'Y'){
  163. $this->sendTgMessage($contractret,$fromaddress,2,$fromaddress,$toaddress,'TRX',$amount,$currentblock,$blocktimestamp,$y['txID'],$found_obj['tg_notice_obj'],$found_obj['bot_token'],$found_obj['comments']);
  164. }
  165. }
  166. // 代理资源或者回收资源
  167. }elseif(in_array($y['raw_data']['contract'][0]['type'],['UnDelegateResourceContract','DelegateResourceContract'])){
  168. $toaddress = $tron->addressFromHex($y['raw_data']['contract'][0]['parameter']['value']['receiver_address']);
  169. $fromaddress = $tron->addressFromHex($y['raw_data']['contract'][0]['parameter']['value']['owner_address']);
  170. $amount = calculationExcept($y['raw_data']['contract'][0]['parameter']['value']['balance'],6);
  171. $resource = $y['raw_data']['contract'][0]['parameter']['value']['resource'] ?? ' ';
  172. //转入地址是否在监控列表
  173. $isto = array_search($toaddress,array_column($data,'monitor_wallet'));
  174. $isfrom = array_search($fromaddress,array_column($data,'monitor_wallet'));
  175. //如果是转入
  176. if($isto !== false && $amount > 0){
  177. $contractret = $y['ret'][0]['contractRet'];
  178. $found_obj = $data[$isto];
  179. $type = $y['raw_data']['contract'][0]['type'] == 'DelegateResourceContract' ?6:61;
  180. //判断功能开关
  181. if(($type == 6 && mb_substr($found_obj['monitor_pledge_transaction'],0,1) == 'Y') || ($type == 61 && mb_substr($found_obj['monitor_pledge_transaction'],1,1) == 'Y')){
  182. $this->sendTgMessage($contractret,$toaddress,$type,$fromaddress,$toaddress,$resource,$amount,$currentblock,$blocktimestamp,$y['txID'],$found_obj['tg_notice_obj'],$found_obj['bot_token'],$found_obj['comments']);
  183. }
  184. }
  185. //如果是转出
  186. if($isfrom !== false && $amount > 0){
  187. $contractret = $y['ret'][0]['contractRet'];
  188. $found_obj = $data[$isfrom];
  189. $type = $y['raw_data']['contract'][0]['type'] == 'DelegateResourceContract' ?7:71;
  190. //判断功能开关
  191. if(($type == 7 && mb_substr($found_obj['monitor_pledge_transaction'],0,1) == 'Y') || ($type == 71 && mb_substr($found_obj['monitor_pledge_transaction'],1,1) == 'Y')){
  192. $this->sendTgMessage($contractret,$fromaddress,$type,$fromaddress,$toaddress,$resource,$amount,$currentblock,$blocktimestamp,$y['txID'],$found_obj['tg_notice_obj'],$found_obj['bot_token'],$found_obj['comments']);
  193. }
  194. }
  195. // 账号更新权限
  196. }elseif($y['raw_data']['contract'][0]['type'] == 'AccountPermissionUpdateContract'){
  197. $fromaddress = $tron->addressFromHex($y['raw_data']['contract'][0]['parameter']['value']['owner_address']);
  198. $returnlist = '';
  199. $isOwn_set = 'N'; //监控地址是否有在所有权限中
  200. $isActive_set = 'N'; //监控地址是否有在活跃权限中
  201. $isJiankong = 'N'; //是否监控地址变更权限
  202. $isFound = 'N'; //是否找到监控钱包
  203. //监控地址变更权限
  204. $isfrom = array_search($fromaddress,array_column($data,'monitor_wallet'));
  205. if($isfrom !== false){
  206. $found_obj = $data[$isfrom];
  207. $isJiankong = 'Y';
  208. $isFound = 'Y';
  209. }
  210. //查询所有者权限
  211. if(isset($y['raw_data']['contract'][0]['parameter']['value']['owner'])){
  212. $ownerPermission = $y['raw_data']['contract'][0]['parameter']['value']['owner'];
  213. $returnlist = $returnlist . "\n🟠🟠所有权限-阈值:".$ownerPermission['threshold']."🟠🟠\n";
  214. $ownerPermissionList = '';
  215. for($i=0;$i<count($ownerPermission['keys']);$i++){
  216. $ownerAddress = $tron->addressFromHex($ownerPermission['keys'][$i]['address']);
  217. //检测是否存在所有者地址权限
  218. $isOwn = array_search($ownerAddress,array_column($data,'monitor_wallet'));
  219. if($isOwn !== false){
  220. $isOwn_set = 'Y';
  221. if($isFound == 'N'){
  222. $found_obj = $data[$isOwn];
  223. $isFound == 'Y';
  224. }
  225. }
  226. $ownerPermissionList = $ownerPermissionList."地址:<code>".$ownerAddress."</code> (权重:".$ownerPermission['keys'][$i]['weight'].")\n";
  227. }
  228. $returnlist = $returnlist.$ownerPermissionList;
  229. }
  230. //查询活跃权限
  231. if(isset($y['raw_data']['contract'][0]['parameter']['value']['actives'])){
  232. $activePermissions = $y['raw_data']['contract'][0]['parameter']['value']['actives'];
  233. if(count($activePermissions) > 0){
  234. $returnlist = $returnlist . "\n🔴🔴活跃权限-共:".count($activePermissions)."个🔴🔴\n";
  235. for($i=0;$i<count($activePermissions);$i++){
  236. $activepermissionname = isset($activePermissions[$i]['permission_name']) ?$activePermissions[$i]['permission_name']:$activePermissions[$i]['type'];
  237. $returnlist = $returnlist . "第". ($i+1) ."个-权限名称:".$activepermissionname." 权限阈值:".$activePermissions[$i]['threshold']."\n";
  238. $activePermissionList = '';
  239. for($j=0;$j<count($activePermissions[$i]['keys']);$j++){
  240. $activeAddress = $tron->addressFromHex($activePermissions[$i]['keys'][$j]['address']);
  241. //检测是否存在活跃地址权限
  242. $isActive = array_search($activeAddress,array_column($data,'monitor_wallet'));
  243. if($isActive !== false){
  244. $isActive_set = 'Y';
  245. if($isFound == 'N'){
  246. $found_obj = $data[$isActive];
  247. $isFound == 'Y';
  248. }
  249. }
  250. $activePermissionList = $activePermissionList."地址:<code>".$activeAddress."</code> (权重:".$activePermissions[$i]['keys'][$j]['weight'].")\n";
  251. }
  252. $returnlist = $returnlist.$activePermissionList;
  253. }
  254. }
  255. }
  256. //判断发送消息
  257. if($isfrom !== false || $isActive_set == 'Y' || $isOwn_set == 'Y'){
  258. $contractret = $y['ret'][0]['contractRet'];
  259. $type = $isJiankong == 'Y' ?5:51;
  260. //判断功能开关
  261. if(($type == 5 && mb_substr($found_obj['monitor_multi_transaction'],0,1) == 'Y') || ($type == 51 && mb_substr($found_obj['monitor_multi_transaction'],1,1) == 'Y')){
  262. $this->sendTgMessage($contractret,$found_obj['monitor_wallet'],$type,$fromaddress,'',$returnlist,0,$currentblock,$blocktimestamp,$y['txID'],$found_obj['tg_notice_obj'],$found_obj['bot_token'],$found_obj['comments']);
  263. }
  264. }
  265. }
  266. }
  267. }
  268. }
  269. }catch (\Exception $e){
  270. $this->log('monitorwallet','----------任务执行报错,请联系管理员。报错原因:----------'.$e->getMessage());
  271. }
  272. }
  273. /**
  274. * 发送tg消息
  275. */
  276. protected function sendTgMessage($contractret,$monitoraddress,$type,$fromaddress,$toaddress,$contract_address,$value,$currentblock,$blocktimestamp,$txid,$tg_notice_obj,$bot_token,$comments){
  277. if($type == 1){
  278. $transtype = '正常转账 ↓';
  279. }elseif($type == 2){
  280. $transtype = '正常转账 ↑';
  281. }elseif($type == 3){
  282. $transtype = '授权转账 ↓';
  283. }elseif($type == 4){
  284. $transtype = '授权转账 ↑';
  285. }elseif($type == 11){
  286. $transtype = '给监控地址取消授权';
  287. }elseif($type == 21){
  288. $transtype = '监控地址给其他地址取消授权';
  289. }elseif($type == 12){
  290. $transtype = '给监控地址授权 ↓';
  291. }elseif($type == 22){
  292. $transtype = '监控地址给其他地址授权 ↑';
  293. }elseif($type == 5){
  294. $transtype = '监控地址变更多签账户';
  295. }elseif($type == 51){
  296. $transtype = '其他地址变更监控地址为多签';
  297. }elseif($type == 6){
  298. $transtype = '给监控地址代理质押 ↓';
  299. }elseif($type == 61){
  300. $transtype = '给监控地址回收质押 ↑';
  301. }elseif($type == 7){
  302. $transtype = '监控地址给其他地址代理质押 ↑';
  303. }elseif($type == 71){
  304. $transtype = '监控地址给其他地址回收质押 ↓';
  305. }else{
  306. $transtype = '其他';
  307. }
  308. if(empty($comments) || $comments == ''){
  309. $comments = '无';
  310. }
  311. if($type == 5 || $type == 51){
  312. $replytext = "监控钱包:<code>".$monitoraddress."</code>\n"
  313. ."监控钱包备注:".$comments."\n"
  314. ."变更钱包:<code>".$fromaddress."</code>\n"
  315. ."---------------------------------------\n"
  316. ."交易类型:<b>".$transtype."</b>\n"
  317. ."交易结果:".$contractret."\n"
  318. .$contract_address."\n"
  319. ."---------------------------------------\n"
  320. ."交易时间:<code>".date('Y-m-d H:i:s', $blocktimestamp/1000)."</code>\n"
  321. ."当前区块号:<code>".$currentblock."</code>\n"
  322. ."当前交易哈希:<code>".$txid."</code>\n";
  323. }elseif(in_array($type,[6,61,7,71])){
  324. $replytext = "监控钱包:<code>".$monitoraddress."</code>\n"
  325. ."监控钱包备注:".$comments."\n"
  326. ."---------------------------------------\n"
  327. ."交易类型:<b>".$transtype."</b>\n"
  328. ."交易结果:".$contractret."\n"
  329. ."代理资源:".$contract_address."\n"
  330. ."代理数量:".$value."\n"
  331. ."---------------------------------------\n"
  332. ."交易时间:<code>".date('Y-m-d H:i:s', $blocktimestamp/1000)."</code>\n"
  333. ."当前区块号:<code>".$currentblock."</code>\n"
  334. ."当前交易哈希:<code>".$txid."</code>\n";
  335. //转账
  336. }elseif(in_array($type,[1,2,3,4])){
  337. $url = 'https://apilist.tronscanapi.com/api/accountv2?address='.$monitoraddress;
  338. $api_key = config('apikey.tronapikey');
  339. $apikeyrand = $api_key[array_rand($api_key)];
  340. $heders = [
  341. "TRON-PRO-API-KEY:".$apikeyrand
  342. ];
  343. $res = Get_Pay($url,null,$heders);
  344. $accountBalance = "未知";
  345. if(empty($res)){
  346. //为空则查询一次grid api
  347. $url = 'https://api.trongrid.io/v1/accounts/'.$monitoraddress;
  348. $api_key = config('apikey.gridapikey');
  349. $apikeyrand = $api_key[array_rand($api_key)];
  350. $heders = [
  351. 'TRON-PRO-API-KEY:'.$apikeyrand
  352. ];
  353. $res = Get_Pay($url,null,$heders);
  354. if(empty($res)){
  355. //为空则不处理
  356. }else{
  357. $res = json_decode($res,true);
  358. if(isset($res['success'])){
  359. if(empty($res['data'])){
  360. $accountBalance = '地址还未激活!';
  361. }else{
  362. $accountBalance = "";
  363. $accountBalance = $accountBalance.(empty($res['data'][0]['balance']) ? 0 : bcdiv($res['data'][0]['balance'],1000000,6) + 0)." TRX";
  364. $usdt = 0;
  365. if(!empty($res['data'][0]['trc20'])){
  366. for($i=1; $i<=count($res['data'][0]['trc20']); $i++){
  367. if(!empty($res['data'][0]['trc20'][$i-1]['TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t'])){
  368. $usdt = bcdiv($res['data'][0]['trc20'][$i-1]['TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t'],1000000,6) + 0;
  369. break;
  370. }
  371. }
  372. }
  373. $accountBalance = $accountBalance.",".$usdt." USDT";
  374. }
  375. }
  376. }
  377. }else{
  378. $res = json_decode($res,true);
  379. //查询余额
  380. if(isset($res['withPriceTokens'])){
  381. $accountBalance = "";
  382. $withPriceTokens = $res['withPriceTokens'];
  383. $trxkey = array_search('_', array_column($withPriceTokens, 'tokenId'));
  384. $usdtkey = array_search('TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t', array_column($withPriceTokens, 'tokenId'));
  385. if($trxkey >= 0){
  386. $accountBalance = $accountBalance.($withPriceTokens[$trxkey]['amount'] + 0) ." TRX";
  387. }else{
  388. $accountBalance = $accountBalance."0 TRX";
  389. }
  390. if(is_bool($usdtkey)){
  391. $accountBalance = $accountBalance.",0 USDT";
  392. }else{
  393. $usdtamount = calculationExcept($withPriceTokens[$usdtkey]['balance'] ,$withPriceTokens[$usdtkey]['tokenDecimal']);
  394. $accountBalance = $accountBalance.",".$usdtamount." USDT";
  395. }
  396. }
  397. }
  398. $replytext = "监控钱包:<code>".$monitoraddress."</code>\n"
  399. ."监控钱包备注:".$comments."\n"
  400. ."---------------------------------------\n"
  401. ."<b>".(in_array($type,[1,3]) ?'🟢收入':'🔴支出').($contract_address == 'TRX' ?'TRX':'USDT')."提醒 ".(in_array($type,[1,3]) ?'+':'-').$value." ".($contract_address == 'TRX' ?'TRX':'USDT')."</b>\n\n"
  402. ."付款地址:<code>".$fromaddress."</code>\n"
  403. ."收款地址:<code>".$toaddress."</code>\n"
  404. ."交易时间:<code>".date('Y-m-d H:i:s', $blocktimestamp/1000)."</code>\n"
  405. ."交易金额:<b>".(in_array($type,[1,3]) ?'+':'-').$value." ".($contract_address == 'TRX' ?'TRX':'USDT')."</b>\n"
  406. ."---------------------------------------\n"
  407. ."账户余额:".$accountBalance."\n"
  408. ."交易结果:".($contractret == 'SUCCESS' ?'成功':'失败'.$contractret)." 类型:".$transtype;
  409. }else{
  410. $replytext = "监控钱包:<code>".$monitoraddress."</code>\n"
  411. ."监控钱包备注:".$comments."\n"
  412. ."---------------------------------------\n"
  413. ."转出地址:<code>".$fromaddress."</code>\n"
  414. ."接收地址:<code>".$toaddress."</code>\n"
  415. ."交易类型:<b>".$transtype."</b>\n"
  416. ."交易金额:<b>".$value."</b>\n"
  417. ."交易结果:".$contractret."\n"
  418. ."---------------------------------------\n"
  419. ."交易时间:<code>".date('Y-m-d H:i:s', $blocktimestamp/1000)."</code>\n"
  420. ."合约地址:<code>".$contract_address."</code>\n"
  421. ."当前区块号:<code>".$currentblock."</code>\n"
  422. ."当前交易哈希:<code>".$txid."</code>\n";
  423. }
  424. $url = 'https://tronscan.io/#/transaction/'.$txid;
  425. //内联按钮
  426. $keyboard = [
  427. 'inline_keyboard' => [
  428. [
  429. ['text' => '查看交易', 'url' => $url]
  430. ]
  431. ]
  432. ];
  433. $encodedKeyboard = json_encode($keyboard);
  434. $sendlist = explode(',',$tg_notice_obj);
  435. foreach ($sendlist as $x => $y) {
  436. $sendmessageurl = 'https://api.telegram.org/bot'.$bot_token.'/sendMessage?chat_id='.$y.'&text='.urlencode($replytext).'&parse_mode=HTML&reply_markup='.urlencode($encodedKeyboard);
  437. Get_Pay($sendmessageurl);
  438. }
  439. }
  440. /**
  441. * 记入日志
  442. * @param $log_title [日志路径]
  443. * @param $message [内容,不支持数组]
  444. * @param $remarks [备注]
  445. */
  446. protected function log($log_title,$message,$remarks='info'){
  447. Log::get($remarks,$log_title)->info($message);
  448. }
  449. }