How to integrate Web3j to java project

1. Environment prepare

1.1. Install solc

npm install -g solc

Check if success use this command:

solcjs --version

success like this:

在这里插入图片描述

1.2. Install web3j-cli

Download web3j-cli 1.4.1 from https://github.com/web3j/web3j-cli/releases
for example I used v1.4.1 :

在这里插入图片描述
extract zip files to local file system:

在这里插入图片描述
set web3j-cli’s /bin folder to system environment path:

在这里插入图片描述
install finish, check version:

在这里插入图片描述

1.3. Contract

Here I use the contract “StandardToken.sol” for testing. It can be download at github ( E.G. https://github.com/tintinweb/smart-contract-sanctuary)

在这里插入图片描述

2. Compile

Use command solcjs to compile *.sol file to get .abi and .bin files like below:

solcjs StandardToken.sol --bin --abi --optimize -o .\

I got files like this:

在这里插入图片描述

3. Generate contract JAVA Wrapper

Command usage:

web3j solidity generate -a \<abiFile\> -b \<binFile\> -o \<destinationFileDir\> -p \<packageName\>

E.G.

在这里插入图片描述
在这里插入图片描述

4. Integration

4.1. Maven dependencies:

Add dependencies to pom.xml like :

    <dependencies>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.13.2</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.web3j</groupId>
            <artifactId>core</artifactId>
            <version>5.0.0</version>
        </dependency>
    </dependencies>

4.2. Create java classes:

Copy contract wrapper file to java project and rename it to “StandardTokenContract.java” like below:

在这里插入图片描述

Here’s a helper class written by java named “ContractLoader” :


import okhttp3.OkHttpClient;
import org.web3j.crypto.Credentials;
import org.web3j.protocol.Web3j;
import org.web3j.protocol.core.methods.response.EthGasPrice;
import org.web3j.protocol.http.HttpService;
import org.web3j.tx.Contract;
import org.web3j.tx.gas.ContractGasProvider;
import org.web3j.tx.gas.StaticGasProvider;
import org.web3j.utils.Convert;

import java.lang.reflect.Method;
import java.math.BigInteger;
import java.net.InetSocketAddress;
import java.net.Proxy;

public final class ContractLoader {
    private static String proxyHost;
    private static int proxyPort;
    private static String rpcUrl;

    private ContractLoader() {

    }

    public static void env(String proxyHost,
                           int proxyPort,
                           String rpcUrl) {
        ContractLoader.proxyHost = proxyHost;
        ContractLoader.proxyPort = proxyPort;
        ContractLoader.rpcUrl = rpcUrl;
    }

    /**
     * Load contract only read block data with default gas-limit 3000000.
     *
     * @param contractAddress contract which want to operate
     * @param contractClazz   java class of contract build by web3j-cli-shadow-{version}. E.G.web3j generate solidity -a=.\StandardToken_sol_StandardToken.abi -b=.\StandardToken_sol_StandardToken.bin -o=.\ -p=cn.netoday.web3j-test
     * @param <T>             return type witch contract java class build by web3j-cli-shadow extends org.web3j.tx.Contract
     * @return implements of org.web3j.tx.Contract
     * @throws Exception Exception
     */
    public static <T extends Contract> T getContract(String contractAddress,
                                                     Class<T> contractClazz) throws Exception {
        return getContract("0000000000000000000000000000000000000000000000000000000000000000",
                Convert.toWei("3000000", Convert.Unit.WEI).toBigInteger(),
                contractAddress,
                contractClazz);
    }

    /**
     * Load contract with read and write block data with default gas-limit 3000000.
     *
     * @param senderPrivateKey msg.sender‘s private key. It can operate msg.sender's private assets if provided.
     * @param contractAddress  contract which want to operate
     * @param contractClazz    java class of contract build by web3j-cli-shadow-{version}. E.G.web3j generate solidity -a=.\StandardToken_sol_StandardToken.abi -b=.\StandardToken_sol_StandardToken.bin -o=.\ -p=cn.netoday.web3j-test
     * @param <T>              return type witch contract java class build by web3j-cli-shadow extends org.web3j.tx.Contract
     * @return implements of org.web3j.tx.Contract
     * @throws Exception Exception
     */
    public static <T extends Contract> T getContract(String senderPrivateKey,
                                                     String contractAddress,
                                                     Class<T> contractClazz) throws Exception {
        return getContract(senderPrivateKey,
                Convert.toWei("3000000", Convert.Unit.WEI).toBigInteger(),
                contractAddress,
                contractClazz);
    }

    /**
     * Load contract with read and write block data with customize gas-limit.
     *
     * @param senderPrivateKey msg.sender‘s private key. It can operate msg.sender's private assets if provided.
     * @param gasLimit         call contract with customize gas-limit
     * @param contractAddress  contract which want to operate
     * @param contractClazz    java class of contract build by web3j-cli-shadow-{version}. E.G.web3j generate solidity -a=.\StandardToken_sol_StandardToken.abi -b=.\StandardToken_sol_StandardToken.bin -o=.\ -p=cn.netoday.web3j-test
     * @param <T>              return type witch contract java class build by web3j-cli-shadow extends org.web3j.tx.Contract
     * @return implements of org.web3j.tx.Contract
     * @throws Exception Exception
     */
    public static <T extends Contract> T getContract(String senderPrivateKey,
                                                     BigInteger gasLimit,
                                                     String contractAddress,
                                                     Class<T> contractClazz) throws Exception {
        if (null == ContractLoader.rpcUrl || "".equals(ContractLoader.rpcUrl)) {
            throw new Exception("Rpc url can not be empty!");
        }

        //set proxy
        OkHttpClient.Builder builder = new OkHttpClient.Builder();
        if (null != ContractLoader.proxyHost && !"".equals(ContractLoader.proxyHost) && ContractLoader.proxyPort > 0) {
            builder.proxy(new Proxy(Proxy.Type.SOCKS, new InetSocketAddress(ContractLoader.proxyHost, ContractLoader.proxyPort)));
        }
        OkHttpClient client = builder.build();

        //initial operation for web3j
        Web3j web3 = Web3j.build(new HttpService(ContractLoader.rpcUrl, client));
        Credentials credentials = Credentials.create(senderPrivateKey);
        EthGasPrice gasPrice = web3.ethGasPrice().sendAsync().get();

        //reflection of contract
        T result = null;
        if (gasPrice != null) {
            Method method = contractClazz.getMethod("load", String.class, Web3j.class, Credentials.class, ContractGasProvider.class);
            result = (T) method.invoke(contractClazz,
                    contractAddress,
                    web3,
                    credentials,
                    new StaticGasProvider(gasPrice.getGasPrice(), gasLimit)
            );
        }
        return result;
    }
}

And here’s a java unit test which used the BSC-TEST rpc point via socks5 proxy:


import com.yayd.contracthelper.ContractLoader;
import com.yayd.contracthelper.StandardTokenContract;
import org.junit.Test;
import org.web3j.utils.Convert;

/**
 * Unit test for simple App.
 */
public class AppTest {
    private static final String PRIVATE_KEY = "here is your wallet private key to authority";
    private static final String RPC_URL = "https://data-seed-prebsc-1-s3.binance.org:8545/";
    private static final String CONTRACT_ADDRESS = "here is your contract address on blockchain";
    public static final String PROXY_HOSTNAME = "127.0.0.1";
    public static final int PROXY_PORT = 10808;

    /**
     * Test call blockchain
     */
    @Test
    public void testTransfer() {
        try {
            ContractLoader.env(
                    PROXY_HOSTNAME,
                    PROXY_PORT,
                    RPC_URL
            );
            //Load contract only read block data with default gas-limit 3000000.
            StandardTokenContract contract = ContractLoader.getContract(
                    CONTRACT_ADDRESS,
                    StandardTokenContract.class);
            System.out.println(contract.owner().send());

            //Load contract with read and write block data with default gas-limit 3000000.
            contract = ContractLoader.getContract(
                    PRIVATE_KEY,
                    CONTRACT_ADDRESS,
                    StandardTokenContract.class);
            System.out.println(contract.owner().send());

            //Load contract with read and write block data with customize gas-limit.
            contract = ContractLoader.getContract(
                    PRIVATE_KEY,
                    Convert.toWei("3000000", Convert.Unit.WEI).toBigInteger(),
                    CONTRACT_ADDRESS,
                    StandardTokenContract.class);
            System.out.println(contract.owner().send());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

5. References

<Installing the Solidity Compiler> : https://docs.soliditylang.org/en/v0.8.14/installing-solidity.html

<Command line tools> : https://docs.web3j.io/4.8.7/command_line_tools/

<Construction and Deployment> : https://docs.web3j.io/4.8.7/smart_contracts/construction_and_deployment/#solidity-smart-contract-wrappers

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值