6分钟以太坊实战系列-Web3j对智能合约的调用

一、 什么是 web3j

web3j是一个高度模块化、响应式、类型安全的Java和Android库,用于与智能合约交互,并与Ethereum网络的客户端(节点)集成。

二、准备工作

1.新建java项目,引入 Maven 包

<dependency>
  <groupId>org.web3j</groupId>
  <artifactId>core</artifactId>
  <version>3.3.1</version>
</dependency>

2.打开客户端
注意:开私有链的时候需要加上 –rpc 参数。否则无法调用。并且需要打开你的矿工,来完成智能合约部署调用等工作。

geth --rpc --datadir "./chain" --nodiscover console 2>>ouput.log

miner.start()

3.生成智能合约的封装器
(1) 下载 web3j 的 Command Line Tool:

brew tap web3j/web3j
brew install web3j

(2) 生成封装器
用 solc 编译生成 .bin .abi 文件
命令:

> solcjs <Solidity文件地址>.sol --bin --abi --optimize -o <输出文件夹路径>/

实例:这里以 SimpleStorage.sol 文件为例

> solcjs SimpleStorage.sol --abi --bin -o ./

用 web3j 生成 java 封装器
命令:

web3j solidity generate --solidityTypes <智能合约编译之后的.bin文件的地址>.bin <智能合约编译之后的.abi文件的地址>.abi -o /path/to/src/main/java -p com.your.organisation.name

-o 后接生成好的java文件放置的位置,-p 后接生成的java文件的包名

注意:.bin .abi文件顺序不能反,否则会报错

实例:使用我们之前生成的文件,将 java 文件生成到我们的项目中:

web3j solidity generate --solidityTypes Compute_sol_Compute.bin Compute_sol_Compute.abi -o ./project/src/main/java -p com.demo

输出如下信息后,可以在我们指定的路径看见生成好的 java 文件Compute_sol_Compute.java

《6分钟以太坊实战系列-Web3j对智能合约的调用》 image.png

三、web3j 基础命令

1.建立以太坊连接

Web3j web3j = Web3j.build(new HttpService());

默认的连接地址是http://localhost:8545/

2.加载账户信息
账户文件可以在私链数据文件夹中的 keystore 文件夹中找到

Credentials credentials = WalletUtils.loadCredentials(
"123",
"/datadir/chain/keystore/UTC--2018-03-14T14-46-38.646997441Z--c2acba996f709d4b806d3330996f49d50f088258"); // 第一个变量填入账户的密码,第二个变量填入账户文件的 path

3.获取账户余额

Web3j web3j = Web3j.build(new HttpService());
String address = "0xa6fd2ebac389773f5bd34d0738bc5fdbd1bea01b";

EthGetBalance ethGetBalance = web3j.ethGetBalance(address, DefaultBlockParameterName.LATEST).send();

if(ethGetBalance!=null){
// 打印账户余额
System.out.println(ethGetBalance.getBalance());
// 将单位转为以太,方便查看
System.out.println(Convert.fromWei(ethGetBalance.getBalance().toString(), Convert.Unit.ETHER));
}

四、使用 Java 部署智能合约

部署智能合约的命令:

YourSmartContract contract = YourSmartContract.deploy(
<web3j>, <credentials>, GAS_PRICE, GAS_LIMIT,
[<initialValue>,]
<param1>, ..., <paramN>).send();

实例:部署 Compute_sol_Compute.java

// 创建一个 web3j 的连接
Web3j web3j = Web3j.build(new HttpService());

// 部署的时候需要用到该账户的 gas,务必保证该账户余额充足
Credentials credentials = WalletUtils.loadCredentials(
"123",
"/datadir/chain/keystore/UTC--2018-03-14T14-46-38.646997441Z--c2acba996f709d4b806d3330996f49d50f088258");

// 部署合约
Compute_sol_Compute compute_sol_compute
= Compute_sol_Compute.deploy(web3j, credentials, BigInteger.valueOf(200000), BigInteger.valueOf(20000000)).send();

// 部署完成后打印合约地址
System.out.println(simpleStorage_sol_simpleStorage.getContractAddress());

五、使用 Java 调用智能合约

这里,我们还是使用第二篇中编写的智能合约为例

1.加载你的智能合约
命令:

YourSmartContract contract = YourSmartContract.load(
"0x<address>|<ensName>", web3j, credentials, GAS_PRICE, GAS_LIMIT);

实例:

// 填入刚才部署后打印出来的合约地址
String address = "0x9b0851112b41664171338abaf0df86e040c34d07";

Compute_sol_Compute compute_sol_compute = Compute_sol_Compute.load(
address,
web3j,
credentials,
BigInteger.valueOf(200000),
BigInteger.valueOf(20000000));

2.验证合约是否可用
命令:

contract.isValid();

实例:验证已部署的智能合约是否可用

System.out.println(compute_sol_compute.isValid());

3.调用智能合约
命令:

Type result = contract.someMethod(<param1>, ...).send();

实例:调用 Compute_sol_Compute.java 中的方法
1.调用 getLCM 方法

// 调用是能合约函数
Uint256 first = new Uint256(2);
Uint256 second = new Uint256(3);
TransactionReceipt transactionReceipt = compute_sol_compute.getLCM(first, second).send();

System.out.println(transactionReceipt);

执行成功后会返回打印出来本次交易的信息。

TransactionReceipt{transactionHash='0x082a938cf5163afe4c1345308482eeb3ccc0cf21ab933d81b7fd73cb9ab83a8e', transactionIndex='0x0', ...

2.调用 getRecord 方法

Uint256 index = new Uint256(0);

List<Uint256> result = compute_sol_compute.getRecord(index).send().getValue();
for (Uint256 uint256 : result) {
System.out.println(uint256.getValue());
}

结果:

2
3
6

3.使用监听事件,获取合约结果

Uint256 first = new Uint256(2);
Uint256 second = new Uint256(3);

TransactionReceipt transactionReceipt = compute_sol_compute.getLCM(first, second).send();

Compute_sol_Compute.GetLCMEventResponse result = compute_sol_compute.getGetLCMEvents(transactionReceipt).get(0);

System.out.println(result.first.getValue());
System.out.println(result.second.getValue());
System.out.println(result.result.getValue());

使用一个监听事件等待到结果返回,因为是同步的,所以执行的时间会比较长。最后,可以拿回本次智能合约执行的结果。

系列文章地址:
第一篇:智能合约与Solidity高级语言(一)
第二篇:智能合约与Solidity高级语言(二)
第三篇:以太坊私有链搭建及智能合约部署
第四篇:Web3j对智能合约的调用

最后,给大家介绍一下:

ChainBoard 核心团队利用其在区块链技术研发上沉淀的丰富经验,围绕项目的需求持续创新,与合作伙伴开放共赢、深度融合,共同打造在金融科技、游戏、众筹互助、医疗保健、物流等领域的区块链应用。 主要输出智能合约开发、公链开发、联盟链开发及交互应用开发等能力,助力项目迅速取得先发优势。目前团队已经在区块链+游戏及区块链+金融与国内知名游戏运营商和海外金融机构展开深度合作。

欢迎对ChainBoard实战经验感兴趣的朋友和手里有行业资源准备布局区块链的大佬关注我们的公众号并和我们取得联系:(原创文章,转载请注明出处,欢迎读者分享到朋友圈)

《6分钟以太坊实战系列-Web3j对智能合约的调用》 image

    原文作者:ChainBoard链博科技
    原文地址: https://www.jianshu.com/p/3671b65462aa
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞