0%

Java × 以太坊 4在Java中调用智能合约

教程参考了很多资料,其中帮助最大的是这个视频:

麦田里的灯:010-java调用智能合约

该视频在B站的播放量只有1700,说是少的可怜,但是的确对于这方面有需求的人是有帮助的。有些时候,好的东西反而不被珍惜。

他将视频里面的代码放到了CSDN上面,CSDN怎么说也的确有人在贡献内容,只能很多时候浏览器搜索的答案大多是抄袭的错误代码。

麦田里的灯:java调用solidity智能合约

之所以强调这两点是因为尊重原创,还要是不想引入过多的代码。

一些建议:

我自己是在本地安装sol编译环境失败了的,所以直接使用的在线编译器REMIX,他真的非常好用,还不需要登录账号。

我没有使用他里面的sol合约代码,我用的是WTF他们教程里面的初始代码,就三行的那个。

参考:https://www.wtf.academy/docs/solidity-101/HelloWeb3/

在Java中如果要调用合约,必须编译一个合约的执行类。调用类里面对应的合约方法,做到映射,这是Java的强项。但是困难的是,很多关于编译合约的方法都是让你先去安装sol的编译器,他们的教程太过古老而生硬。

避坑操作:

导入依赖:

接下来是模仿什么的过程,我们利用Java带调用合约。

Java的好处在于,你可以很容易看懂他人的代码,如果他们遵守规定。

首先要引入几个依赖文件,视频里面使用的是5.0版本,我使用的是4.8.7,看个人习惯:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<!--        导入web3j需要的code生成包-->
<dependency>
<groupId>org.web3j</groupId>
<artifactId>codegen</artifactId>
<version>4.8.7</version>
</dependency>
<!-- web3J依赖 -->
<dependency>
<groupId>org.web3j</groupId>
<artifactId>core</artifactId>
<version>4.8.7</version>
</dependency>
<!-- 胡图工具包-->
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.8.6</version>
</dependency>

他视频中因为引发了模块缺少,还导入了okthttp包,如有需要,自行导入。

生成合约类:

视频下面有一个问题,我也遇到了:

remix生成的Bytecode文件并不是视频里面演示的JSON文件,但是他代码里面读取的是JSON文件。

这个问题很好解决,我们看下他的先关代码,如下所示:

1
2
3
4
5
6
public static String getBytecodeJson(){
String bytecodePath = basePath + "utils/bytecode.json";
FileReader bytecodePathReader = new FileReader(bytecodePath);
String bytecodeResult = bytecodePathReader.readString();
return bytecodeResult;
}

直接将bytecode.json改成bytecode.txt就好了,将我们获取到的输入存入txt文本中。因为他最后读取文件,获取的还是String文本嘛,所以这样做的完全可行的。

执行合约:

我没有使用Ganache,我使用Sepolia测试网,先用Remix调用小狐狸,部署了一个合约。

然后获取到abi和bytecode生成合约类。

最后执行合约类。

既然改了网络就必须更改prcURL和chainID,如果你连接失败请更换一个PRC。

最后无误的话会调用成功,我这个合约是只读的合约,所以就只有一个变量。

部署合约:

你也可以使用Java代码来部署该合约,因为对应的合约工具类已经生成好了。

你可以在其中找到deploy方法,下面的代码仅供参考:

1
2
3
4
5
6
7
Web3j web3 = Web3j.build(new HttpService(url));
Credentials credentials = Credentials.create(Key);
TransactionManager transactionManager = new RawTransactionManager(
web3, credentials,11155111);
SolidityERC721 send = SolidityERC721.deploy(web3, transactionManager, new DefaultGasProvider()).send();
String contractAddress = send.getContractAddress();
ystem.out.println("合约地址为:"+contractAddress);

自此,用Java部署、调用合约的第一步成功。