java调用以太坊私链上的合约方法

简介: 以下介绍java调用以太坊私链上的合约方法

使用 java调用以太坊私链上的合约方法


引入java依赖 pom


        <!--web3j-->
        <dependency>
            <groupId>org.web3j</groupId>
            <artifactId>core</artifactId>
            <version>3.4.0</version>
        </dependency>
        <dependency>
            <groupId>org.web3j</groupId>
            <artifactId>geth</artifactId>
            <version>3.4.0</version>
        </dependency>
        <dependency>
            <groupId>org.web3j</groupId>
            <artifactId>abi</artifactId>
            <version>3.4.0</version>
        </dependency>


配置文件 application.yml


contract:
  ctAddr: "************************************"  #游戏合约地址
  startAddr:  "************************************"   #顶级节点地址
  sendAddr:  "************************************"   #授权地址
  sendAddrPk:  "************************************"  
  gasPrice: 5000000000 # Gas Price越高,交易优先级越高,打包交易速度越快。
  gasLimit: 1500000  # Gas Limit 是用户愿意为执行某个操作或确认交易支付的最大Gas量(最少21,000)
  isAddGas: false #是否启用按当前市价进行加权矿工费用
  addGas:   2000000000 #所增加费用
  url: "https://mainnet.infura.io/d75c50732022222222222222222222" #正式网 or 测试网


创建java服务接口


import org.web3j.abi.datatypes.Type;
import java.math.BigInteger;
import java.util.List;
/**
 * @Datetime: 2020/6/23   10:35
 * @Author:   
 * @title
 */
public interface IBaseWeb3j {
    /**
     * 执行合约打包
     *
     * @param fromAddr        支付地址
     * @param fromPrivateKey  支付地址私钥
     * @param hashVal         合约地址
     * @param month           合约方法
     * @param gasPrice        旷工费用
     * @param inputParameters 方法参数
     * @return hash
     */
    String transact(String fromAddr, String fromPrivateKey, String hashVal, String month, BigInteger gasPrice, BigInteger gasLimit, List<Type> inputParameters);
}


实现类


import com.alibaba.fastjson.JSONObject;
import com.blockchain.server.contractGzhz.web3j.IBaseWeb3j;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.web3j.abi.FunctionEncoder;
import org.web3j.abi.TypeReference;
import org.web3j.abi.datatypes.Bool;
import org.web3j.abi.datatypes.Function;
import org.web3j.abi.datatypes.Type;
import org.web3j.crypto.Credentials;
import org.web3j.crypto.RawTransaction;
import org.web3j.crypto.TransactionEncoder;
import org.web3j.protocol.Web3j;
import org.web3j.protocol.core.DefaultBlockParameterName;
import org.web3j.protocol.core.methods.response.*;
import org.web3j.protocol.http.HttpService;
import org.web3j.utils.Numeric;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.List;
/**
 * @Datetime: 2020/6/23   10:36
 * @Author: 
 * @title
 */
@Component
public class BaseWeb3jImpl implements IBaseWeb3j {
    private static final Logger LOG = LoggerFactory.getLogger(BaseWeb3jImpl.class);
    static Web3j web3j;
    @Value("${contract.url}")
    private   String URL;
    @Value("${contract.addGas}")
    private BigInteger addGas;
    @Value("${contract.isAddGas}")
    private boolean isAddGas;
    public String transact(String fromAddr, String fromPrivateKey, String hashVal, String month, BigInteger gasPrice, BigInteger gasLimit, List<Type> inputParameters) {
        EthSendTransaction ethSendTransaction = null;
        BigInteger nonce = BigInteger.ZERO;
        String hash = null;
        try {
            if(web3j == null){
                web3j = Web3j.build(new HttpService(URL));
            }
            EthGetTransactionCount ethGetTransactionCount = web3j.ethGetTransactionCount(
                    fromAddr,
                    DefaultBlockParameterName.PENDING
            ).send();
            //根据配置是否开启根据实时市场gas费用,增加指定gas费用,加快打包速率
            if(isAddGas){
                 BigInteger gas  = web3j.ethGasPrice().send().getGasPrice();
                 LOG.info("获取到的gasPrice{}",gas);
                 gasPrice = addGas.add(gas);
            }
            //返回指定地址发生的交易数量。
            nonce =  ethGetTransactionCount.getTransactionCount();
            List outputParameters = new ArrayList();
            TypeReference<Bool> typeReference = new TypeReference<Bool>() {
            };
            outputParameters.add(typeReference);
            LOG.info("付给矿工的gasPrice为:{}",gasPrice);
            Function function = new Function(
                    month,
                    inputParameters,
                    outputParameters);
            String encodedFunction = FunctionEncoder.encode(function);
            Credentials credentials = Credentials.create(fromPrivateKey);
            RawTransaction rawTransaction = RawTransaction.createTransaction(nonce, gasPrice, gasLimit, hashVal,
                    encodedFunction);
            byte[] signedMessage = TransactionEncoder.signMessage(rawTransaction, credentials);
            String hexValue = Numeric.toHexString(signedMessage);
            ethSendTransaction = web3j.ethSendRawTransaction(hexValue).sendAsync().get();
            hash = ethSendTransaction.getTransactionHash();
            LOG.info(JSONObject.toJSONString(ethSendTransaction));
        } catch (Exception e) {
            if (null != ethSendTransaction) {
                LOG.info("失败的原因:" + ethSendTransaction.getError().getMessage());
                LOG.info("参数:fromAddr = " + fromAddr);
                LOG.info("参数:month = " + month);
                LOG.info("参数:gasPrice = " + gasPrice);
                LOG.info("参数:gasLimit = " + gasLimit);
                LOG.info("参数:inputParameters = " + JSONObject.toJSONString(inputParameters));
            }
            e.printStackTrace();
        }
        return hash;
    }


调用层


import com.blockchain.server.contractGzhz.service.SettlementService;
import com.blockchain.server.contractGzhz.web3j.IBaseWeb3j;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.web3j.abi.datatypes.Type;
import java.math.BigInteger;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
/**
 * @Datetime: 2020/6/23   11:47
 * @Author:
 * @title
 */
@Component
public class SettlementServiceImpl  {
    private static final Logger LOG = LoggerFactory.getLogger(SettlementServiceImpl.class);
    /*合约地址*/
    @Value("${contract.ctAddr}")
    private String ctAddr;
    /*初始地址*/
    @Value("${contract.startAddr}")
    private String startAddr;
    /*发币地址*/
    @Value("${contract.sendAddr}")
    private String sendAddr;
    /*发币地址私钥*/
    @Value("${contract.sendAddrPk}")
    private String sendAddrPk;
    @Value("${contract.gasLimit}")
    private BigInteger CT_GAS_LIMIT;
    @Value("${contract.gasPrice}")
    private BigInteger CT_GAS_PRICE;
    @Autowired
    IBaseWeb3j iBaseWeb3j;
    /**
     调用服务
    **/
    public void test() {
        try {
            List<Type> inputParameters = Arrays.asList( );
            iBaseWeb3j.transact(sendAddr,sendAddrPk,ctAddr,"month_name", CT_GAS_PRICE, CT_GAS_LIMIT,inputParameters);
        }catch (Exception ex){
            LOG.error("发生异常",ex);
        }
    }



相关文章
|
2月前
|
消息中间件 Java Kafka
在Java中实现分布式事务的常用框架和方法
总之,选择合适的分布式事务框架和方法需要综合考虑业务需求、性能、复杂度等因素。不同的框架和方法都有其特点和适用场景,需要根据具体情况进行评估和选择。同时,随着技术的不断发展,分布式事务的解决方案也在不断更新和完善,以更好地满足业务的需求。你还可以进一步深入研究和了解这些框架和方法,以便在实际应用中更好地实现分布式事务管理。
|
2月前
|
Java
java小工具util系列5:java文件相关操作工具,包括读取服务器路径下文件,删除文件及子文件,删除文件夹等方法
java小工具util系列5:java文件相关操作工具,包括读取服务器路径下文件,删除文件及子文件,删除文件夹等方法
85 9
|
2月前
|
安全 Java 开发者
Java中WAIT和NOTIFY方法必须在同步块中调用的原因
在Java多线程编程中,`wait()`和`notify()`方法是实现线程间协作的关键。这两个方法必须在同步块或同步方法中调用,这一要求背后有着深刻的原因。本文将深入探讨为什么`wait()`和`notify()`方法必须在同步块中调用,以及这一机制如何确保线程安全和避免死锁。
49 4
|
2月前
|
Java
深入探讨Java中的中断机制:INTERRUPTED和ISINTERRUPTED方法详解
在Java多线程编程中,中断机制是协调线程行为的重要手段。了解和正确使用中断机制对于编写高效、可靠的并发程序至关重要。本文将深入探讨Java中的`Thread.interrupted()`和`Thread.isInterrupted()`方法的区别及其应用场景。
71 4
|
2月前
|
Java 数据处理 数据安全/隐私保护
Java处理数据接口方法
Java处理数据接口方法
29 1
|
3月前
|
Java API
Java 对象释放与 finalize 方法
关于 Java 对象释放的疑惑解答,以及 finalize 方法的相关知识。
66 17
|
2月前
|
存储 Java 程序员
Java基础的灵魂——Object类方法详解(社招面试不踩坑)
本文介绍了Java中`Object`类的几个重要方法,包括`toString`、`equals`、`hashCode`、`finalize`、`clone`、`getClass`、`notify`和`wait`。这些方法是面试中的常考点,掌握它们有助于理解Java对象的行为和实现多线程编程。作者通过具体示例和应用场景,详细解析了每个方法的作用和重写技巧,帮助读者更好地应对面试和技术开发。
143 4
|
2月前
|
Java 测试技术 Maven
Java一分钟之-PowerMock:静态方法与私有方法测试
通过本文的详细介绍,您可以使用PowerMock轻松地测试Java代码中的静态方法和私有方法。PowerMock通过扩展Mockito,提供了强大的功能,帮助开发者在复杂的测试场景中保持高效和准确的单元测试。希望本文对您的Java单元测试有所帮助。
356 2
|
3月前
|
Java 开发者
在Java多线程编程中,创建线程的方法有两种:继承Thread类和实现Runnable接口
【10月更文挑战第20天】在Java多线程编程中,创建线程的方法有两种:继承Thread类和实现Runnable接口。本文揭示了这两种方式的微妙差异和潜在陷阱,帮助你更好地理解和选择适合项目需求的线程创建方式。
47 3
|
3月前
|
Java 大数据 API
别死脑筋,赶紧学起来!Java之Steam() API 常用方法使用,让开发简单起来!
分享Java Stream API的常用方法,让开发更简单。涵盖filter、map、sorted等操作,提高代码效率与可读性。关注公众号,了解更多技术内容。
130 5