您的位置 首页 java

java使用web3j链接自己智能合约(教程)

首先,我们要有自己的智能合约,我们使用测试网络(ropsten),还要有自己开发编号。申请如下:

地址:

注册登录,创建自己的项目

注意:选择测试ropsten链,复制自己的链接 web3j需要用到。

第二步:使用solidity编译自己的智能合约(个人理解就是链上的服务器脚本),为了案例的丰富性和实用性,全方位的展示web3j调度性,我们使用留言版智能合约模板,solidity代码如下(采用了8.15编译):

 // SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
//声明一个 结构体 用于留言保持
 struct  Message{
     string  word;
    address from;
    string timeStr;
}
contract Test_Web3j{
    Message[] public AllMsg;
    // 构造方法 
     constructor  (){

    }
    //接受留言
     Function  setWord(string memory sendMsgStr,string memory tStr)public returns(uint256){
        AllMsg.push(Message({word:sendMsgStr,from:msg.sender,timeStr:tStr}));
        return AllMsg.length;
    }
    //查询留言
    function getWord() public view returns(uint256,string memory,address,string memory){
        if(AllMsg.length==0){         //当没有留言数据时候,返回空
        return (0,"", address (0),"");
        }else{                                   //当有留言时候,返回最新的一条
        uint256 indexInt=AllMsg.length-1;
        Message storage thisMsg=AllMsg[indexInt];
        return (AllMsg.length,thisMsg.word,thisMsg.from,thisMsg.timeStr);
        }
    }
    //返回总留言的条数
    function getSize() public view returns(uint256){
    return AllMsg.length;
    }
    //测试方法1
    function testStr() public pure returns( String  memory){
    return "hello word";
    }
    function testInt(uint256 argInt) public pure returns(uint256){
    return argInt+10;
    }
}  

采用remix在线版发布合约,注意浏览器中需要安装metaMask;才需要ropsten有测试币

第三步 java 部分

 import  Java .math.BigInteger;
import java.util.Arrays;
import java.util.List;
import org.web3j.abi.FunctionEncoder;
import org.web3j.abi.FunctionReturn decode r;
import org.web3j.abi.datatypes.Function;
import org.web3j.abi.datatypes.Utf8String;
import org.web3j.abi.datatypes.Address;
import org.web3j.abi.datatypes.generated.Uint256;
import org.web3j.crypto.Credentials;
import org.web3j.crypto. Raw Transaction;
import org.web3j.crypto.TransactionEncoder;
import org.web3j.protocol.Web3j;
import org.web3j.protocol.core.DefaultBlockParameterName;
import org.web3j.protocol.core.methods. request .Transaction;
import org.web3j.protocol.core.methods.response.EthCall;
import org.web3j.protocol.core.methods.response.EthGetBalance;
import org.web3j.protocol.core.methods.response.EthSendTransaction;
import org.web3j.protocol.http.HttpService;
import org.web3j.abi.datatypes.Type;
import org.web3j.abi.TypeReference;
import org.web3j.tx.Contract;
import org.web3j.utils.Convert;
import org.web3j.utils.Numeric;

public class mainCreateSolitidyJava {
    public  static   void  main(String[] args) {
        try {

            String url = "#34;;

            String contractAddress="0x954e9A986467861********F5aEa8b83cAB63B6";                        //合约地址

            String fromAddr="0xb4377fb04FE5aDe3C35*******0cd354308807bF";                               //查询用户地址

            String input Private Key="4369ceac05601**************a29f2ab6a41e7c6f93f3ea55222c5d";  //该账号密钥

            //查询一下自己虚拟币的数量
            Web3j web3j = Web3j.build(new HttpService(url));
            //第二个参数: 区块 的参数,建议选最新区块
            EthGetBalance balance = web3j.ethGetBalance(fromAddr, DefaultBlockParameterName.LATEST).send();
            String blanceETH = Convert.fromWei(balance.getBalance().toString(), Convert.Unit.ETHER).toPlainString();//.concat(" ether");
            System.out.println("====> 拥有的以太坊币 :" + blanceETH);
            //测试调用方法一
            try {
                List input = Arrays.asList();                                               //输入参数
                List output = Arrays.asList(new TypeReference<Utf8String>() {});            //接受返回参数
                String methodName = "testStr";
                Function function = new Function(methodName,  input , output);
                String data = FunctionEncoder.encode(function);
                Transaction transaction = Transaction.createEthCallTransaction(fromAddr, contractAddress, data);
                EthCall ethCall = web3j.ethCall(transaction, DefaultBlockParameterName.LATEST).sendAsync().get();
                List<Type> results = FunctionReturnDecoder.decode(ethCall.getValue(), function.getOutputParameters());
                System.out.println("==111==>"+results.get(0).getValue());
            }catch ( Exception  e){
                e.printStackTrace();
            }
            //测试调用方法二
            try {
                List input = Arrays.asList(new Uint256(100));
                List output = Arrays.asList(new TypeReference<Uint256>() {});
                String methodName = "testInt";
                Function function = new Function(methodName, input, output);
                String data = FunctionEncoder.encode(function);
                Transaction transaction = Transaction.createEthCallTransaction(fromAddr, contractAddress, data);
                EthCall ethCall = web3j.ethCall(transaction, DefaultBlockParameterName.LATEST).sendAsync().get();
                List<Type> results = FunctionReturnDecoder.decode(ethCall.getValue(), function.getOutputParameters());
                System.out.println("==222==>"+results.get(0).getValue());
            }catch (Exception e){
                e.printStackTrace();
            }
            //测试调用方法三
            try {
                List input = Arrays.asList(new Utf8String("第一条留言"),new Utf8String("这是插入时间"));
                List output = Arrays.asList(new TypeReference<Uint256>() {});
                String methodName = "setWord";
                Function function = new Function(methodName, input, output);
                String encodedFunction = FunctionEncoder.encode(function);
                BigInteger nonce =NormalUtil.getNonce(web3j,fromAddr);        //获取nonce

                BigInteger gasPrice = NormalUtil.requestCurrentGasPrice(web3j);     //gas数
                BigInteger gasLimit = Contract.GAS_LIMIT;                           //限制gas数

                RawTransaction rawTransaction = RawTransaction.createTransaction(nonce, gasPrice, gasLimit, contractAddress, encodedFunction);

                Credentials credentials = Credentials.create(inputPrivateKey);
                 byte [] signMessage = TransactionEncoder.signMessage(rawTransaction, credentials);
                String hexValue = Numeric.toHexString(signMessage);
                EthSendTransaction  ethResult=web3j.ethSendRawTransaction(hexValue).sendAsync().get();

                System.out.println("交易编号:"+ethResult.getTransaction Hash ());

            }catch (Exception e){
                e.printStackTrace();
            }
            //获得总留言数量

            try {
                List input = Arrays.asList();
                List ouput = Arrays.asList(new TypeReference<Uint256>() {});
                String methodName = "getSize";
                Function function = new Function(methodName, input, ouput);
                String data = FunctionEncoder.encode(function);
                Transaction transaction = Transaction.createEthCallTransaction(fromAddr, contractAddress, data);
                EthCall ethCall = web3j.ethCall(transaction, DefaultBlockParameterName.LATEST).sendAsync().get();
                List<Type> results = FunctionReturnDecoder.decode(ethCall.getValue(), function.getOutputParameters());

                System.out.println("==333==>"+results.get(0).getValue());


            }catch (Exception e){
                e.printStackTrace();
            }


            //调用自己合约地址
            try {
                List input = Arrays.asList();
                List ouput = Arrays.asList(new TypeReference<Uint256>(){},new TypeReference<Utf8String>() {},new TypeReference<Address>() {},new TypeReference<Utf8String>() {});
                String methodName = "getWord";
                Function function = new Function(methodName, input, ouput);

                String data = FunctionEncoder.encode(function);
                Transaction transaction = Transaction.createEthCallTransaction(fromAddr, contractAddress, data);

                EthCall ethCall = web3j.ethCall(transaction, DefaultBlockParameterName.LATEST).sendAsync().get();
                //System.out.println(ethCall.getValue());
                List<Type> results = FunctionReturnDecoder.decode(ethCall.getValue(), function.getOutputParameters());
                System.out.println("==444==>"+results.get(1).getValue());

            }catch (Exception e){
                e.printStackTrace();
            }
        }catch (Exception e){
            e.printStackTrace();
        }
    }
}  

Java部分核心难度地方:ethCall和ethSendRawTransaction区别,ethcall调用的方法是不需要gas费用,而ethSendRawTransaction需要,因此此教程中,插入留言就需要使用ethSendRawTransaction方法来调用。

运行结果如下:

文章来源:智云一二三科技

文章标题:java使用web3j链接自己智能合约(教程)

文章地址:https://www.zhihuclub.com/186299.shtml

关于作者: 智云科技

热门文章

网站地图