快捷搜索:  汽车  科技

javaweb控制类的存活周期,java使用web3j链接自己智能合约

javaweb控制类的存活周期,java使用web3j链接自己智能合约运行结果如下:import Java.math.BigInteger; import java.util.Arrays; import java.util.List; import org.web3j.abi.FunctionEncoder; import org.web3j.abi.FunctionReturndecoder; 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

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

地址:https://infura.io/

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

javaweb控制类的存活周期,java使用web3j链接自己智能合约(1)

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

javaweb控制类的存活周期,java使用web3j链接自己智能合约(2)

第二步:使用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有测试币

javaweb控制类的存活周期,java使用web3j链接自己智能合约(3)

第三步 java部分

import Java.math.BigInteger; import java.util.Arrays; import java.util.List; import org.web3j.abi.FunctionEncoder; import org.web3j.abi.FunctionReturndecoder; 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.RawTransaction; 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 = "https://ropsten.infura.io/v3/8ac1e3ea********7a4a077c0a0745"; String contractAddress="0x954e9A986467861********F5aEa8b83cAB63B6"; //合约地址 String fromAddr="0xb4377fb04FE5aDe3C35*******0cd354308807bF"; //查询用户地址 String inputPrivateKey="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.getTransactionHash()); }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方法来调用。

运行结果如下:

javaweb控制类的存活周期,java使用web3j链接自己智能合约(4)

猜您喜欢: