trongrid加密token转账

本文介绍了一种基于Tron区块链的转账及余额查询服务实现方法。通过构造交易并利用Secp256k1算法进行签名,文章详细展示了如何发起代币转账,并提供了查询账户余额的具体步骤。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

composer 安装扩展 composer require kornrunner/secp256k1

<?php
namespace app\admin\service;

use think\facade\Cache;
use kornrunner\Secp256k1;
use kornrunner\Signature\Signature;

class TrxrpcService {

  private  $address ;
  private  $port ;


  public function __construct($host = '',$port = '',$user = '',$pass = '',$protocal='http')
  {
      $this->address = "https://api.trongrid.io";
      $this->address_wallet = "https://api.trongrid.io";// "http://47.241.24.41";
      $this->port = 8090;//8091    
      $this->port_wallet = 8090;// 8090;          

  }
  
  public static function sign(string $message, string $privateKey): string
{
    $secp = new Secp256k1();

    /** @var Signature $sign */
    $sign = $secp->sign($message, $privateKey, ['canonical' => false]);

    return $sign->toHex() . bin2hex(implode('', array_map('chr', [$sign->getRecoveryParam()])));
}

  public  function get_Balance($addr)
  { 

    $hex_addr = $this->base58check2HexString($addr);
    //$path = "walletsolidity/getaccount";
    $path = "wallet/getaccount";
    $post_data = array('address'=>$hex_addr);
    $result =  json_decode($this->request($path,$post_data),true);
    $ret = array();
    
    if(isset($result['balance'])){
      $ret['balance'] = $result['balance']/pow(10,6) ;
      return array('code'=>1,'data'=>$ret);    
    }else{
      return array('code'=>0,'data'=>json_encode($result)); 
    }
  }

  
  //eth的token余额
  public  function get_TokenBalance($addr,$token_contract='TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t',$decimals=6)
  {   
      $hex_addr = $this->base58check2HexString($addr);
      $hex_token = $this->base58check2HexString($token_contract);

      $path = "wallet/triggerconstantcontract";//"wallet/triggersmartcontract";

      $post_data = array(
          'contract_address'=>$hex_token,
          'function_selector'=>"balanceOf(address)",
          'parameter'=> "000000000000000000000000".substr($hex_addr,2),
          'owner_address'=>$hex_addr
        );
      $result =  json_decode($this->request($path,$post_data),true);
      $ret = array();
      if($result['result']['result']===true){
        $hex_number = preg_replace('/^0+/','',$result['constant_result'][0]);
        //var_dump($result['constant_result']);
        //var_dump($hex_number);
        //die();
        if(empty($hex_number)){
             $num = 0;
        }else{
             $num = gmp_init($hex_number,16);
            $num = round(gmp_strval($num,10)/pow(10,$decimals),8) ;//转为十进制          
        }
        $ret['balance'] = $num;
        return array('code'=>1,'data'=>$ret);    
      }else{
        return array('code'=>0,'data'=>$result['msg']); 
      }
  }

  //transfer token
  public  function send_TokenTransactions($from, $to, $value, $pwd,$token_contract = 'TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t',$decimals=6){
      //创建交易
      $path = "wallet/triggersmartcontract";
      $hex_from =  $this->base58check2HexString($from);
      $hex_to =  $this->base58check2HexString($to);
      $hex_token =  $this->base58check2HexString($token_contract);

      $value_hex =  $this->bc_dechex($value*pow(10,$decimals));
      $format_str = $value_hex;
      for ($i=0; $i < (64-strlen($value_hex)); $i++) {
          $format_str = '0'.$format_str;
      }

      $post_data = array(
        'owner_address'=>$hex_from,
        'contract_address'=>$hex_token,
        'function_selector'=>"transfer(address,uint256)",
        'parameter'=> "000000000000000000000000".substr($hex_to,2).$format_str,
        'call_value'=>0,
        'fee_limit'=>100000000
      );
      $result =  json_decode($this->request($path,$post_data),true);
      if(isset($result['transaction'])){
          $transaction  = $result['transaction'];
          $txId  = $transaction['txID'];
          //var_dump($txId);
      }else{
        return array('code'=>0,'data'=>json_encode($result)); 
      } 
      //var_dump($result);
    //   print_r($transaction);exit;
      //签名交易
    //   $path = "wallet/gettransactionsign";
    //   $post_data = array('transaction'=>$transaction,'privateKey'=>$pwd);
    //   $transaction['txID'] = "13ada8ed21287f129f24b31ff2f411d0403d380da2222ac16b29050a7a1e5971";
      $result2['signature'] = self::sign($transaction['txID'],$pwd);
    //   $result2 =  json_decode($this->request($path,$post_data),true);
    //  print_r($result2);exit;
      if(!isset($result2['signature'])){
        return array('code'=>0,'data'=>json_encode($result2)); 
      } 
      
      $result2['raw_data'] = $transaction['raw_data'];
      
      $result2['raw_data_hex'] = $transaction['raw_data_hex'];
      //var_dump($result2);
      //广播交易
      $path = "wallet/broadcasttransaction";
      $post_data = $result2;
      
    //   print_r($post_data);exit;
      $result3 =  json_decode($this->request($path,$post_data),true);
      if(isset($result3['result'])&&$result3['result']==true){
        $ret = array();
        $ret['tx_id']  = $txId;         
        return array('code'=>1,'data'=>$ret);    
      }else{
        return array('code'=>0,'data'=>json_encode($result3)); 
      } 
  }

  private  function request($path,$post_data)
  {

      if (strlen($this->address) <= 0 || $this->port <= 0) {
          echo "eth client address or port error";
          exit();
      }
      // $url = $this->address . ":" . $this->port. "/". $path;
      $url = $this->address . "/". $path;
      //$data = json_encode($post_data);
      $data = $post_data;
      //echo " $url";
      //echo " $data";die();
      return $this->post($url, json_encode($data));
  }

  private  function request2($path,$post_data)
  {

      if (strlen($this->address) <= 0 || $this->port <= 0) {
          echo "eth client address or port error";
          exit();
      }
      $url = $this->address_wallet . ":" . $this->port_wallet. "/". $path;
      //$data = json_encode($post_data);
      $data = $post_data;
      //echo " $url";
      //echo " $data";die();
      return $this->post($url, json_encode($data));
  }



  // curl for request
  private  function post($url, $post_data = array(), $timeout = 10)
  {
    $curl = curl_init(); // 启动一个CURL会话
    curl_setopt($curl, CURLOPT_URL, $url); // 要访问的地址
    curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, 0); // 对认证证书来源的检查
    //curl_setopt($curl, CURLOPT_USERAGENT, $_SERVER['HTTP_USER_AGENT']); // 模拟用户使用的浏览器
    //curl_setopt($curl, CURLOPT_FOLLOWLOCATION, 1); // 使用自动跳转
    curl_setopt($curl, CURLOPT_HTTPHEADER, array('Content-Type: application/json', "TRON-PRO-API-KEY:c5bb16bd-88fa-4dde-b211-b4f9fd8e1c23"));
    curl_setopt($curl, CURLOPT_AUTOREFERER, 1); // 自动设置Referer
    curl_setopt($curl, CURLOPT_POST, 1); // 发送一个常规的Post请求
    curl_setopt($curl, CURLOPT_POSTFIELDS, $post_data); // Post提交的数据包
    curl_setopt($curl, CURLOPT_TIMEOUT, $timeout ); // 设置超时限制防止死循环
    curl_setopt($curl, CURLOPT_HEADER, 0); // 显示返回的Header区域内容
    curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1); // 获取的信息以文件流的形式返回
    $tmpInfo = curl_exec($curl); // 执行操作
    if (curl_errno($curl)) {
        echo 'Errno'.curl_error($curl);//捕抓异常
    }
    curl_close($curl); // 关闭CURL会话
    return $tmpInfo; // 返回数据,json格式
  }



  private function base58_encode($string)
  {
      $alphabet = '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz';
      $base = strlen($alphabet);
      if (is_string($string) === false) {
          return false;
      }
      if (strlen($string) === 0) {
          return '';
      }
      $bytes = array_values(unpack('C*', $string));
      $decimal = $bytes[0];
      for ($i = 1, $l = count($bytes); $i < $l; $i++) {
          $decimal = bcmul($decimal, 256);
          $decimal = bcadd($decimal, $bytes[$i]);
      }
      $output = '';
      while ($decimal >= $base) {
          $div = bcdiv($decimal, $base, 0);
          $mod = bcmod($decimal, $base);
          $output .= $alphabet[$mod];
          $decimal = $div;
      }
      if ($decimal > 0) {
          $output .= $alphabet[$decimal];
      }
      $output = strrev($output);
      foreach ($bytes as $byte) {
          if ($byte === 0) {
              $output = $alphabet[0] . $output;
              continue;
          }
          break;
      }
      return (string) $output;
  }
  private function base58_decode($base58)
  {
      $alphabet = '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz';
      $base = strlen($alphabet);
      if (is_string($base58) === false) {
          return false;
      }
      if (strlen($base58) === 0) {
          return '';
      }
      $indexes = array_flip(str_split($alphabet));
      $chars = str_split($base58);
      foreach ($chars as $char) {
          if (isset($indexes[$char]) === false) {
              return false;
          }
      }
      $decimal = $indexes[$chars[0]];
      for ($i = 1, $l = count($chars); $i < $l; $i++) {
          $decimal = bcmul($decimal, $base);
          $decimal = bcadd($decimal, $indexes[$chars[$i]]);
      }
      $output = '';
      while ($decimal > 0) {
          $byte = bcmod($decimal, 256);
          $output = pack('C', $byte) . $output;
          $decimal = bcdiv($decimal, 256, 0);
      }
      foreach ($chars as $char) {
          if ($indexes[$char] === 0) {
              $output = "\x00" . $output;
              continue;
          }
          break;
      }
      return $output;
  }
  
  //encode address from byte[] to base58check string
  private function base58check_en($address)
  {
      $hash0 = hash("sha256", $address);
      $hash1 = hash("sha256", hex2bin($hash0));
      $checksum = substr($hash1, 0, 8);
      $address = $address.hex2bin($checksum);
      $base58add = $this->base58_encode($address);
      return $base58add;
  }
  
  //decode address from base58check string to byte[]
  private function base58check_de($base58add)
  {
      $address = $this->base58_decode($base58add);
      $size = strlen($address);
      if ($size != 25) {
          return false;
      }
      $checksum = substr($address, 21);
      $address = substr($address, 0, 21);     
      $hash0 = hash("sha256", $address);
      $hash1 = hash("sha256", hex2bin($hash0));
      $checksum0 = substr($hash1, 0, 8);
      $checksum1 = bin2hex($checksum);
      if (strcmp($checksum0, $checksum1)) {
          return false;
      }
      return $address;
  }
  
  private function hexString2Base58check($hexString){
      $address = hex2bin($hexString);
      $base58add = $this->base58check_en($address);
      return $base58add;
  }
  
  private function base58check2HexString($base58add){
      $address = $this->base58check_de($base58add);
      $hexString = bin2hex($address);
      return $hexString;
  }
  
  private function hexString2Base64($hexString){
      $address = hex2bin($hexString);
      $base64 = base64_encode($address);
      return $base64;
  }
  
  private function base642HexString($base64){
      $address = base64_decode($base64);
      $hexString = bin2hex($address);
      return $hexString;
  }
  
  private function base58check2Base64($base58add){
      $address = $this->base58check_de($base58add);
      $base64 = base64_encode($address);
      return $base64;
  }
  
  private function base642Base58check($base64){
      $address = base64_decode($base64);
      $base58add = $this->base58check_en($address);
      return $base58add;
  }

  private  function bc_dechex($number)
  {
      if ($number <= 0) {
          return false;
      }
      $conf = ['0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'];
      $char = '';
      do {
          $key = fmod($number, 16);
          $char = $conf[$key].$char;
          $number = floor(($number-$key)/16);
      } while ( $number > 0);
      return $char;
  }
}

?>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

weixin_41997115

您的鼓励是我最大的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值