赞
踩
首先安装solc(用于编译智能合约)和web3j命令行工具(用于打包智能合约)
npm install -g solc
web3j安装地址: Releases · web3j/web3j · GitHub,选择对应操作系统
首先准备一个智能合约 Owner.sol,建议先在remix上测试一下Remix - Ethereum IDE
- //SPDX-License-Identifier:UNLICENSED
-
- pragma solidity >=0.7.0 <0.9.0;
-
- contract Qwner {
- address private owner;
- event OwnerSet(address oldAddress,address newAddress);
- modifier isOwner(){
- require (msg.sender==owner,"Caller is not owner!");
- _;
- }
- constructor (){
- owner = msg.sender;
- emit OwnerSet( address(0) , owner);
- }
- function changeOwner (address newOwner) public isOwner {
- emit OwnerSet(owner, newOwner);
- owner = newOwner;
-
- }
- function getOwner()public view returns (address) {
- return owner;
- }
-
- }

先编译 solcjs Owner.sol --bin --abi --optimize -o .\ 然后你可以看到当前文件夹下生成了两个文件,.abi和.bin,这名字有点反人类,最好改成Owner.abi和Owner.bin
然后打包成把合约打包成Java文件使用如下命令,其中-p是指定包名
web3j generate solidity -a src\main\Owner.abi -b src\main\Owner.bin -o src\main\java\ -p com.example
执行完上述命令后可以看到src\main\java\com\example下多了一个Owner.java文件
接着就是代码,包括部署智能合约,调用智能合约的函数:
- package com.example;
-
- import java.io.BufferedReader;
- import java.io.InputStreamReader;
- import java.math.BigInteger;
- import java.util.List;
- import org.web3j.crypto.Credentials;
- import org.web3j.protocol.Web3j;
- import org.web3j.protocol.core.methods.response.TransactionReceipt;
- import org.web3j.protocol.http.HttpService;
- import org.web3j.tx.gas.ContractGasProvider;
- import org.web3j.tx.gas.DefaultGasProvider;
-
- class Cpp{
- public static void main(String[] args) {
- try {
- Web3j web3j = Web3j.build(new HttpService("http://127.0.0.1:8545"));
- //创建钱包
- Credentials defaulCredential = Credentials.create(App.privateKey1);
- BigInteger gasPrice = web3j.ethGasPrice().send().getGasPrice();
- //这个类的作用是你能够根据你不同函数名称灵活的选择不同的GasPrice和GasLimit
- ContractGasProvider myGasProvider = new DefaultGasProvider(){
- @Override
- public BigInteger getGasPrice(String contractFunc ) {
- return gasPrice;
- }
- @Override
- public BigInteger getGasLimit(String contractFunc ){
- return BigInteger.valueOf(6721975);
- }
- };
- //部署合约,并打印合约地址
- Owner myContract = Owner.deploy(web3j, defaulCredential, myGasProvider).send();
- System.out.println("deploy contract: "+myContract.isValid());
- System.out.println("contract adddress: "+myContract.getContractAddress());
- } catch (Exception e) {
- e.printStackTrace();
- }
-
- }
- }
- public class App
- {
- static Web3j web3j = null;
- //ganache上的accounts[0]和accounts[1]的私钥
- static String privateKey1 = "0x64685c9589ef1e937e8009eba589059d4b7b10bb44a6efc6eeb436c7f47ab85c";
- static String privateKey2 = "0xae7d780682ee82c5301152bec4ddb51ada56944135d211130a582f33c52d7c1d";
- //硬编码,填入合约部署后输出的合约地址
- static String contractAddress = "0x30a856cd0aaf589b99152331ae4bc1193ed32570";
-
- public static void main(String[] args )
- {
- try {
- web3j = Web3j.build(new HttpService("http://127.0.0.1:8545"));
- String clientVersion = web3j.web3ClientVersion().send().getWeb3ClientVersion();
- System.out.println("clientVersion : "+clientVersion);
- List<String> accounts = web3j.ethAccounts().send().getAccounts();
- System.out.println("accounts"+accounts);
- //连个私钥accounts[0]和accounts[1]
- Credentials defaulCredential = Credentials.create(privateKey1);
- Credentials secondCredentials = Credentials.create(privateKey2);
- BigInteger gasPrice = web3j.ethGasPrice().send().getGasPrice();
- ContractGasProvider myGasProvider = new DefaultGasProvider(){
- @Override
- public BigInteger getGasPrice(String contractFunc ) {
- return gasPrice;
- }
- @Override
- public BigInteger getGasLimit(String contractFunc ){
- return BigInteger.valueOf(6721975);
- }
- };
- BufferedReader br = new BufferedReader( new InputStreamReader(System.in));
- String command;
- //根据地址获取合约实例,注意这两个合约实例不同之处在于他们的用户不同,第一个合约对应accounts[0],第二给合约对应accounts[1]
- Owner myContract = Owner.load(contractAddress, web3j,defaulCredential , myGasProvider);
- Owner secondContract = Owner.load(contractAddress, web3j,secondCredentials , myGasProvider);
- //判断合约是否合法,这一步也很重要
- if(myContract.isValid()==false||secondContract.isValid()==false) {
- throw new Exception("load contract error");
- }
- System.out.println("load contract: "+myContract.isValid()+" "+secondContract.isValid());
- System.out.println("contract adddress: "+myContract.getContractAddress()+" "+secondContract.getContractAddress());
-
- boolean exit = false;
- TransactionReceipt receipt;
- while (exit == false) {
- System.out.println("please input command :");
- command = br.readLine();
- switch (command){
- case "set":{
- //accounts[0]把Owner设成accounts[1],accounts[1]再设成accounts[0],如此循环
- if( myContract.getOwner().send().equals( accounts.get(0) ) ){
- receipt = myContract.changeOwner(accounts.get(1)).send();
- }
- else {
- receipt = secondContract.changeOwner(accounts.get(0)).send();
- }
- System.out.println(receipt);
- System.out.println("now owner is ");
- System.out.println(myContract.getOwner().send());
-
- break;
- }
- case "get":{
- System.out.println("now owner is ");
- System.out.println(myContract.getOwner().send());
- break;
- }
- case "exit": {
- System.out.println("you type exit");
- exit = true;
- break;
- }
- default :{
- System.out.println("wrong command input again");
- break;
- }
- }
- }
- } catch (Exception e) {
- System.err.println(e);
- }
- }
- }
-

部署合约(Cpp中main函数输出)
加载合约并调用合约函数 (App中main函数输出)
还能监听区块链事件,主要有三种:监听区块,监听交易,监听合约事件
- package com.example;
-
- import java.io.BufferedReader;
- import java.io.InputStreamReader;
- import java.math.BigInteger;
-
- import org.web3j.crypto.Credentials;
- import org.web3j.protocol.Web3j;
- import org.web3j.protocol.core.DefaultBlockParameterName;
- import org.web3j.protocol.http.HttpService;
- import org.web3j.tx.gas.ContractGasProvider;
- import org.web3j.tx.gas.DefaultGasProvider;
-
- import io.reactivex.disposables.CompositeDisposable;
- import io.reactivex.disposables.Disposable;
-
- public class App
- {
- static Web3j web3j = Web3j.build(new HttpService("http://127.0.0.1:8545"));
- static String privateKey = "0x36308cc80ca2e632b0fb90d8acbe316d4c23f782f03131d4406a0026ed5de9e7";
- static String contractAddress = "0x30a856cd0aaf589b99152331ae4bc1193ed32570";
- static DefaultBlockParameterName earliest = DefaultBlockParameterName.EARLIEST;
- static DefaultBlockParameterName latest = DefaultBlockParameterName.LATEST;
- public static void main( String[] args )
- {
- try {
- String clientVersion = web3j.web3ClientVersion().send().getWeb3ClientVersion();
- System.out.println(clientVersion);
- Credentials defaulCredential = Credentials.create(privateKey);
- BigInteger gasLimit = BigInteger.valueOf(6721975);
- BigInteger gasPrice = web3j.ethGasPrice().send().getGasPrice();
- ContractGasProvider simplProvider = new DefaultGasProvider(){
- @Override
- public BigInteger getGasPrice(String contractFunc ) {
- return gasPrice;
- }
- @Override
- public BigInteger getGasLimit(String contractFunc ){
- return gasLimit;
- }
- };
- Owner mycontract = Owner.load(contractAddress, web3j, defaulCredential, simplProvider);
- if(mycontract.isValid()==false){
- throw new Exception("load error");
- }
- System.out.println("load contract: "+mycontract.isValid());
-
- //使用CompositeDisposable
- CompositeDisposable disposableSet = new CompositeDisposable();
- //监听区块
- Disposable blockSubscription =web3j.blockFlowable(false).subscribe( block -> {
- System.out.println("new block: "+block.getBlock().getHash());
- } );
- //监听交易
- Disposable txsubcription = web3j.transactionFlowable().subscribe( tx -> {
- System.out.println("new tx: from "+tx.getFrom()+ "; to "+tx.getTo());
- } );
- //监听合约的OwnerSet事件
- Disposable ownersetSubscription = mycontract.ownerSetEventFlowable(latest, latest).subscribe(res -> {
- System.out.println(res.log);
- System.out.println("owner chage: old "+res.oldAddress+" new "+res.newAddress);
- });
-
- disposableSet.add(blockSubscription);
- disposableSet.add(txsubcription);
- disposableSet.add(ownersetSubscription);
- System.out.println(disposableSet);
- BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
- String command =null;
- while(true){
- System.out.println("input command: ");
- command = br.readLine();
- if(command.equals("stop")){
- disposableSet.dispose();
- System.out.println(disposableSet);
- break;
- } else {
- continue;
- }
- }
- } catch (Exception e) {
- System.err.println(e);
- }
- }
- }

控制台输出:
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。