赞
踩
最近公司做NFT市场开发,特记录一下自己在使用web3j组件测试调用区块链合约的时使用的方法和踩过的坑,便于自己以后查看。
主要用到工具有4个
idea,谷歌浏览,小狐狸钱包(metamask)插件,remix在线智能合约平台
在pom.xml中添加引用仓库地址,添加web3j的引入
- <repositories>
- <repository>
- <id>jitpack.io</id>
- <url>https://jitpack.io</url>
- </repository>
- </repositories>
-
- <dependencies>
-
- <!--web3j-->
- <dependency>
- <groupId>org.web3j</groupId>
- <artifactId>core</artifactId>
- <version>4.8.4</version>
- <exclusions>
- <exclusion>
- <groupId>org.jetbrains.kotlin</groupId>
- <artifactId>kotlin-stdlib</artifactId>
- </exclusion>
- <exclusion>
- <groupId>com.squareup.okhttp3</groupId>
- <artifactId>okhttp</artifactId>
- </exclusion>
- </exclusions>
- </dependency>
- </dependencies>

开始前,必须有一个用于测试的区块链智能合约,进入以太坊官网提供的在线平台,地址为:https://remix.ethereum.org/,编写测试合约。
编写完成,编译测试无误后,部署合约,方法选择如下
因为选择通过web3的方式来发布合约,所以同步会要求登录小狐狸(MetaMask),我这里事先就已经添加好了币安测试链,如果各位没有添加的话,自己自行添加哈
合约发布成功后,测试一下合约内的方法是否可以正常使用,一切OK了以后,在remix中的编译模块内,将abi和bin保存放入本地文件中用于生成java文件。
说明一下哦,在生成java文件时,本地要有web3j的资源文件,我事先已经做好了准备工作了,如果你们没有的话,就自己查下哈。
进入cmd命令窗口
命令如下
web3j solidity generate --abiFile=abi文件地址 -o 文件生成地址 -p 文件包名
以下是我的合约生成的java文件
- package com.XX.XXX.contracts.constants;
-
- import io.reactivex.Flowable;
- import io.reactivex.functions.Function;
- import java.math.BigInteger;
- import java.util.ArrayList;
- import java.util.Arrays;
- import java.util.Collections;
- import java.util.List;
- import org.web3j.abi.EventEncoder;
- import org.web3j.abi.TypeReference;
- import org.web3j.abi.datatypes.Address;
- import org.web3j.abi.datatypes.Event;
- import org.web3j.abi.datatypes.Type;
- import org.web3j.abi.datatypes.Utf8String;
- import org.web3j.abi.datatypes.generated.Uint256;
- import org.web3j.crypto.Credentials;
- import org.web3j.protocol.Web3j;
- import org.web3j.protocol.core.DefaultBlockParameter;
- import org.web3j.protocol.core.RemoteFunctionCall;
- import org.web3j.protocol.core.methods.request.EthFilter;
- import org.web3j.protocol.core.methods.response.BaseEventResponse;
- import org.web3j.protocol.core.methods.response.Log;
- 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.5.
- */
- @SuppressWarnings("rawtypes")
- public class EventTest extends Contract {
- private static final String BINARY = "Bin file was not provided";
-
- public static final String FUNC_CHANGENAME = "changeName";
-
- public static final String FUNC_COUNTS = "counts";
-
- public static final String FUNC_INCREMENT = "increment";
-
- public static final String FUNC_NAME = "name";
-
- public static final Event INCREMENT_EVENT = new Event("Increment",
- Arrays.<TypeReference<?>>asList(new TypeReference<Uint256>(true) {}, new TypeReference<Address>() {}));
- ;
-
- public static final Event CHANGENAMEEVENT_EVENT = new Event("changeNameEvent",
- Arrays.<TypeReference<?>>asList(new TypeReference<Utf8String>() {}, new TypeReference<Address>() {}));
- ;
-
- @Deprecated
- protected EventTest(String contractAddress, Web3j web3j, Credentials credentials, BigInteger gasPrice, BigInteger gasLimit) {
- super(BINARY, contractAddress, web3j, credentials, gasPrice, gasLimit);
- }
-
- protected EventTest(String contractAddress, Web3j web3j, Credentials credentials, ContractGasProvider contractGasProvider) {
- super(BINARY, contractAddress, web3j, credentials, contractGasProvider);
- }
-
- @Deprecated
- protected EventTest(String contractAddress, Web3j web3j, TransactionManager transactionManager, BigInteger gasPrice, BigInteger gasLimit) {
- super(BINARY, contractAddress, web3j, transactionManager, gasPrice, gasLimit);
- }
-
- protected EventTest(String contractAddress, Web3j web3j, TransactionManager transactionManager, ContractGasProvider contractGasProvider) {
- super(BINARY, contractAddress, web3j, transactionManager, contractGasProvider);
- }
-
- public List<IncrementEventResponse> getIncrementEvents(TransactionReceipt transactionReceipt) {
- List<Contract.EventValuesWithLog> valueList = extractEventParametersWithLog(INCREMENT_EVENT, transactionReceipt);
- ArrayList<IncrementEventResponse> responses = new ArrayList<IncrementEventResponse>(valueList.size());
- for (Contract.EventValuesWithLog eventValues : valueList) {
- IncrementEventResponse typedResponse = new IncrementEventResponse();
- typedResponse.log = eventValues.getLog();
- typedResponse.which = (BigInteger) eventValues.getIndexedValues().get(0).getValue();
- typedResponse.who = (String) eventValues.getNonIndexedValues().get(0).getValue();
- responses.add(typedResponse);
- }
- return responses;
- }
-
- public Flowable<IncrementEventResponse> incrementEventFlowable(EthFilter filter) {
- return web3j.ethLogFlowable(filter).map(new Function<Log, IncrementEventResponse>() {
- @Override
- public IncrementEventResponse apply(Log log) {
- Contract.EventValuesWithLog eventValues = extractEventParametersWithLog(INCREMENT_EVENT, log);
- IncrementEventResponse typedResponse = new IncrementEventResponse();
- typedResponse.log = log;
- typedResponse.which = (BigInteger) eventValues.getIndexedValues().get(0).getValue();
- typedResponse.who = (String) eventValues.getNonIndexedValues().get(0).getValue();
- return typedResponse;
- }
- });
- }
-
- public Flowable<IncrementEventResponse> incrementEventFlowable(DefaultBlockParameter startBlock, DefaultBlockParameter endBlock) {
- EthFilter filter = new EthFilter(startBlock, endBlock, getContractAddress());
- filter.addSingleTopic(EventEncoder.encode(INCREMENT_EVENT));
- return incrementEventFlowable(filter);
- }
-
- public List<ChangeNameEventEventResponse> getChangeNameEventEvents(TransactionReceipt transactionReceipt) {
- List<Contract.EventValuesWithLog> valueList = extractEventParametersWithLog(CHANGENAMEEVENT_EVENT, transactionReceipt);
- ArrayList<ChangeNameEventEventResponse> responses = new ArrayList<ChangeNameEventEventResponse>(valueList.size());
- for (Contract.EventValuesWithLog eventValues : valueList) {
- ChangeNameEventEventResponse typedResponse = new ChangeNameEventEventResponse();
- typedResponse.log = eventValues.getLog();
- typedResponse.str = (String) eventValues.getNonIndexedValues().get(0).getValue();
- typedResponse.who = (String) eventValues.getNonIndexedValues().get(1).getValue();
- responses.add(typedResponse);
- }
- return responses;
- }
-
- public Flowable<ChangeNameEventEventResponse> changeNameEventEventFlowable(EthFilter filter) {
- return web3j.ethLogFlowable(filter).map(new Function<Log, ChangeNameEventEventResponse>() {
- @Override
- public ChangeNameEventEventResponse apply(Log log) {
- Contract.EventValuesWithLog eventValues = extractEventParametersWithLog(CHANGENAMEEVENT_EVENT, log);
- ChangeNameEventEventResponse typedResponse = new ChangeNameEventEventResponse();
- typedResponse.log = log;
- typedResponse.str = (String) eventValues.getNonIndexedValues().get(0).getValue();
- typedResponse.who = (String) eventValues.getNonIndexedValues().get(1).getValue();
- return typedResponse;
- }
- });
- }
-
- public Flowable<ChangeNameEventEventResponse> changeNameEventEventFlowable(DefaultBlockParameter startBlock, DefaultBlockParameter endBlock) {
- EthFilter filter = new EthFilter(startBlock, endBlock, getContractAddress());
- filter.addSingleTopic(EventEncoder.encode(CHANGENAMEEVENT_EVENT));
- return changeNameEventEventFlowable(filter);
- }
-
- public RemoteFunctionCall<TransactionReceipt> changeName(String str) {
- final org.web3j.abi.datatypes.Function function = new org.web3j.abi.datatypes.Function(
- FUNC_CHANGENAME,
- Arrays.<Type>asList(new org.web3j.abi.datatypes.Utf8String(str)),
- Collections.<TypeReference<?>>emptyList());
- return executeRemoteCallTransaction(function);
- }
-
- public RemoteFunctionCall<TransactionReceipt> counts(BigInteger param0) {
- final org.web3j.abi.datatypes.Function function = new org.web3j.abi.datatypes.Function(
- FUNC_COUNTS,
- Arrays.<Type>asList(new org.web3j.abi.datatypes.generated.Uint256(param0)),
- Collections.<TypeReference<?>>emptyList());
- return executeRemoteCallTransaction(function);
- }
-
- public RemoteFunctionCall<TransactionReceipt> increment(BigInteger which) {
- final org.web3j.abi.datatypes.Function function = new org.web3j.abi.datatypes.Function(
- FUNC_INCREMENT,
- Arrays.<Type>asList(new org.web3j.abi.datatypes.generated.Uint256(which)),
- Collections.<TypeReference<?>>emptyList());
- return executeRemoteCallTransaction(function);
- }
-
- public RemoteFunctionCall<TransactionReceipt> name() {
- final org.web3j.abi.datatypes.Function function = new org.web3j.abi.datatypes.Function(
- FUNC_NAME,
- Arrays.<Type>asList(),
- Collections.<TypeReference<?>>emptyList());
- return executeRemoteCallTransaction(function);
- }
-
- @Deprecated
- public static EventTest load(String contractAddress, Web3j web3j, Credentials credentials, BigInteger gasPrice, BigInteger gasLimit) {
- return new EventTest(contractAddress, web3j, credentials, gasPrice, gasLimit);
- }
-
- @Deprecated
- public static EventTest load(String contractAddress, Web3j web3j, TransactionManager transactionManager, BigInteger gasPrice, BigInteger gasLimit) {
- return new EventTest(contractAddress, web3j, transactionManager, gasPrice, gasLimit);
- }
-
- public static EventTest load(String contractAddress, Web3j web3j, Credentials credentials, ContractGasProvider contractGasProvider) {
- return new EventTest(contractAddress, web3j, credentials, contractGasProvider);
- }
-
- public static EventTest load(String contractAddress, Web3j web3j, TransactionManager transactionManager, ContractGasProvider contractGasProvider) {
- return new EventTest(contractAddress, web3j, transactionManager, contractGasProvider);
- }
-
- public static class IncrementEventResponse extends BaseEventResponse {
- public BigInteger which;
-
- public String who;
- }
-
- public static class ChangeNameEventEventResponse extends BaseEventResponse {
- public String str;
-
- public String who;
- }
- }

说明:
web3j通过rpc的方式建立连接,连接方式我测试时,用了两种方式,一种是http的方式调用合约的方法,websocket的方式调用的事件监听,两种方式测试都是OK的
- package com.xx.xxx.contracts.util;
-
- import com.nft.service.contracts.constants.ContractConstants;
- import com.nft.service.contracts.constants.EventTest;
- import org.slf4j.Logger;
- import org.slf4j.LoggerFactory;
- import org.web3j.abi.EventValues;
- import org.web3j.abi.datatypes.Type;
- import org.web3j.crypto.Credentials;
- import org.web3j.protocol.Web3j;
- import org.web3j.protocol.core.DefaultBlockParameterName;
- import org.web3j.protocol.core.RemoteFunctionCall;
- import org.web3j.protocol.core.methods.request.Transaction;
- import org.web3j.protocol.core.methods.response.EthEstimateGas;
- import org.web3j.protocol.core.methods.response.EthGetTransactionCount;
- import org.web3j.protocol.core.methods.response.Log;
- import org.web3j.protocol.core.methods.response.TransactionReceipt;
- import org.web3j.protocol.http.HttpService;
- import org.web3j.protocol.websocket.WebSocketService;
- import org.web3j.tx.Contract;
- import org.web3j.tx.ReadonlyTransactionManager;
- import org.web3j.tx.TransactionManager;
- import org.web3j.tx.gas.DefaultGasProvider;
-
- import java.io.IOException;
- import java.math.BigInteger;
- import java.net.ConnectException;
- import java.util.concurrent.ExecutionException;
-
- /**
- * @author viowio
- * @version v1.0
- * @date 17:52 2022/4/9
- * @description ERC20工具类
- */
- public class TestUtil {
-
-
- private static Web3j web3j = Web3j.build(new HttpService("https://data-seed-prebsc-2-s1.binance.org:8545/"));
- private static final Logger logger = LoggerFactory.getLogger(TestUtil.class);
-
- public static void changeName(){
- String token = "合约地址";
- try {
- Credentials credentials = Credentials.create("换成自己的测试钱包地址私钥");
- BigInteger currentGasPrice = web3j.ethGasPrice().sendAsync().get().getGasPrice();
- EventTest eventTest = EventTest.load(token, web3j, credentials, new DefaultGasProvider() {
- /**
- * 使用动态获取的 Gas Price
- * @return
- */
- @Override
- public BigInteger getGasPrice() {
- return currentGasPrice;
- }
- });
-
- RemoteFunctionCall<TransactionReceipt> changeNames = eventTest.changeName("0x7503D2667a3Af2a5f5268B9628F7Bb0A3E6282B4");
- TransactionReceipt transactionReceipt = changeNames.sendAsync().get();
- String transactionHash = transactionReceipt.getTransactionHash();
- logger.info("changeName hash: {}",transactionHash);
- }catch (ExecutionException | InterruptedException ex){
- logger.info(ex.getMessage());
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
- public static void changeNameEvent() throws ConnectException {
- String token = "合约地址";
- String wsurl = ContractConstants.WEBSOCKET_RPC;
- //实例化websocket
- WebSocketService webSocketService = new WebSocketService(wsurl,true);
- //建立连接
- webSocketService.connect();
- //实例化web3j
- Web3j client = Web3j.build(webSocketService);
- TransactionManager transactionManager = new ReadonlyTransactionManager(web3j, token);
- try {
- //方式一
- /* client.ethLogFlowable(
- new EthFilter(
- DefaultBlockParameterName.EARLIEST,
- DefaultBlockParameterName.LATEST,
- // 合约地址
- token
- )
- ).subscribe(event -> {
- System.out.println(event);
- // => Log{removed=false, logIndex='0x39', transactionIndex='0x13', transactionHash='0x9c3653c27946cb39c3a256229634cfedbca54f146a740f46b661b986590f8358', blockHash='0x1e674b9d111601519f977b75f9a1865ba359b474550ff5d0d87daec1f543d64d', blockNumber='0xb83ccd', address='0x7b52aae43e962ce6a9a1b7e79f549582ae8bcff9', data='0x', type='null', topics=[0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef, 0x0000000000000000000000000000000000000000000000000000000000000000, 0x0000000000000000000000006ab3d0bd875f8667026d2a9bb3060ec44380bcc2, 0x0000000000000000000000000000000000000000000000000000000000000017]}
- }, Throwable::printStackTrace);*/
-
- //方式二
- /*Credentials credentials = Credentials.create("换成自己的测试钱包地址私钥");
- BigInteger currentGasPrice = web3j.ethGasPrice().sendAsync().get().getGasPrice();
- EventTest eventTest = EventTest.load(token, web3j, credentials, new DefaultGasProvider() {
- *//**
- * 使用动态获取的 Gas Price
- * @return
- *//*
- @Override
- public BigInteger getGasPrice() {
- return currentGasPrice;
- }
- });
- eventTest
- .changeNameEventEventFlowable(DefaultBlockParameterName.EARLIEST, DefaultBlockParameterName.LATEST)
- .subscribe(event -> {
- Log log = event.log;
- EventValues eventValues = Contract.staticExtractEventParameters(EventTest.CHANGENAMEEVENT_EVENT, log);
- for (Type nonIndexedValue : eventValues.getNonIndexedValues()) {
- System.out.println(nonIndexedValue.getValue());
- }
- });*/
- //方式3
- Credentials credentials = Credentials.create("换成自己的测试钱包地址私钥");
- BigInteger currentGasPrice = client.ethGasPrice().sendAsync().get().getGasPrice();
- EventTest eventTest = EventTest.load(token, client, credentials, new DefaultGasProvider() {
- /**
- * 使用动态获取的 Gas Price
- * @return
- */
- @Override
- public BigInteger getGasPrice() {
- return currentGasPrice;
- }
- });
- eventTest
- .changeNameEventEventFlowable(DefaultBlockParameterName.EARLIEST, DefaultBlockParameterName.LATEST)
- .subscribe(event -> {
- Log log = event.log;
- logger.info("transactionHash: {}",log.getTransactionHash());
- //解析时间返回的参数
- EventValues eventValues = Contract.staticExtractEventParameters(EventTest.CHANGENAMEEVENT_EVENT, log);
- for (Type nonIndexedValue : eventValues.getNonIndexedValues()) {
- System.out.println(nonIndexedValue.getValue());
- }
- });
- }catch (Exception e) {
- e.printStackTrace();
- }
- }
- }

事件测试结果
- 16:32:05.978 [restartedMain] INFO c.n.s.c.u.TestUtil - [lambda$changeNameEvent$0,146] - transactionHash: 0xd4fac21ba08d7496d8025281c37e932b914ea3bb9dce48e73bd3c08ac934fdd3
- test
- 0x5ae241178c67689ead468bf5170b3105011a5766
- 16:32:05.979 [restartedMain] INFO c.n.s.c.u.TestUtil - [lambda$changeNameEvent$0,146] - transactionHash: 0x42aff4ead062feb340a2fa68c73b5024a0d58029287a2f0acc62156c60780d97
- test
- 0x5ae241178c67689ead468bf5170b3105011a5766
- 16:32:05.980 [restartedMain] INFO c.n.s.c.u.TestUtil - [lambda$changeNameEvent$0,146] - transactionHash: 0x1050583b9e907378fb61289ab5b373f195f4d332c5fd7d273e2c817554c90f7b
- 123
- 0x5ae241178c67689ead468bf5170b3105011a5766
- 16:32:05.980 [restartedMain] INFO c.n.s.c.u.TestUtil - [lambda$changeNameEvent$0,146] - transactionHash: 0xc86374d895f83bfef380a9a1f4cc5a15ddfcc78090305cff5e4367460d423af4
- 1237
- 0x5ae241178c67689ead468bf5170b3105011a5766
- 16:32:05.981 [restartedMain] INFO c.n.s.c.u.TestUtil - [lambda$changeNameEvent$0,146] - transactionHash: 0xf76fbd23e603109752215c5455e3920a08583de8728c2a42699f61aa45959d29
- 12374
- 0x5ae241178c67689ead468bf5170b3105011a5766
- 16:32:05.981 [restartedMain] INFO c.n.s.c.u.TestUtil - [lambda$changeNameEvent$0,146] - transactionHash: 0x0d751916f7ae66162959138c0a700feb136153fabee8d8b25a10e410fe74f904
- 1237455
- 0x5ae241178c67689ead468bf5170b3105011a5766
- 16:32:05.981 [restartedMain] INFO c.n.s.c.u.TestUtil - [lambda$changeNameEvent$0,146] - transactionHash: 0xe03249489b93e287e9d033f547c2a36a741c7b3ae49e5c95542315816f4af572
- 12374556
- 0x5ae241178c67689ead468bf5170b3105011a5766

OK,暂时完事了。
最后补充一下
如果没有的rpc地址的,可以搜一下,也可以使用我上面的那个地址,不过仅限于测试用哦。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。