ApiJsonController.php 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486
  1. <?php
  2. namespace App\Http\Controllers;
  3. use App\Models\MemberClans;
  4. use App\Servers\Eth\Address;
  5. use App\Servers\Eth\EthereumRPC;
  6. use App\Servers\Eth\Utils;
  7. use App\Servers\MemberServer;
  8. use Illuminate\Support\Facades\DB;
  9. use Illuminate\Support\Facades\Log;
  10. class ApiJsonController extends Controller
  11. {
  12. /**
  13. * 合约地址
  14. * @var string
  15. */
  16. private $token_address = '0x6718DC858bC2EA664e6a8752E1320F1de6e0Dc52';
  17. /**
  18. * 系统钱包地址
  19. * @var string
  20. */
  21. private $sys_address='0x9202c91a5181dbfa44f5bd219c1065016c1d23ad';
  22. /**
  23. * 系统秘钥
  24. * @var string
  25. */
  26. private $sys_key='4b649bc90ece239238a3c513fb4b9d445d681c52086b91bb250280b5054639c2';
  27. protected $sing_key = "lu0ziiun8znpxtv8o9sdfhggfhfgsw9p6eooxw2efk";
  28. protected function getNonce($address)
  29. {
  30. /** @var static $tx */
  31. $nonce='0x51';
  32. if (!empty($nonce)) {
  33. return Utils::dec2hex(Utils::hex2dec($nonce) + 1);
  34. }
  35. // return self::rpc()->getTransactionCount($address);
  36. }
  37. public function index()
  38. {
  39. // exit;
  40. //测试币名称:nntt
  41. // 合约地址:0x6718DC858bC2EA664e6a8752E1320F1de6e0Dc52
  42. //0x378fb524c5dfcc2a42fbea91b9652c6457042c19
  43. //75c50cb3f53e579e0ac3a12897a37ce23f31ae19dcc4ef08054761b90b833465
  44. //测试地址主账户
  45. //0x9202c91a5181dbfa44f5bd219c1065016c1d23ad
  46. //4b649bc90ece239238a3c513fb4b9d445d681c52086b91bb250280b5054639c2
  47. //收款账户
  48. //0x51eba8cdd9d14193cb4321a63395eef616f395c3
  49. //925baa5153e40866a474bd1311baf058c9f3466260b2fc7e1cf1ace8065e9658
  50. //生成钱包地址 返回数组
  51. //-------------------------------生成钱包地址
  52. // $address = Address::generate();
  53. // var_dump($address);exit;
  54. //交易测试
  55. // $eth = new EthereumRPC();
  56. // $serviceFee = Utils::dec2hex('1500000000000000'); // 手续费
  57. // var_dump($serviceFee);exit;
  58. // $eth_num = $eth->getBalance('0x51eba8cdd9d14193cb4321a63395eef616f395c3');
  59. // $eth_num = '0x5d21dba00';
  60. // $eth_num = Utils::hex2dec($eth_num);
  61. // var_dump($eth_num);
  62. // $eth_num = Utils::int2fund($eth_num, 18);
  63. // var_dump($eth_num);exit;
  64. // $eth_num = $eth->getBalance('0x51eba8cdd9d14193cb4321a63395eef616f395c3');
  65. // $eth_num = Utils::hex2dec($eth_num);
  66. // $eth_num = Utils::int2fund($eth_num, 18);
  67. // var_dump($eth_num);exit;
  68. // var_dump($this->getTransactionReceipt('0xadc978f46ba41dc1b56bb37b37bd90b9ba63f9809678e16751693d9e130f0429'));exit;
  69. $from='0x02b9132724a056b43944426bbebebf07a064e972';
  70. $to='0xc3d7901a8eebbcd8b0873e9aa7e20440b3014761';
  71. // $from='0x39e505a18e29d5cb9e746b86f31771385e3b3b7b';
  72. // $to='0x51eba8cdd9d14193cb4321a63395eef616f395c3';
  73. $money=1000;
  74. $tx = $this->build($from, '0x2d874077a83618aab75624cc1a4974510a0eb1ae', '0x0', Utils::decodeSolMethod('transfer(address,uint256)', [$to, Utils::fund2int($money, 18)]));
  75. // var_dump($tx);exit;
  76. // $tx = $this->build($from,$to, '0x0', Utils::decodeSolMethod('transfer(address,uint256)', [$to, Utils::fund2int($money, 18)]));
  77. // $service_info=$this->nytrWithholdServiceCharge($tx);
  78. // var_dump($service_info);exit;
  79. $ret=$this->ntrTransferAccounts($tx,'527a4fd9bdb84d02ffb8046cb5704642969c95ca67cfa5535511fd38c358c2a1');
  80. var_dump($ret);exit;
  81. // if($from!=$this->sys_address){
  82. // $service_info=$this->nytrWithholdServiceCharge($tx);
  83. // if(!empty($service_info['data']['hash']))return ['code'=>'0','msg'=>'手续费代扣失败'];
  84. // //手续费哈希值
  85. // //0xf553bff171816ff5704aad45661f828d6b0b15e7fd84cfaaf545a71269a906eb
  86. // var_dump($service_info);exit;
  87. // }else{
  88. //
  89. // }
  90. //
  91. //----------------------------------------查询用户余额--------------
  92. // $receipt = $eth->getTransactionReceipt('0x70c6b91bb92841bcb459e91ab8255fd8352370a545a7291ae1b8d19c97d371fa');//交易查询
  93. // $tx = [];
  94. // $tx['from'] = '0x9202c91a5181dbfa44f5bd219c1065016c1d23ad';//用户地址
  95. // $tx['to'] = $this->token_address;//系统钱包地址
  96. // $tx['data'] = Utils::decodeSolMethod('balanceOf(address)', ['0x9202c91a5181dbfa44f5bd219c1065016c1d23ad']);
  97. // $balance = $eth->call($tx);
  98. // $balance = Utils::hex2dec($balance);
  99. // $balance = Utils::int2fund($balance); // 18位小数
  100. // $balance = Utils::fund2int($balance, 2);
  101. // var_dump('-------------------nntt余额');
  102. // return Utils::int2fund($balance, 2);
  103. //--------------获取eth的余额
  104. // var_dump('-------------------ETH余额');
  105. //-----------------代币NYTR转账测试
  106. // $gasPrice = $eth->getGasPrice(); // 手续费
  107. // var_dump($gasPrice);
  108. // var_dump('-------------------交易手续费');
  109. // $money = 100;
  110. // token 交易
  111. // $tx = $this->build('0x51eba8cdd9d14193cb4321a63395eef616f395c3', '0x6718DC858bC2EA664e6a8752E1320F1de6e0Dc52', '0x0', Utils::decodeSolMethod('transfer(address,uint256)', ['0x9202c91a5181dbfa44f5bd219c1065016c1d23ad', Utils::fund2int($money, 18)]));
  112. // $tx = [];
  113. // $tx['from'] = '0x9202c91a5181dbfa44f5bd219c1065016c1d23ad';
  114. // $tx['to'] = '0x6718DC858bC2EA664e6a8752E1320F1de6e0Dc52';
  115. // $tx['value'] = Utils::dec2hex(Utils::fund2int($money));
  116. // $tx['data'] = Utils::fixHex(bin2hex('transfer'));
  117. // if ($tx['from'] != $this->token_address) {
  118. // $gasLimit = $eth->estimateGas($tx);
  119. // 手续费交易
  120. // $serviceFee = Utils::dec2hex(bcmul(Utils::hex2dec($gasPrice), Utils::hex2dec($gasLimit))); // 手续费
  121. // $serviceTx = $this->build($this->token_address, $tx['from'], $serviceFee, Utils::fixHex(bin2hex('service charge')));
  122. // 广播手续费
  123. // $depend = EthTransaction::push($serviceTx, $this->masterKey, null);
  124. // if (!$depend) {
  125. // return false;
  126. // }
  127. // }
  128. $transaction = [
  129. 'depend' => 0,
  130. 'from' => '0x9202c91a5181dbfa44f5bd219c1065016c1d23ad',
  131. 'to' => '0x6718DC858bC2EA664e6a8752E1320F1de6e0Dc52',
  132. 'nonce' => '',
  133. 'value' => !empty($tx['value']) ? $tx['value'] : '0x0',
  134. 'data' => !empty($tx['data']) ? $tx['data'] : Utils::fixHex(bin2hex('NYT')),
  135. 'chain_id' => $eth->chainId,
  136. 'gas_price' => '',
  137. 'gas_limit' => '',
  138. 'sign' => '',
  139. 'hash' => '',
  140. ];
  141. $nonce = $eth->getTransactionCount($transaction['from']);
  142. $transaction['nonce'] = $nonce;//交易顺序十六进制。由eth_getTransactionCount获取
  143. $gas_price = $eth->getGasPrice();
  144. $transaction['gas_price'] = $gas_price;//燃料十六进制。由eth_estimateGas获取
  145. $gas_limit = $this->getGasLimit($transaction);
  146. $transaction['gas_limit'] = $gas_limit;
  147. $sign = $this->sign($transaction, '4b649bc90ece239238a3c513fb4b9d445d681c52086b91bb250280b5054639c2');//交易签名
  148. $hash = $eth->sendRawTransaction($sign, $error);//广播交易
  149. $receipt = $eth->getTransactionReceipt($hash);//交易查询
  150. if (!$hash) {
  151. var_dump('---------------');
  152. var_dump($error);
  153. var_dump('---------------');
  154. }
  155. var_dump($receipt);
  156. var_dump($hash);
  157. var_dump($sign);
  158. var_dump($gas_limit);
  159. var_dump($gas_price);
  160. var_dump($nonce);
  161. exit;
  162. }
  163. /**
  164. * 查询用户NYTR余额
  165. * @param $eth_address 用户钱包地址
  166. * @return bool|mixed|string
  167. */
  168. function getNytrNum($eth_address)
  169. {
  170. $eth = new EthereumRPC();
  171. $tx = [];
  172. $tx['from'] = $eth_address;//用户地址
  173. $tx['to'] = $this->token_address;//系统钱包地址
  174. $tx['data'] = Utils::decodeSolMethod('balanceOf(address)', [$eth_address]);
  175. $balance = $eth->call($tx);
  176. $balance = Utils::hex2dec($balance);
  177. $balance = Utils::int2fund($balance); // 18位小数
  178. $balance = Utils::fund2int($balance, 2);
  179. return $balance;
  180. }
  181. /**
  182. * 获取ETH余额
  183. * @param $eth_address 用户钱包地址
  184. * @return bool|mixed|string
  185. */
  186. function getEthNum($eth_address)
  187. {
  188. $eth = new EthereumRPC();
  189. $eth_num = $eth->getBalance($eth_address);
  190. $eth_num = Utils::hex2dec($eth_num);
  191. $eth_num = Utils::int2fund($eth_num, 18);
  192. return $eth_num;
  193. }
  194. function nytrWithholdServiceCharge($tx){
  195. $eth = new EthereumRPC();
  196. $gasPrice = $eth->getGasPrice(); // 手续费
  197. $tx = [
  198. 'from' => '0x02b9132724a056b43944426bbebebf07a064e972',
  199. 'to' => '0xc3d7901a8eebbcd8b0873e9aa7e20440b3014761',
  200. 'value'=>'0x0',
  201. 'data'=>$tx['data'],
  202. ];
  203. $gasLimit = $eth->estimateGas($tx);
  204. // 手续费交易
  205. $serviceFee = Utils::dec2hex('2000000000000000'); // 手续费
  206. // 广播手续费
  207. //0x51eba8cdd9d14193cb4321a63395eef616f395c3
  208. //925baa5153e40866a474bd1311baf058c9f3466260b2fc7e1cf1ace8065e9658
  209. $transaction = [
  210. 'depend' => 0,
  211. // 'from' =>$this->sys_address,
  212. 'from' =>'0x02b9132724a056b43944426bbebebf07a064e972',
  213. 'to' => '0xc3d7901a8eebbcd8b0873e9aa7e20440b3014761',
  214. 'nonce' => '',
  215. 'value' =>$serviceFee,
  216. 'data' => '',
  217. 'gas' => $gasLimit,
  218. 'chain_id' => $eth->chainId,
  219. 'gas_price' => '',
  220. 'gas_limit' => '',
  221. 'sign' => '',
  222. 'hash' => '',
  223. ];
  224. $nonce = $eth->getTransactionCount($transaction['from']);
  225. $transaction['nonce'] = $nonce;//交易顺序十六进制。由eth_getTransactionCount获取
  226. var_dump($nonce);
  227. // $transaction['nonce'] = $this->getNonce($tx['from']);//交易顺序十六进制。由eth_getTransactionCount获取
  228. var_dump($gasPrice);
  229. $transaction['gas_price'] = $gasPrice;//燃料十六进制。由eth_estimateGas获取
  230. // $transaction['gas_price'] = $gasPrice;//燃料十六进制。由eth_estimateGas获取
  231. $transaction['gas_limit'] = $gasLimit;
  232. var_dump($transaction);
  233. // $sign = $this->sign($transaction, $this->sys_key);//交易签名
  234. $sign = $this->sign($transaction, '527a4fd9bdb84d02ffb8046cb5704642969c95ca67cfa5535511fd38c358c2a1');//交易签名
  235. $hash = $eth->sendRawTransaction($sign, $error);//广播交易
  236. var_dump($hash);
  237. var_dump($error);exit;
  238. if (!$hash) {
  239. return ['code'=>'0','data'=>$error,'msg'=>empty($error['message'])?'广播交易失败':$error['message']];
  240. } else {
  241. return ['code'=>'1','data'=>['hash'=>$hash],'msg'=>'广播交易成功'];
  242. }
  243. }
  244. /**
  245. * NYTR 转账
  246. * @param $tx
  247. * @param $from_key
  248. * @return array
  249. */
  250. function ntrTransferAccounts($tx, $from_key)
  251. {
  252. $eth = new EthereumRPC();
  253. // token 交易
  254. $transaction = [
  255. 'depend' => 0,//代扣手续费ID
  256. 'from' => $tx['from'],
  257. 'to' => $tx['to'],
  258. 'nonce' => '',
  259. 'value' => !empty($tx['value']) ? $tx['value'] : '0x0',
  260. 'data' => !empty($tx['data']) ? $tx['data'] : Utils::fixHex(bin2hex('NYT')),
  261. 'chain_id' => $eth->chainId,
  262. 'gas_price' => '',
  263. 'gas_limit' => '',
  264. 'sign' => '',
  265. 'hash' => '',
  266. ];
  267. $nonce = $eth->getTransactionCount($transaction['from']);
  268. $transaction['nonce'] = $nonce;//交易顺序十六进制。由eth_getTransactionCount获取
  269. $gas_price = $eth->getGasPrice();
  270. $gas_price = Utils::dec2hex(Utils::toWei("5gwei") + Utils::hex2dec($gas_price));
  271. $transaction['gas_price'] = $gas_price;//燃料十六进制。由eth_estimateGas获取
  272. $gas_limit = $this->getGasLimit($transaction);
  273. $transaction['gas_limit'] = $gas_limit;
  274. var_dump($transaction);
  275. //
  276. $sign = $this->sign($transaction, $from_key); //交易签名
  277. var_dump($sign);
  278. $hash = $eth->sendRawTransaction($sign, $error);//广播交易
  279. var_dump($hash);exit;
  280. if (!$hash) {
  281. return ['code'=>'0','data'=>$error,'msg'=>empty($error['message'])?'广播交易失败':$error['message']];
  282. } else {
  283. return ['code'=>'1','data'=>['hash'=>$hash],'msg'=>'广播交易成功'];
  284. }
  285. }
  286. function getSendTransaction($transaction){
  287. $tx = [];
  288. $tx['from'] = $transaction['from'];
  289. $tx['to'] =$transaction['to'];
  290. $tx['value'] =$transaction['value'];
  291. $tx['gas'] =$transaction['gas'];
  292. $tx['gasPrice'] =$transaction['gas_price'];
  293. $tx['nonce'] =$transaction['nonce'];
  294. $tx['data'] = '';
  295. return $tx;
  296. }
  297. /**
  298. * 查询交易结果
  299. * @param $hash
  300. * @return bool|mixed 成功返回交易信息 失败返回false
  301. */
  302. function getTransactionReceipt($hash)
  303. {
  304. $eth = new EthereumRPC();
  305. $receipt = $eth->getTransactionReceipt($hash);//交易查询
  306. return $receipt;
  307. }
  308. /**
  309. * 转账内容拼接
  310. * @param $from
  311. * @param $to
  312. * @param $value
  313. * @param $data
  314. * @return array
  315. * @throws
  316. */
  317. protected function build($from, $to, $value, $data)
  318. {
  319. $tx = [];
  320. $tx['from'] = $from;
  321. $tx['to'] = $to;
  322. $tx['value'] = $value;
  323. $tx['data'] = $data;
  324. return $tx;
  325. }
  326. /**
  327. * @param $transaction
  328. * @return string
  329. */
  330. public static function getGasLimit($transaction)
  331. {
  332. $tx = [
  333. 'from' => $transaction['from'],
  334. 'to' => $transaction['to'],
  335. 'nonce' => $transaction['nonce'],
  336. 'value' => $transaction['value'],
  337. 'data' => $transaction['data'],
  338. 'chainId' => $transaction['chain_id'],
  339. 'gasPrice' => $transaction['gas_price'],
  340. ];
  341. $eth = new EthereumRPC();
  342. $gasLimit = $eth->estimateGas($tx);
  343. if (!$gasLimit) {
  344. $gasLimit = 10 * 10000; // 预估失败, 最高10万
  345. }
  346. return $gasLimit;
  347. }
  348. protected static function sign($transaction, $key)
  349. {
  350. $tx = [
  351. 'from' => $transaction['from'],
  352. 'to' => $transaction['to'],
  353. 'nonce' => $transaction['nonce'],
  354. 'value' => $transaction['value'],
  355. 'data' => $transaction['data'],
  356. 'chainId' => $transaction['chain_id'],
  357. 'gasPrice' => $transaction['gas_price'],
  358. 'gasLimit' => $transaction['gas_limit'],
  359. ];
  360. // 数据签名
  361. $tr = new Transaction($tx);
  362. $tr->sign($key);
  363. return Utils::fixHex($tr->serialize()->toString('hex'));
  364. }
  365. public function nytr()
  366. {
  367. $member = Member::where('username', request()->input('user_name', ''))->first();
  368. if( empty($member) ){
  369. return response()->json([
  370. 'msg' => '账户不存在',
  371. 'data' => [],
  372. 'code' => 0,
  373. ]);
  374. }
  375. $sign = $this->wxSign([
  376. 'user_name' => request()->input('user_name', ''),
  377. 'money' => request()->input('money', ''),
  378. 'send_time' => request()->input('send_time', ''),
  379. 'token' => request()->input('token', ''),
  380. ]);
  381. if( $sign != strtoupper(request()->input('token', '')) ){
  382. return response()->json([
  383. 'msg' => 'token错误',
  384. 'data' => [],
  385. 'code' => 0,
  386. ]);
  387. }
  388. if( request()->input('money', '') <= 0 ){
  389. return response()->json([
  390. 'msg' => '数目小于等于零',
  391. 'data' => [],
  392. 'code' => 0,
  393. ]);
  394. }
  395. // 会员添加NYTR
  396. try{
  397. DB::beginTransaction();
  398. Member::where('id', $member->{'id'})->increment('old_nytr', request()->input('money', '') * MemberServer::$NYTR);
  399. DB::table('nytr_nyts')->insert([
  400. 'member_id' => $member->{'id'},
  401. 'username' => $member->{'username'},
  402. 'money' => request()->input('money', ''),
  403. 'updated_at' => date('Y-m-d H:i:s', time()),
  404. 'created_at' => date('Y-m-d H:i:s', time()),
  405. ]);
  406. Log::info('OLD-NYTR(SUCCESS):'.request()->input('money', ''));
  407. DB::commit();
  408. return response()->json([
  409. 'msg' => '成功',
  410. 'data' => [],
  411. 'code' => 1,
  412. ]);
  413. }catch (\Exception $e){
  414. DB::rollBack();
  415. Log::info('OLD-NYTR:'.$e->getMessage()." ".$e->getFile()." ".$e->getCode());
  416. return response()->json([
  417. 'msg' => '失败',
  418. 'data' => [],
  419. 'code' => 0,
  420. ]);
  421. }
  422. }
  423. /**
  424. * 签名
  425. * @param $data
  426. * @return string
  427. */
  428. private function wxSign($data)
  429. {
  430. ksort($data);
  431. $str = '';
  432. foreach ($data as $key => $val) {
  433. if ($val && $key != 'token') {
  434. if ($str != '') $str .= '&';
  435. $str .= "{$key}={$val}";
  436. }
  437. }
  438. $str .= '&key=' . $this->sing_key;
  439. $sign = strtoupper(md5($str));
  440. return $sign;
  441. }
  442. }