0, 'from' => $from, 'to' => $to, 'nonce' => '', 'coin_id' => $coin_id, 'value' => '0x0', 'data' => !empty($tx['data']) ? $tx['data'] : Utils::fixHex(bin2hex('NYT')), 'chain_id' => 0, 'gas_price' => '', 'gas_limit' => '', 'to_address' => $to, 'sign' => '', 'success' => '', 'hash' => $status == 5 ? '系统内部转账,直接成功,无需链上广播' : '', 'from_key' => $from_key, 'money' =>round($money,6), 'status' => $status, 'type' => $status_type, 'm_id' => $member_id, 'order_id' => $order_id, ]; $transaction = Broadcast::create($transaction); return $transaction->{'id'}; } /** * 广播查询 */ public function getBroadcast() { $list = Broadcast::where('status', '2')->select(['id', 'm_id', 'from', 'to', 'value', 'coin_id', 'type', 'sign', 'money', 'from_key', 'coin_id', 'hash', 'order_id'])->limit(100)->get(); $ret_type=false; if (empty($list)) return $ret_type; $bnbServer=BanRPC::creatServer(); foreach ($list as $value) { $receipt = $bnbServer->getTransactionReceipt($value['hash']);//交易查询 if (empty($receipt)) { //交易正在广播中,下次继续查询 continue; } else { //交易已完成 返回数据格式数据 ,将数据json保存 $distribution=ContractDistribution::where('id',$value->{'order_id'})->where('type',$value->{'type'})->first(); if ($receipt['status'] != '0x1') { $update_info['error'] = '广播提交失败'; $update_info['status'] = 3; $distribution->update(['status' => 2]); } else { $update_info['status'] = 4; $update_info['end_time'] = time(); $distribution->update(['status' => 3]); } $value->update($update_info); } } return $list->count(); } /** * 交易广播 */ function sendBroadcast(){ $list = Broadcast::where('status', '1')->where([['end_time','=',0,'or'],['end_time','<=',time()-60,'or']])->select(['id', 'm_id', 'from', 'to', 'nonce', 'value', 'data', 'gas_price', 'gas_limit', 'sign', 'money', 'from_key', 'coin_id', 'depend','type','contract_address','order_id'])->limit(100)->get(); $bnbServer=BanRPC::creatServer(); foreach ($list as $value){ $bnbNum=$bnbServer->getBalance($value->{'from'}); if(env('TEST_SERVE')){ $value->{'money'}='0.00001'; } if((empty($bnbNum) || $bnbNum<($value->{'money'}+0.0004)) && !env('TEST_SERVE')){ $transaction['end_time'] = time(); }else{ //ETH广播 $send_num = Broadcast::where('from', $value->{'from'})->where('status', '2')->count('id'); if ($send_num > 0) { sleep(1); continue; } $transaction = $this->sendBnb($value); if (empty($transaction) || empty($transaction['hash'])) { $transaction = ['status' => 3, 'error' => '广播失败']; } else { $transaction['status'] = 2; } if ($transaction) { Broadcast::where('id', $value->{'id'})->update($transaction); } } } return $list->count(); } function sendBnb($value){ $bnbServer=BanRPC::creatServer(); // try { $transaction['from'] = $value['from']; $transaction['to'] = $value['to']; $transaction['chain_id'] = $bnbServer->chainId; $transaction['value'] = Utils::dec2hex(Utils::fund2int($value['money'] )); // 转账金额 $transaction['data'] = '0x0'; // $transaction['data'] = Utils::decodeSolMethod('transfer(address,uint256)', [$value['to'], Utils::fund2int($value['money'], 18)]); $nonce = $bnbServer->getTransactionCount($value['from']); $transaction['nonce'] = $nonce; $gas_price = $bnbServer->getGasPrice(); // $transaction['gas_price'] = Utils::dec2hex(Utils::toWei("26gwei") + Utils::hex2dec($gas_price));//燃料十六进制。由eth_estimateGas获取 $transaction['gas_price'] =$gas_price;//燃料十六进制。由eth_estimateGas获取 $gas_limit =$this->getEthGasLimit($transaction); $transaction['gas_limit'] = $gas_limit; if($value->{'type'}==3)$value->{'m_id'}=0; $sign = $this->ethSign($transaction, PassServer::creatServer()->getSecretKey($value->{'from_key'}, $value->{'m_id'})); //交易签名 $transaction['sign'] = $sign; $error=''; $hash = $bnbServer->sendRawTransaction($transaction['sign'], $error);//广播交易 $transaction['hash'] = $hash; return $transaction; // } catch (\Exception $e) { // return false; // } } /** * @param $transaction * @return string */ public function getEthGasLimit($transaction) { $bnbServer=BanRPC::creatServer(); $tx = [ 'from' => $transaction['from'], 'to' => $transaction['to'], 'nonce' => $transaction['nonce'], 'value' => $transaction['value'], 'data' => $transaction['data'], 'chainId' => $bnbServer->chainId, 'gasPrice' => $transaction['gas_price'], ]; $gasLimit = $bnbServer->estimateGas($tx); if (!$gasLimit) { $gasLimit = 10 * 10000; // 预估失败, 最高10万 } return $gasLimit; } protected function build($from, $to, $value, $data) { $tx = []; $tx['from'] = $from; $tx['to'] = $to; $tx['value'] = $value; $tx['data'] = $data; return $tx; } function ethSign($transaction, $key) { $bnbServer=BanRPC::creatServer(); $tx = [ 'from' => $transaction['from'], 'to' => $transaction['to'], 'nonce' => $transaction['nonce'], 'value' => $transaction['value'], 'data' => $transaction['data'], 'chainId' => $bnbServer->chainId, 'gasPrice' => $transaction['gas_price'], 'gasLimit' => $transaction['gas_limit'], ]; // 数据签名 $tr = new Transaction($tx); $tr->sign($key); return Utils::fixHex($tr->serialize()); } }