web3j基本使用

编译生成javaBean对象

  1. 编写solidity程序,保存在Voting.sol文件中
pragma solidity ^0.4.22;

contract Voting{
    
    bytes32[] public candidateList;
    mapping(bytes32=>uint8) public votingMap;
    
    constructor(bytes32[] candidateListName) public{
        candidateList = candidateListName;
    }
    
    function validateCandidate(bytes32 candidateListName) internal view returns(bool){
        for(uint8 i=0 ; i<candidateList.length ; i++){
            if(candidateListName == candidateList[i]){
                return true;
            }
        }
        return false;
    }
    
    function vote(bytes32 candidateListName) public{
        require(validateCandidate(candidateListName));
        votingMap[candidateListName] += 1;
    }
    
    function totalVoters(bytes32 candidateListName) public view returns(uint8){
        require(validateCandidate(candidateListName));
        return votingMap[candidateListName];
    } 
}
  1. 编译sol文件,生成bin和abi文件
./node_modules/solc/solcjs Voting.sol --bin --abi --optimize -o sourceCode
  1. 使用web3j编译生成javaBean类,将生成的文件加入到java的项目中
web3j solidity generate sourceCode/Voting_sol_Voting.bin sourceCode/Voting_sol_Voting.abi -o ./javaAPI -p com.yqj.blockChain

部署私链

geth --networkid 123 --rpc --rpcaddr 192.168.1.114 --rpcport 8989 --port 3000 --dev --datadir data1 console

编写java程序测试web3j

  1. 导包
<dependency>
    <groupId>org.web3j</groupId>
    <artifactId>core</artifactId>
    <version>3.6.0</version>
</dependency>
  1. 测试连接情况
@Slf4j(topic = "c.BlockChainTest")
public class BlockChainTest {
    public static void main(String[] args) throws IOException {
        Web3j web3 = Web3j.build(new HttpService("http://192.168.1.114:8989"));
        Web3ClientVersion web3ClientVersion = web3.web3ClientVersion().send();
        String clientVersion = web3ClientVersion.getWeb3ClientVersion();
        log.debug("{}",clientVersion);
    }
}

输出结果:

19:14:34 [main] c.BlockChainTest - Geth/v1.8.17-stable/linux-amd64/go1.9.7

Process finished with exit code 0

合约部署与方法调用

  • 测试文件 BlockChainTest
package com.yqj.blockchain;

import lombok.extern.slf4j.Slf4j;
import org.web3j.crypto.Credentials;
import org.web3j.crypto.WalletUtils;
import org.web3j.protocol.Web3j;
import org.web3j.protocol.core.methods.response.Web3ClientVersion;
import org.web3j.protocol.http.HttpService;
import org.web3j.utils.Numeric;

import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

@Slf4j(topic = "c.BlockChainTest")
public class BlockChainTest {
    public static void main(String[] args) throws Exception {
        loadContract();
    }

    //加载已经在链上的合约,并且调用方法
    public static void loadContract() throws Exception {
        //建立私链连接
        Web3j web3j = Web3j.build(new HttpService("http://192.168.1.114:8989"));
        //加载钱包账户,需要从geth的data文件中拷贝出来keysotre文件夹里的内容
        Credentials credentials = WalletUtils.loadCredentials("", "D:\\study\\code\\blockchain\\java-blockchain\\target\\classes\\keystore\\UTC--2020-05-23T13-30-20.410109802Z--613d104e6d80ce5a06e7987d39bbd4ee0ccd7656");
        //加载合约
        String contractAddr = "0x0db5bd6503e820be1691760491fd83df3ede3d76";
        Voting_sol_Voting contract = Voting_sol_Voting.load(contractAddr, web3j, credentials, BigInteger.valueOf(3000000), BigInteger.valueOf(3000000));
        log.debug("{}",contract);
        String count = contract.totalVoters(stringToBytes("Alice")).send().toString();
        log.debug("{}",count);
        contract.vote(stringToBytes("Alice")).send();
        count = contract.totalVoters(stringToBytes("Alice")).send().toString();
        log.debug("{}",count);
    }

    //部署合约
    public static void createContract() throws Exception {
        //建立私链连接
        Web3j web3j = Web3j.build(new HttpService("http://192.168.1.114:8989"));
        //查看版本信息,验证是否连接成功
        Web3ClientVersion web3ClientVersion = web3j.web3ClientVersion().send();
        String clientVersion = web3ClientVersion.getWeb3ClientVersion();
        log.debug("{}",clientVersion);
        //加载钱包账户
        Credentials credentials = WalletUtils.loadCredentials("", "D:\\study\\code\\blockchain\\java-blockchain\\target\\classes\\keystore\\UTC--2020-05-23T13-30-20.410109802Z--613d104e6d80ce5a06e7987d39bbd4ee0ccd7656");
        log.debug("{}",credentials);
        //构建初始化参数
        List<byte[]> list = new ArrayList<>();
        list.add(stringToBytes("Alice"));
        list.add(stringToBytes("Bob"));
        list.add(stringToBytes("Jerry"));
        //部署合约
        Voting_sol_Voting voting = Voting_sol_Voting.deploy(web3j,credentials,BigInteger.valueOf(3000000),BigInteger.valueOf(3000000),list).send();
        //合约地址 0x0db5bd6503e820be1691760491fd83df3ede3d76
        log.debug("{}",voting.getContractAddress());
    }

    //将字符串转换为可以转换为bytes32的形式的byte[]
    public static byte[] stringToBytes(String asciiValue)
    {
        char[] chars = asciiValue.toCharArray();
        StringBuffer hex = new StringBuffer();
        for (int i = 0; i < chars.length; i++) {
            hex.append(Integer.toHexString((int) chars[i]));
        }
        String hexString = hex.toString() + "".join("", Collections.nCopies(32 - (hex.length()/2), "00"));
        return Numeric.hexStringToByteArray(hexString);
    }
}
  • 由web3j自动生成的文件 Voting_sol_Voting
package com.yqj.blockchain;

import java.math.BigInteger;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import org.web3j.abi.FunctionEncoder;
import org.web3j.abi.TypeReference;
import org.web3j.abi.datatypes.Function;
import org.web3j.abi.datatypes.Type;
import org.web3j.abi.datatypes.generated.Bytes32;
import org.web3j.abi.datatypes.generated.Uint8;
import org.web3j.crypto.Credentials;
import org.web3j.protocol.Web3j;
import org.web3j.protocol.core.RemoteCall;
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 3.6.0.
 */
public class Voting_sol_Voting extends Contract {
    private static final String BINARY = "608060405234801561001057600080fd5b506040516102c43803806102c483398101604052805101805161003a906000906020840190610041565b50506100ab565b82805482825590600052602060002090810192821561007e579160200282015b8281111561007e5782518255602090920191600190910190610061565b5061008a92915061008e565b5090565b6100a891905b8082111561008a5760008155600101610094565b90565b61020a806100ba6000396000f3006080604052600436106100615763ffffffff7c01000000000000000000000000000000000000000000000000000000006000350416634db33f9281146100665780634dfb9c8014610094578063a69beaba146100ac578063b13c744b146100c6575b600080fd5b34801561007257600080fd5b5061007e6004356100f0565b6040805160ff9092168252519081900360200190f35b3480156100a057600080fd5b5061007e600435610105565b3480156100b857600080fd5b506100c4600435610131565b005b3480156100d257600080fd5b506100de60043561016e565b60408051918252519081900360200190f35b60016020526000908152604090205460ff1681565b60006101108261018d565b151561011b57600080fd5b5060009081526001602052604090205460ff1690565b61013a8161018d565b151561014557600080fd5b6000908152600160208190526040909120805460ff19811660ff91821690930116919091179055565b600080548290811061017c57fe5b600091825260209091200154905081565b6000805b60005460ff821610156101d3576000805460ff83169081106101af57fe5b6000918252602090912001548314156101cb57600191506101d8565b600101610191565b600091505b509190505600a165627a7a72305820bd2c76f66cb75779f0ca7f961af01658e499cf6ba22b040e7ea9e334018b76c60029";

    public static final String FUNC_VOTINGMAP = "votingMap";

    public static final String FUNC_TOTALVOTERS = "totalVoters";

    public static final String FUNC_VOTE = "vote";

    public static final String FUNC_CANDIDATELIST = "candidateList";

    @Deprecated
    protected Voting_sol_Voting(String contractAddress, Web3j web3j, Credentials credentials, BigInteger gasPrice, BigInteger gasLimit) {
        super(BINARY, contractAddress, web3j, credentials, gasPrice, gasLimit);
    }

    protected Voting_sol_Voting(String contractAddress, Web3j web3j, Credentials credentials, ContractGasProvider contractGasProvider) {
        super(BINARY, contractAddress, web3j, credentials, contractGasProvider);
    }

    @Deprecated
    protected Voting_sol_Voting(String contractAddress, Web3j web3j, TransactionManager transactionManager, BigInteger gasPrice, BigInteger gasLimit) {
        super(BINARY, contractAddress, web3j, transactionManager, gasPrice, gasLimit);
    }

    protected Voting_sol_Voting(String contractAddress, Web3j web3j, TransactionManager transactionManager, ContractGasProvider contractGasProvider) {
        super(BINARY, contractAddress, web3j, transactionManager, contractGasProvider);
    }

    public RemoteCall<BigInteger> votingMap(byte[] param0) {
        final Function function = new Function(FUNC_VOTINGMAP, 
                Arrays.<Type>asList(new Bytes32(param0)),
                Arrays.<TypeReference<?>>asList(new TypeReference<Uint8>() {}));
        return executeRemoteCallSingleValueReturn(function, BigInteger.class);
    }

    public RemoteCall<BigInteger> totalVoters(byte[] candidateListName) {
        final Function function = new Function(FUNC_TOTALVOTERS, 
                Arrays.<Type>asList(new Bytes32(candidateListName)),
                Arrays.<TypeReference<?>>asList(new TypeReference<Uint8>() {}));
        return executeRemoteCallSingleValueReturn(function, BigInteger.class);
    }

    public RemoteCall<TransactionReceipt> vote(byte[] candidateListName) {
        final Function function = new Function(
                FUNC_VOTE, 
                Arrays.<Type>asList(new Bytes32(candidateListName)),
                Collections.<TypeReference<?>>emptyList());
        return executeRemoteCallTransaction(function);
    }

    public RemoteCall<byte[]> candidateList(BigInteger param0) {
        final Function function = new Function(FUNC_CANDIDATELIST, 
                Arrays.<Type>asList(new org.web3j.abi.datatypes.generated.Uint256(param0)), 
                Arrays.<TypeReference<?>>asList(new TypeReference<Bytes32>() {}));
        return executeRemoteCallSingleValueReturn(function, byte[].class);
    }

    public static RemoteCall<Voting_sol_Voting> deploy(Web3j web3j, Credentials credentials, ContractGasProvider contractGasProvider, List<byte[]> candidateListName) {
        String encodedConstructor = FunctionEncoder.encodeConstructor(Arrays.<Type>asList(new org.web3j.abi.datatypes.DynamicArray<Bytes32>(
                        org.web3j.abi.Utils.typeMap(candidateListName, Bytes32.class))));
        return deployRemoteCall(Voting_sol_Voting.class, web3j, credentials, contractGasProvider, BINARY, encodedConstructor);
    }

    public static RemoteCall<Voting_sol_Voting> deploy(Web3j web3j, TransactionManager transactionManager, ContractGasProvider contractGasProvider, List<byte[]> candidateListName) {
        String encodedConstructor = FunctionEncoder.encodeConstructor(Arrays.<Type>asList(new org.web3j.abi.datatypes.DynamicArray<Bytes32>(
                        org.web3j.abi.Utils.typeMap(candidateListName, Bytes32.class))));
        return deployRemoteCall(Voting_sol_Voting.class, web3j, transactionManager, contractGasProvider, BINARY, encodedConstructor);
    }

    @Deprecated
    public static RemoteCall<Voting_sol_Voting> deploy(Web3j web3j, Credentials credentials, BigInteger gasPrice, BigInteger gasLimit, List<byte[]> candidateListName) {
        String encodedConstructor = FunctionEncoder.encodeConstructor(Arrays.<Type>asList(new org.web3j.abi.datatypes.DynamicArray<Bytes32>(
                        org.web3j.abi.Utils.typeMap(candidateListName, Bytes32.class))));
        return deployRemoteCall(Voting_sol_Voting.class, web3j, credentials, gasPrice, gasLimit, BINARY, encodedConstructor);
    }

    @Deprecated
    public static RemoteCall<Voting_sol_Voting> deploy(Web3j web3j, TransactionManager transactionManager, BigInteger gasPrice, BigInteger gasLimit, List<byte[]> candidateListName) {
        String encodedConstructor = FunctionEncoder.encodeConstructor(Arrays.<Type>asList(new org.web3j.abi.datatypes.DynamicArray<Bytes32>(
                        org.web3j.abi.Utils.typeMap(candidateListName, Bytes32.class))));
        return deployRemoteCall(Voting_sol_Voting.class, web3j, transactionManager, gasPrice, gasLimit, BINARY, encodedConstructor);
    }

    @Deprecated
    public static Voting_sol_Voting load(String contractAddress, Web3j web3j, Credentials credentials, BigInteger gasPrice, BigInteger gasLimit) {
        return new Voting_sol_Voting(contractAddress, web3j, credentials, gasPrice, gasLimit);
    }

    @Deprecated
    public static Voting_sol_Voting load(String contractAddress, Web3j web3j, TransactionManager transactionManager, BigInteger gasPrice, BigInteger gasLimit) {
        return new Voting_sol_Voting(contractAddress, web3j, transactionManager, gasPrice, gasLimit);
    }

    public static Voting_sol_Voting load(String contractAddress, Web3j web3j, Credentials credentials, ContractGasProvider contractGasProvider) {
        return new Voting_sol_Voting(contractAddress, web3j, credentials, contractGasProvider);
    }

    public static Voting_sol_Voting load(String contractAddress, Web3j web3j, TransactionManager transactionManager, ContractGasProvider contractGasProvider) {
        return new Voting_sol_Voting(contractAddress, web3j, transactionManager, contractGasProvider);
    }
}
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 220,295评论 6 512
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,928评论 3 396
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 166,682评论 0 357
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 59,209评论 1 295
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 68,237评论 6 397
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,965评论 1 308
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,586评论 3 420
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,487评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 46,016评论 1 319
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 38,136评论 3 340
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,271评论 1 352
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,948评论 5 347
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,619评论 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,139评论 0 23
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,252评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,598评论 3 375
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,267评论 2 358