<?php
namespace App\Common;

use App\Model\user_nonce;
class EthToken
{
    private $api_key='DSH5B24BQYKD1AD8KUCDY3SAQSS6ZAU175';
    private $api_host="https://api.etherscan.io/api";
    function request_by_curl($post_data) {
        $post_data['api_key'] = $this->api_key;
        $post_str = http_build_query($post_data);
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $this->api_host);
        curl_setopt($ch, CURLOPT_POSTFIELDS,$post_str);
        curl_setopt($ch, CURLOPT_POST, 1);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        $data = curl_exec($ch);
        curl_close($ch);
        $json = json_decode($data,true);
        if($json)
        {
            if(isset($json['error'])){
                return $json;
            }
            return $json['result'];
        }else{
            throw new \Exception("jsonException");
        }
    }

    /** 组装交易数组
     * @param        $from_address 来源地址
     * @param        $private      来源私钥
     * @param        $toAddress    目标地址
     * @param        $value        交易金额
     * @param string $num          金额和发送数量之前的倍数
     * @param int    $id           平台发送请求的唯一标识，防止重复提交
     * @return mixed
     * @throws \Exception
     */
    public function ethSend($from_address,$private,$toAddress,$value,$num="1000000000000000000",$id=0)
    {
        $toAddress = strtolower($toAddress);
        //对提现数字做处理
        $value = number_format($value,8,'.','');
        $num_str = explode('.',$value);
        $num_long = strlen($num_str[1]);
        $bs = pow(10,$num_long);
        $num_gs = substr($num,$num_long);
        $value = $bs*$value.$num_gs;
        $value = base_convert($value,10,16);
        if(strlen($value)%2!=0)
        {
            $value = '0'.$value;
        }
        $value = '0x'.$value;
        $Limit      = '0x5208';
        //gas price 获取，防止区块网络拥堵问题，先获取最低价格，然后加上5
        $gas_price = $this->getGasPrice();
        $price = base_convert($gas_price,16,10);
        $gas_price = $price+5000000000;
        $gas_price = '0x'.base_convert($gas_price,10,16);
        //唯一性数据，保证不发起重复交易
        $gasLimit   = $this->getGasLimit($from_address);
        //user_nonce 保存以太坊系列交易唯一性数据
        $nonce_info = new user_nonce();
        $nonce_exist = $nonce_info->where(['chainId'=>$id,'symbol'=>'eth']);
        if($nonce_exist){
            $nonce = $nonce_exist[0]['nonce'];
        }else{
            $nonce = $nonce_info->where(['symbol'=>'eth'],1,'nonce desc');
            $nonce = $nonce?$nonce:0;
        }
        //作比较 找出最大值
        if($nonce>0 && base_convert($gasLimit,16,10)<=base_convert($nonce,16,10)){
            $gasLimit = "0x".base_convert((base_convert($nonce,16,10)+1),10,16);
        }
        $txArray=[
            'nonce'    => $gasLimit,//存入的是16进制;
            'gasPrice' => $gas_price,
            'gasLimit' => $Limit,
            'to'       => $toAddress,
            'value'    => $value,//是否转换为十六进制
            'data'     => '',
            'chainId'  => $id,
            'ten'	   => base_convert($gasLimit,16,10),
        ];
        $result = $nonce_info->insert($txArray);
        if(!$result){
            return ['error'=>['message'=>'user_nonce插入失败']];
        }
        $cmd_json = addslashes(json_encode($txArray));
        //调用nodejs进行密码签名
        //TODO ejs.js和服务器上地址要一致
        exec("node C:/Users/Administrator/Desktop/ejs.js \"".$cmd_json."\" ".$private,$cmd_ret);
        if(!isset($cmd_ret[0]))
        {
            return ['error'=>['message'=>'nodejs sign Error']];
        }
        $result = $this->request_by_curl(
           ['tag'=>'latest',
               'module'=>'proxy',
               'hex'=>$cmd_ret[0],
               'action'=>'eth_sendRawTransaction',
           ]);
        return $result;
    }

    public function getGasLimit($address)
    {
        return $this->request_by_curl(
            ['tag'=>'latest',
                'module'=>'proxy',
                'address'=>$address,
                'action'=>'eth_getTransactionCount',
            ]);
    }

    //得到gas价格
    private function getGasPrice()
    {
        return $this->request_by_curl(
            ['tag'=>'latest',
                'module'=>'proxy',
                'action'=>'eth_gasPrice',
            ]
        );
    }
}
