java如何对接波场链

在这里插入图片描述

引言

本文将通过列举一些核心步骤的例子,确保大家看完之后能通过举一反三自行对接。
0,建立波场链连接
1,同步区块,
2,区块解析
3,交易状态判断
4,交易转账如何打包
5,如何调用链上指定方法
6,本地钱包如何生成

在这里插入图片描述

首先引入tron核心pom依赖,由于科学上网的原因,我是直接从官网下的包,jar包我放在文章最后面
依赖配置如下

        <dependency>
            <groupId>com.github.tronprotocol</groupId>
            <artifactId>java-tron</artifactId>
            <version>Odyssey-v3.2</version>
            <scope>system</scope>
            <systemPath>${project.basedir}/src/main/resources/lib/java-tron-Odyssey-v3.2.jar</systemPath>
        </dependency>

上DEMO

0,建立波场链连接


 

import com.alibaba.fastjson.JSONObject;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.ResponseEntity;
import org.springframework.http.client.ClientHttpRequestFactory;
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
import org.springframework.web.client.RestTemplate;

import java.text.SimpleDateFormat;
import java.util.TimeZone;

 
public class TronRpcUtil {
    private static final Logger log = LoggerFactory.getLogger(TronRpcUtil.class);

    private static final RestTemplate restTemplate = new RestTemplate(getClientHttpRequestFactory());


    SimpleDateFormat dateFormatter = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");

    public TronRpcUtil() {
        dateFormatter.setTimeZone(TimeZone.getTimeZone("UTC"));
    }


    /**
     * get请求,返回JSONObject
     * @param url
     * @return
     */
    public ResponseEntity<JSONObject> get(String url) {
        ResponseEntity<JSONObject> responseEntity = null;
        try {
            responseEntity = restTemplate.getForEntity(url, JSONObject.class);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return responseEntity;
    }

    /**
     * get请求,返回String
     * @param url
     * @return
     */
    public ResponseEntity<String> getResponseString(String url) {
        ResponseEntity<String> responseEntity = null;
        try {
            responseEntity = restTemplate.getForEntity(url, String.class);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return responseEntity;
    }

    /**
     * post请求
     * @param url
     * @param parameterJson
     * @return
     */
    public ResponseEntity<JSONObject> post(String url, String parameterJson) {
        ResponseEntity<JSONObject> responseEntity = null;
        try {
            responseEntity = restTemplate.postForEntity(url, parameterJson, JSONObject.class);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return responseEntity;
    }

    /**
     * post请求
     *
     * @param url 测试网:https://api.shasta.trongrid.io/
     * @param parameterJson
     * @return
     */
    public ResponseEntity<String> postResponseString(String url, String parameterJson) {
        ResponseEntity<String> responseEntity = null;
        try {
            responseEntity = restTemplate.postForEntity(url, parameterJson, String.class);
        } catch (Exception e) {
             log.error("广播请求异常",e);
        }
        return responseEntity;
    }

    /**
     * 配置HttpClient超时时间
     * @return
     */
    private static ClientHttpRequestFactory getClientHttpRequestFactory() {
        RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(6000)
                .setConnectTimeout(10000).build();
        CloseableHttpClient client = HttpClientBuilder.create().setDefaultRequestConfig(requestConfig).build();
        return new HttpComponentsClientHttpRequestFactory(client);
    }
}

1,同步区块,

    public JSONObject getNewBlock() {
        String url = tronConfig.getInstance().getUrl() + WALLET + GET_NOW_BLOCK;
        ResponseEntity<String> responseEntity = tronRpc.getResponseString(url);
        if (responseEntity == null) return null;
        return JSONObject.parseObject(responseEntity.getBody());
    }
    public BigInteger getNewBlocknNumber() {

        JSONObject jsonObject = getNewBlock();
        if(jsonObject != null){
            return jsonObject.getJSONObject("block_header").getJSONObject("raw_data").getBigInteger("number");

        }
        return null;
    }

2,区块解析

            JSONObject jsonObject = tronWalletUtilService.getBlockByNum(blockNumber);

    public JSONObject getBlockByNum(BigInteger num) {
        String url = tronConfig.getInstance().getUrl() + WALLET + GET_BLOCK_BY_NUM;
        Map<String, BigInteger> map = new HashMap<>();
        map.put("num", num);
        String param = JsonUtils.objectToJson(map);
        return getPost(url, param);
    }
    private JSONObject getPost(String url, String param) {
        ResponseEntity<String> stringResponseEntity = tronRpc.postResponseString(url, param);
        if (stringResponseEntity == null) return null;
        return JSONObject.parseObject(stringResponseEntity.getBody());
    }

3,交易状态判断

    public JSONObject getTransaction(String hashId) {
        String url = tronConfig.getInstance().getUrl() + WALLET + GET_TRANSACTION;
        Map<String, String> map = new HashMap<>();
        map.put("value", hashId);
        String param = JsonUtils.objectToJson(map);
        ResponseEntity<String> stringResponseEntity = tronRpc.postResponseString(url, param);
        try {
            if (stringResponseEntity != null) return JSONObject.parseObject(stringResponseEntity.getBody());
        } catch (Exception e) {
            return null;
        }
        return null;
    }

4,交易转账如何打包

    /**
     * trx
     * @param owner
     * @param privateKey
     * @param to
     * @param amount
     * @return
     */
    @Override
    public String handleTransactionTRX(String owner, String privateKey, String to, BigInteger amount) {
        log.info("Tron 转账入参:{}, {}, {}, {}",owner,privateKey,to,amount);
        // 创建交易
        String url = tronConfig.getInstance().getUrl() + WALLET + CREATE_TRANSACTION;
        Map<String, Object> map = new HashMap<>();
        map.put("to_address", to);
        map.put("owner_address", owner);
        map.put("amount", amount);
        String param = JsonUtils.objectToJson(map);
        ResponseEntity<String> stringResponseEntity = tronRpc.postResponseString(url, param);
        log.info("创建交易:{}",stringResponseEntity);
        return signAndBroadcast(stringResponseEntity.getBody(), privateKey);
     }

/**
     * 交易TRC20
     *
     * @param owner
     * @param privateKey
     * @param to
     * @param amount
     * @param tokenHexAddr
     * @return
     */
    @Override
    public String handleTransactionTRC20(String owner, String privateKey, String to, BigInteger amount, String tokenHexAddr) {
        log.debug("trc20转账入参:owner:{},privateKey:{},to:{},amount:{},tokenHexAddr:{}",owner,privateKey,to,amount,tokenHexAddr);
        String url = tronConfig.getInstance().getUrl() + WALLET + TRIGGER_SMART_CONTRACT;
        // 格式化参数
        log.info("owner:{}, parameter:{}",owner,to);
        String parameter = formatParameter(to) + formatParameter(amount.toString(16));
        Map<String, Object> map = new HashMap<>();
        map.put("contract_address", tokenHexAddr);
        map.put("function_selector", "transfer(address,uint256)");
        //最高gas 不超过30trx
        map.put("fee_limit", 30000000);
        map.put("parameter", parameter);
        map.put("owner_address", owner);
        log.info(JsonUtils.objectToJson(map));
        ResponseEntity<String> stringResponseEntity = tronRpc.postResponseString(url, JsonUtils.objectToJson(map));
        JSONObject data = JSONObject.parseObject(stringResponseEntity.getBody());
        JSONObject transaction = data.getJSONObject("transaction");
        transaction.remove("visible");
        transaction.remove("raw_data_hex");
        return signAndBroadcast(JsonUtils.objectToJson(transaction), privateKey);
    }

5,如果调用链上指定方法

6,本地钱包如何生成

 

 
import org.spongycastle.math.ec.ECPoint;
import org.tron.common.crypto.ECKey;
import org.tron.common.crypto.Hash;
import org.tron.common.crypto.Sha256Sm3Hash;
import org.tron.common.utils.Base58;
import org.tron.common.utils.ByteArray;
import org.tron.common.utils.Utils;
import org.tron.core.exception.CipherException;
import org.tron.walletserver.WalletApi;

import java.math.BigInteger;

import static java.util.Arrays.copyOfRange;

public class ECCreateKey {

  private static byte[] private2PublicDemo(byte[] privateKey) {
    BigInteger privKey = new BigInteger(1, privateKey);
    ECPoint point = ECKey.CURVE.getG().multiply(privKey);
    return point.getEncoded(false);
  }


  private static byte[] public2AddressDemo(byte[] publicKey) {
    byte[] hash = Hash.sha3(copyOfRange(publicKey, 1, publicKey.length));
    //System.out.println("sha3 = " + ByteArray.toHexString(hash));
    byte[] address = copyOfRange(hash, 11, hash.length);
    address[0] = WalletApi.getAddressPreFixByte();
    return address;
  }

  public static String address2Encode58CheckDemo(byte[] input) {
    byte[] hash0 = Sha256Sm3Hash.hash(input);

    byte[] hash1 = Sha256Sm3Hash.hash(hash0);

    byte[] inputCheck = new byte[input.length + 4];

    System.arraycopy(input, 0, inputCheck, 0, input.length);
    System.arraycopy(hash1, 0, inputCheck, input.length, 4);

    return Base58.encode(inputCheck);
  }

  public static String private2Address() throws CipherException {
    ECKey eCkey = new ECKey(Utils.getRandom()); //

    String privateKey=ByteArray.toHexString(eCkey.getPrivKeyBytes());
    System.out.println("Private Key: " + privateKey);

    byte[] publicKey0 = eCkey.getPubKey();
    byte[] publicKey1 = private2PublicDemo(eCkey.getPrivKeyBytes());
    if (!ECCreateKey.equals(publicKey0, publicKey1)) {
      throw new CipherException("publickey error");
    }
    String publicKey=ByteArray.toHexString(publicKey0);
    System.out.println("Public Key: " + publicKey);

    byte[] address0 = eCkey.getAddress();
    byte[] address1 = public2AddressDemo(publicKey0);
    if (!ECCreateKey.equals(address0, address1)) {
      throw new CipherException("address error");
    }
    String address=ByteArray.toHexString(address0);
    System.out.println("Address: " +address);

    String base58checkAddress0 = WalletApi.encode58Check(address0);
    String base58checkAddress1 = address2Encode58CheckDemo(address0);
    if (!base58checkAddress0.equals(base58checkAddress1)) {
      throw new CipherException("base58checkAddress error");
    }
    String dataList=privateKey+ TronConstant.DELIMIT+base58checkAddress1+TronConstant.DELIMIT+address;
    return dataList;
  }

  public static boolean equals(byte[] a, byte[] a2) {
    if (a==a2)
      return true;
    if (a==null || a2==null){
      System.out.println("都为null");
      return false;
    }


    int length = a.length;
    if (a2.length != length){
      System.out.println("长度不等");
      return false;
    }


    for (int i=0; i<length; i++)
      if (a[i] != a2[i]){
        System.out.println("值不等");
        return false;
      }


    return true;
  }

  public static void main(String[] args) throws CipherException {

 
    System.out.println("================================================================\r\n");
    String dataList = private2Address();
    System.out.println("base58Address: " + dataList);
    String[] split = dataList.split(TronConstant.DELIMIT);
    String privateKey = split[0];
    String address = split[1];
    String hexAddress =split[2];
    System.out.println("privateKey:"+privateKey+" address:"+address+" hexAddress:"+hexAddress);
  }
}

到这里基本上一套完整的流程已经对接完了,剩下的稍微琢磨一下就全明白了,至于详细的波场链字段说明,参考api即可

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/533560.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

蓝桥杯物联网竞赛_STM32L071KBU6_我的全部省赛及历年模拟赛源码

我写的省赛及历年模拟赛代码 链接&#xff1a;https://pan.baidu.com/s/1A0N_VUl2YfrTX96g3E8TfQ?pwd9k6o 提取码&#xff1a;9k6o

【MATLAB源码-第44期】基于matlab的2*2MIMO-LDPC系统的误码率仿真。

操作环境&#xff1a; MATLAB 2022a 1、算法描述 2x2 MIMO&#xff08;多输入多输出&#xff09;和LDPC&#xff08;低密度奇偶校验码&#xff09;编码是在通信系统中常用的技术&#xff0c;它们通常用于提高无线通信系统的性能和可靠性。 1. 2x2 MIMO&#xff1a; 2x2 MIM…

14.java openCV4.x 入门-Core之图像融合

专栏简介 &#x1f492;个人主页 &#x1f4f0;专栏目录 点击上方查看更多内容 &#x1f4d6;心灵鸡汤&#x1f4d6;我们唯一拥有的就是今天&#xff0c;唯一能把握的也是今天建议把本文当作笔记来看&#xff0c;据说专栏目录里面有相应视频&#x1f92b; &#x1f9ed;文…

Linux进阶篇:centos7扩展root分区:LVM应用案例

centos7扩展root分区&#xff1a;LVM应用案例 当服务器根分区或者是root分区存储空间快用完的时候&#xff0c;并且重要的数据都在root分区下&#xff0c;当如何应对&#xff0c;没关系坐好&#xff0c;分分钟解决它&#xff0c;我们可以进行分区扩容。 一 添加一块新的硬盘 …

0 idea搭建springboot项目

1 2 3 4 5 配置文件 application.yaml server:servlet:context-path: /app #项目名controller //注入到spring容器 Controller public class HelloController {GetMapping("hello")ResponseBodypublic String hello(){return "Hello,SpringBoot";} }启…

环信 IM 客户端将适配鸿蒙 HarmonyOS

自华为推出了自主研发操作系统鸿蒙 HarmonyOS 后&#xff0c;国内许多应用软件开始陆续全面兼容和接入鸿蒙操作系统。环信 IM 客户端计划将全面适配统鸿蒙 HarmonyOS &#xff0c;助力开发者快速实现社交娱乐、语聊房、在线教育、智能硬件、社交电商、在线金融、线上医疗等广泛…

JavaScript逆向爬取实战——使用Python实现列表页内容爬取

JavaScript逆向爬取—使用Python实现列表页内容爬取 1. 案例介绍 案例网址&#xff1a;https://spa6.scrape.center/&#xff0c; 如图所示&#xff1a; 点击任意一步电影&#xff0c;观察一下URL的变化&#xff0c;如图所示&#xff1a; 看到详情页URL包含了一个长字符串&am…

Ant Design Vue 表单验证手机号的正则

代码&#xff1a; pattern: /^1[3456789]\d{9}$/ 1. <a-form-item label"原手机号" v-bind"validateInfos.contactTel"><a-inputstyle"width: 600px"allow-clear:maxlength"20"placeholder"请输入原手机号"v-mo…

吴恩达机器学习ex3 python实现(详细注释)

文章目录 1、多分类1.1 数据集1.2 数据可视化1.3 矢量化 Logistic 回归1.3.1 向量化成本函数1.3.2 矢量化梯度 1.4 一对多分类 2.神经网络 1、多分类 在本练习中&#xff0c;您将使用逻辑回归和神经网络来识别手写数字&#xff08;从 0 到 9&#xff09;。 自动手写数字识别如…

马云支持阿里改革,预见AI时代的到来将带来巨大的变化

&#x1f989; AI新闻 &#x1f680; 马云支持阿里改革&#xff0c;预见AI时代的到来将带来巨大的变化 摘要&#xff1a;马云在阿里内网发表《致改革 致创新》帖子&#xff0c;这是其退休五年来首次深度分享对阿里改革创新及未来的看法。文章中&#xff0c;马云对蔡崇信和吴泳…

微服务-4 Nacos

目录 一、注册中心 二、配置管理 1. 添加配置 2. 配置自动刷新 3. 多环境配置共享​编辑 一、注册中心 服务列表&#xff1a; 服务详情&#xff1a; 二、配置管理 1. 添加配置 (1). 在 nacos 界面中添加配置文件&#xff1a; 配置列表&#xff1a; 配置详情&#xff1a;…

【C++学习】C++11新特性(第二节)—— 右值引用与移动语义超详解

文章目录 文章简介二.右值引用1.什么是左值&#xff0c;什么是右值&#xff1f;什么是左值引用&#xff0c;什么是右值引用&#xff1f;2.左值引用与右值引用比较 三.右值引用使用场景和意义1.左值引用的使用场景&#xff1a;2.左值引用的短板&#xff1a;3.右值引用与移动构造…

Unity之Unity面试题(五)

内容将会持续更新&#xff0c;有错误的地方欢迎指正&#xff0c;谢谢! Unity之Unity面试题&#xff08;五&#xff09; TechX 坚持将创新的科技带给世界&#xff01; 拥有更好的学习体验 —— 不断努力&#xff0c;不断进步&#xff0c;不断探索 TechX —— 心探索、心进取…

LVM逻辑卷

LVM逻辑卷 一.逻辑卷简介 LVM 是 Logical Volume Manager 的简称&#xff0c;译为中文就是逻辑卷管理。它是 Linux 下对硬盘分区的一种管理机制。LVM 适合于管理大存储设备&#xff0c;并允许用户动态调整文件系统的大小。此外&#xff0c;LVM 的快照功能可以帮助我们快速备份…

【AI大模型应用开发】【LangChain系列】 LangChain框架介绍,实现LangChain的Hello World

AI时代&#xff0c;相信大家或多或少都听过 LangChain 的大名。通俗的说&#xff0c;LangChain是一个面向大模型的开发框架&#xff08;SDK&#xff09;。 目前 LangChain 仍在快速迭代中&#xff0c;所以在使用中要时刻关注你所使用的版本和接口变更。 0. 认识LangChain框架 从…

Kafka 消费端消费重试和死信队列

系列文章目录 文章目录 系列文章目录前言前言 前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到网站,这篇文章男女通用,看懂了就去分享给你的码吧。 Spring-Kafka 提供消费重试的机制。当消息消费失败的时候,Spring-Kafka …

【QT】pro文件里添加又删除LIBS不影响运行的原因

我发现个问题啊&#xff0c;如果运行项目&#xff0c;发现报错&#xff0c;缺少某dll&#xff0c;接着你在pro文件里加上win32:LIBS -lOpengl32&#xff08;举个例子&#xff09;&#xff0c;接着可以运行了&#xff0c;接着把这行删掉&#xff0c;再运行&#xff0c;仍然可以…

中介者模式【行为模式C++】

1.简介 中介者模式是一种行为设计模式&#xff0c; 能让你减少对象之间混乱无序的依赖关系。 该模式会限制对象之间的直接交互&#xff0c; 迫使它们通过一个中介者对象进行合作。 亦称&#xff1a; 调解人、控制器、Intermediary、Controller、Mediator 2.示例 中介者模式在…

计算机组成原理(IO,输入输出)

1、“821.2016T1(1)”&#xff0c;表示821真题&#xff0c;2016年的题&#xff0c;T1是 选择题/填空题/大题 的第一题&#xff0c;其他类似标记也是相通 2、个人小白总结自用&#xff0c;不一定适用于其他人&#xff0c;请自行甄别 3、有任何疑问&#xff0c;欢迎私信探讨&…

uniapp开发h5端使用video播放mp4格式视频黑屏,但有音频播放解决方案

mp4格式视频有一些谷歌播放视频黑屏&#xff0c;搜狗浏览器可以正常播放 可能和视频的编码格式有关&#xff0c;谷歌只支持h.264编码格式的视频播放 将mp4编码格式修改为h.264即可 转换方法&#xff1a; 如果是自己手动上传文件可以手动转换 如果是后端接口调取的地址就需…