ETH私有链搭建与使用-java调用智能合约方法(4)


1.准备智能合约java类

1.1下载与pom.xml中web3j相同版本的命令行操作工具

下载链接: https://mituxiaogaoyang.club/eth-source/web3j-4.5.0.zip

1.2解压zip文件进入bin目录

将SimpleStorage_sol_SimpleStorage.abi和SimpleStorage_sol_SimpleStorage.bin文件从服务器下载到本地这个目录中,这两个文件是上一篇文章中solc编译出来的文件.

1.3通过web3j命令行工具将合约转换为java类

web3j solidity generate -a SimpleStorage_sol_SimpleStorage.abi -b SimpleStorage_sol_SimpleStorage.bin -o ./output -p com.fc.v2.web3j

 

 转换成功如上图所示,对应文件夹下会生成相应的java类.

 

2.编写调用合约方法

 2.1引入pom依赖

<!-- web3j依赖 -->
        <dependency>
            <groupId>org.web3j</groupId>
            <artifactId>core</artifactId>
            <version>4.5.0</version>
        </dependency>

2.2复制SimpleStorage_sol_SimpleStorage.java类到项目中

2.3在SimpleStorage_sol_SimpleStorage.java中新增一个合约方法来获取返回值

// 新增获取返回值方法
    public RemoteFunctionCall<BigInteger> getForReturn() {
        final Function function = new Function(
                FUNC_GET, 
                Collections.emptyList(),
                Arrays.asList(new TypeReference<Uint256>(){}));
        return executeRemoteCallSingleValueReturn(function, BigInteger.class);
    }

完整SimpleStorage_sol_SimpleStorage.java代码如下:

package com.fc.v2.web3j;

import java.math.BigInteger;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;

import org.web3j.abi.TypeReference;
import org.web3j.abi.datatypes.Function;
import org.web3j.abi.datatypes.Type;
import org.web3j.abi.datatypes.generated.Uint256;
import org.web3j.crypto.Credentials;
import org.web3j.protocol.Web3j;
import org.web3j.protocol.core.RemoteCall;
import org.web3j.protocol.core.RemoteFunctionCall;
import org.web3j.protocol.core.methods.response.TransactionReceipt;
import org.web3j.tx.Contract;
import org.web3j.tx.TransactionManager;
import org.web3j.tx.gas.ContractGasProvider;

/**
 * <p>Auto generated code.
 * <p><strong>Do not modify!</strong>
 * <p>Please use the <a href="https://docs.web3j.io/command_line.html">web3j command line tools</a>,
 * or the org.web3j.codegen.SolidityFunctionWrapperGenerator in the 
 * <a href="https://github.com/web3j/web3j/tree/master/codegen">codegen module</a> to update.
 *
 * <p>Generated with web3j version 4.5.0.
 */
public class SimpleStorage_sol_SimpleStorage extends Contract {
    private static final String BINARY = "608060405234801561001057600080fd5b50610150806100206000396000f3fe608060405234801561001057600080fd5b50600436106100365760003560e01c806360fe47b11461003b5780636d4ce63c14610057575b600080fd5b610055600480360381019061005091906100c3565b610075565b005b61005f61007f565b60405161006c91906100ff565b60405180910390f35b8060008190555050565b60008054905090565b600080fd5b6000819050919050565b6100a08161008d565b81146100ab57600080fd5b50565b6000813590506100bd81610097565b92915050565b6000602082840312156100d9576100d8610088565b5b60006100e7848285016100ae565b91505092915050565b6100f98161008d565b82525050565b600060208201905061011460008301846100f0565b9291505056fea26469706673582212203566a002af029ac481d6936a3e6ebbbfb633f7e8e862712e84d7fe96fd38e09464736f6c63430008090033";

    public static final String FUNC_GET = "get";

    public static final String FUNC_SET = "set";

    @Deprecated
    protected SimpleStorage_sol_SimpleStorage(String contractAddress, Web3j web3j, Credentials credentials, BigInteger gasPrice, BigInteger gasLimit) {
        super(BINARY, contractAddress, web3j, credentials, gasPrice, gasLimit);
    }

    protected SimpleStorage_sol_SimpleStorage(String contractAddress, Web3j web3j, Credentials credentials, ContractGasProvider contractGasProvider) {
        super(BINARY, contractAddress, web3j, credentials, contractGasProvider);
    }

    @Deprecated
    protected SimpleStorage_sol_SimpleStorage(String contractAddress, Web3j web3j, TransactionManager transactionManager, BigInteger gasPrice, BigInteger gasLimit) {
        super(BINARY, contractAddress, web3j, transactionManager, gasPrice, gasLimit);
    }

    protected SimpleStorage_sol_SimpleStorage(String contractAddress, Web3j web3j, TransactionManager transactionManager, ContractGasProvider contractGasProvider) {
        super(BINARY, contractAddress, web3j, transactionManager, contractGasProvider);
    }

    public RemoteFunctionCall<TransactionReceipt> get() {
        final Function function = new Function(
                FUNC_GET, 
                Arrays.<Type>asList(), 
                Collections.<TypeReference<?>>emptyList());
        return executeRemoteCallTransaction(function);
    }

    public RemoteFunctionCall<TransactionReceipt> set(BigInteger x) {
        final Function function = new Function(
                FUNC_SET, 
                Arrays.<Type>asList(new org.web3j.abi.datatypes.generated.Uint256(x)), 
                Collections.<TypeReference<?>>emptyList());
        return executeRemoteCallTransaction(function);
    }
    // 新增获取返回值方法
    public RemoteFunctionCall<BigInteger> getForReturn() {
        final Function function = new Function(
                FUNC_GET, 
                Collections.emptyList(),
                Arrays.asList(new TypeReference<Uint256>(){}));
        return executeRemoteCallSingleValueReturn(function, BigInteger.class);
    }

    @Deprecated
    public static SimpleStorage_sol_SimpleStorage load(String contractAddress, Web3j web3j, Credentials credentials, BigInteger gasPrice, BigInteger gasLimit) {
        return new SimpleStorage_sol_SimpleStorage(contractAddress, web3j, credentials, gasPrice, gasLimit);
    }

    @Deprecated
    public static SimpleStorage_sol_SimpleStorage load(String contractAddress, Web3j web3j, TransactionManager transactionManager, BigInteger gasPrice, BigInteger gasLimit) {
        return new SimpleStorage_sol_SimpleStorage(contractAddress, web3j, transactionManager, gasPrice, gasLimit);
    }

    public static SimpleStorage_sol_SimpleStorage load(String contractAddress, Web3j web3j, Credentials credentials, ContractGasProvider contractGasProvider) {
        return new SimpleStorage_sol_SimpleStorage(contractAddress, web3j, credentials, contractGasProvider);
    }

    public static SimpleStorage_sol_SimpleStorage load(String contractAddress, Web3j web3j, TransactionManager transactionManager, ContractGasProvider contractGasProvider) {
        return new SimpleStorage_sol_SimpleStorage(contractAddress, web3j, transactionManager, contractGasProvider);
    }

    public static RemoteCall<SimpleStorage_sol_SimpleStorage> deploy(Web3j web3j, Credentials credentials, ContractGasProvider contractGasProvider) {
        return deployRemoteCall(SimpleStorage_sol_SimpleStorage.class, web3j, credentials, contractGasProvider, BINARY, "");
    }

    @Deprecated
    public static RemoteCall<SimpleStorage_sol_SimpleStorage> deploy(Web3j web3j, Credentials credentials, BigInteger gasPrice, BigInteger gasLimit) {
        return deployRemoteCall(SimpleStorage_sol_SimpleStorage.class, web3j, credentials, gasPrice, gasLimit, BINARY, "");
    }

    public static RemoteCall<SimpleStorage_sol_SimpleStorage> deploy(Web3j web3j, TransactionManager transactionManager, ContractGasProvider contractGasProvider) {
        return deployRemoteCall(SimpleStorage_sol_SimpleStorage.class, web3j, transactionManager, contractGasProvider, BINARY, "");
    }

    @Deprecated
    public static RemoteCall<SimpleStorage_sol_SimpleStorage> deploy(Web3j web3j, TransactionManager transactionManager, BigInteger gasPrice, BigInteger gasLimit) {
        return deployRemoteCall(SimpleStorage_sol_SimpleStorage.class, web3j, transactionManager, gasPrice, gasLimit, BINARY, "");
    }
}

2.4编写Web3jDemo.java测试类,完整代码如下

package com.fc.v2.web3j;

import java.math.BigInteger;

import org.web3j.crypto.Credentials;
import org.web3j.crypto.RawTransaction;
import org.web3j.crypto.TransactionEncoder;
import org.web3j.crypto.WalletUtils;
import org.web3j.protocol.Web3j;
import org.web3j.protocol.admin.Admin;
import org.web3j.protocol.admin.methods.response.PersonalUnlockAccount;
import org.web3j.protocol.core.DefaultBlockParameterName;
import org.web3j.protocol.core.methods.response.EthGetBalance;
import org.web3j.protocol.core.methods.response.EthGetTransactionCount;
import org.web3j.protocol.core.methods.response.EthSendTransaction;
import org.web3j.protocol.core.methods.response.TransactionReceipt;
import org.web3j.protocol.http.HttpService;
import org.web3j.tx.RawTransactionManager;
import org.web3j.tx.TransactionManager;
import org.web3j.tx.gas.ContractGasProvider;
import org.web3j.tx.gas.StaticGasProvider;
import org.web3j.utils.Convert;
import org.web3j.utils.Numeric;

public class Web3jDemo {
    private static final String RPC_URL = "http://116.62.58.222:8545";//RPC访问地址,由节点设置,请替换成自己节点的rpc地址
    private static final Web3j web3j = Web3j.build(new HttpService(RPC_URL));//Web3j客户端
    private static final Admin adminWeb3j = Admin.build(new HttpService(RPC_URL));//Admin管理端
    private static final String address = "0xffd4a30c08d9f16f095f6315e14bd034f7d04fb0";//有余额的钱包地址
    private static final String password = "123456";//钱包地址解锁密码
    private static final String to = "0x1ef3c8b97c47ba09d01be4a0cf633d9f08ef4cd1";//转出的钱包地址
    private static final String filePath = "D:\\wallet";//有余额的钱包地址私钥文件路径
    private static final long chainId = 666l;//创世区块json文件中的chainId
    private static final BigInteger gasPrice = new BigInteger("5000");//燃料消耗
    private static final BigInteger gasLimit = new BigInteger("300000");//消耗限制
    private static final String contractAddress = "0xd74859b57c108dffae39bfe6c1bf9cea67b527ea";//合约地址,部署合约成功后会返回该地址
 
    //测试主函数
    public static void main(String[] args) throws Exception {
//        getAge(to);
//        sendTransaction();
        excuteContract();
    }
 
    // 查询钱包余额
    public static void getAge(String address) throws Exception {
        // 这里要填写真实的钱包地址
        EthGetBalance ethGetBalance = web3j
                .ethGetBalance(address, DefaultBlockParameterName.LATEST).send();
        if (ethGetBalance != null) {
            System.out.println("余额:" + Convert.fromWei(ethGetBalance.getBalance().toString(), Convert.Unit.ETHER));
        }
    }
    // 发送转账交易
    public static void sendTransaction() throws Exception {
        PersonalUnlockAccount personalUnlockAccount = adminWeb3j.personalUnlockAccount(address, password).send();
        if (personalUnlockAccount.accountUnlocked()) {
            BigInteger gasPrice = web3j.ethGasPrice().sendAsync().get().getGasPrice();
            System.out.println(gasPrice);
            // send a transaction
            EthGetTransactionCount ethGetTransactionCount = web3j.ethGetTransactionCount(address, DefaultBlockParameterName.LATEST).sendAsync().get();
            BigInteger nonce = ethGetTransactionCount.getTransactionCount();
            RawTransaction rawTransaction = RawTransaction.createEtherTransaction(nonce, new BigInteger("5000"), new BigInteger("300000"), to, new BigInteger("3"));
            // 对交易进行签名和编码:
            // String fileName = WalletUtils.generateNewWalletFile(password, new File(filePath));
            String fileName = "UTC--2021-10-12T07-07-33.666057600Z--ffd4a30c08d9f16f095f6315e14bd034f7d04fb0";
            Credentials credentials = WalletUtils.loadCredentials(password, filePath + "\\" + fileName);
            byte[] signedMessage = TransactionEncoder.signMessage(rawTransaction, chainId, credentials);
            String hexValue = Numeric.toHexString(signedMessage);
            EthSendTransaction ethSendTransaction = web3j.ethSendRawTransaction(hexValue).sendAsync().get();
            String transactionHash = ethSendTransaction.getTransactionHash();
            System.out.println("transactionHash:"+transactionHash);
        }
    }
    // 执行合约方法
    public static void excuteContract() throws Exception {
        // 私钥文件名
        String fileName = "UTC--2021-10-12T07-07-33.666057600Z--ffd4a30c08d9f16f095f6315e14bd034f7d04fb0";
        Credentials credentials = WalletUtils.loadCredentials(password, filePath + "\\" + fileName);
        ContractGasProvider contractGasProvider = new StaticGasProvider(gasPrice, gasLimit);
        TransactionManager transactionManager = new RawTransactionManager(web3j, credentials, chainId);
        SimpleStorage_sol_SimpleStorage contract = SimpleStorage_sol_SimpleStorage.load(contractAddress, web3j, transactionManager, contractGasProvider);
        
        System.out.println(contract.isValid());//验证合约是否有效,返回true代表有效
        
        TransactionReceipt result = contract.set(new BigInteger("88")).send();//调用合约方法(阻塞形式),节点需开启挖矿并等待挖矿后进入到下一步
        System.out.println(result.getTransactionHash());//打印交易hash
        
        BigInteger data = contract.getForReturn().send();//调用合约方法获取数据,节点无需开启挖矿
        System.out.println(data);//打印返回数据
    }
    
}

2.5从服务器拷贝私钥文件到本地对应路径

服务器私钥文件路径:

 

 本地路径:

 

 2.6运行代码查看测试打印结果

 

至此,数据"88"已经存储到了eth私有链上,并能够被合约正常取出.

如果你觉得文章对你有帮助,可以请作者喝杯咖啡.

 


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM