1. 投票合约的编写
solidity代码:
pragma solidity ^0.4.24; //编译器版本要求:0.4.x
contract Voting { // 使用 contract 关键字定义合约
mapping (bytes32 => uint8) public votes; //使用映射表记录候选人得票数
bytes32[] public candidates; //使用定长数组记录候选人名单
//构造函数。参数:候选人名单
constructor(bytes32[] candidateNames) public {
candidates = candidateNames;
}
//获取指定候选人得票数。参数:候选人名称。返回值:8 位无符号整数
function getVotesFor(bytes32 candidate) view public returns (uint8) {
require(validCandidate(candidate));//要求指定名称必须是有效候选人,否则停止执行
return votes[candidate];
}
//投票给指定候选人。参数:候选人名称
function voteFor(bytes32 candidate) public {
require(validCandidate(candidate));
votes[candidate] += 1;
}
//检查指定的名称是否在候选人名单里。参数:候选人名称。返回值:true 或 false
function validCandidate(bytes32 candidate) view public returns (bool) {
for(uint i = 0; i < candidates.length; i++) {
if (candidates[i] == candidate) {
return true;
}
}
return false;
}
}
2.用web3j生成对应的java合约类
package org.example.Voting;
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.Bool;
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;
/**
* <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.4.0.
*/
public class Voting extends Contract {
private static final String BINARY = "608060405234801561001057600080fd5b506040516102f23803806102f283398101604052805101805161003a906001906020840190610041565b50506100ab565b82805482825590600052602060002090810192821561007e579160200282015b8281111561007e5782518255602090920191600190910190610061565b5061008a92915061008e565b5090565b6100a891905b8082111561008a5760008155600101610094565b90565b610238806100ba6000396000f30060806040526004361061006c5763ffffffff7c01000000000000000000000000000000000000000000000000000000006000350416632b38cd9681146100715780633477ee2e1461009f57806335154986146100c9578063392e6678146100e3578063b13479081461010f575b600080fd5b34801561007d57600080fd5b50610089600435610127565b6040805160ff9092168252519081900360200190f35b3480156100ab57600080fd5b506100b760043561013c565b60408051918252519081900360200190f35b3480156100d557600080fd5b506100e160043561015b565b005b3480156100ef57600080fd5b506100fb600435610193565b604080519115158252519081900360200190f35b34801561011b57600080fd5b506100896004356101e0565b60006020819052908152604090205460ff1681565b600180548290811061014a57fe5b600091825260209091200154905081565b61016481610193565b151561016f57600080fd5b6000908152602081905260409020805460ff8082166001011660ff19909116179055565b6000805b6001548110156101d55760018054849190839081106101b257fe5b60009182526020909120015414156101cd57600191506101da565b600101610197565b600091505b50919050565b60006101eb82610193565b15156101f657600080fd5b5060009081526020819052604090205460ff16905600a165627a7a72305820e21c62aada75c0a8df3642910df2e5ca8d19c86fe553d488d8f78dcb0ded40770029";
public static final String FUNC_VOTES = "votes";
public static final String FUNC_CANDIDATES = "candidates";
public static final String FUNC_VOTEFOR = "voteFor";
public static final String FUNC_VALIDCANDIDATE = "validCandidate";
public static final String FUNC_GETVOTESFOR = "getVotesFor";
protected Voting(String contractAddress, Web3j web3j, Credentials credentials, BigInteger gasPrice, BigInteger gasLimit) {
super(BINARY, contractAddress, web3j, credentials, gasPrice, gasLimit);
}
protected Voting(String contractAddress, Web3j web3j, TransactionManager transactionManager, BigInteger gasPrice, BigInteger gasLimit) {
super(BINARY, contractAddress, web3j, transactionManager, gasPrice, gasLimit);
}
public RemoteCall<BigInteger> votes(byte[] param0) {
final Function function = new Function(FUNC_VOTES,
Arrays.<Type>asList(new Bytes32(param0)),
Arrays.<TypeReference<?>>asList(new TypeReference<Uint8>() {}));
return executeRemoteCallSingleValueReturn(function, BigInteger.class);
}
public RemoteCall<byte[]> candidates(BigInteger param0) {
final Function function = new Function(FUNC_CANDIDATES,
Arrays.<Type>asList(new org.web3j.abi.datatypes.generated.Uint256(param0)),
Arrays.<TypeReference<?>>asList(new TypeReference<Bytes32>() {}));
return executeRemoteCallSingleValueReturn(function, byte[].class);
}
public RemoteCall<TransactionReceipt> voteFor(byte[] candidate) {
final Function function = new Function(
FUNC_VOTEFOR,
Arrays.<Type>asList(new Bytes32(candidate)),
Collections.<TypeReference<?>>emptyList());
return executeRemoteCallTransaction(function);
}
public RemoteCall<Boolean> validCandidate(byte[] candidate) {
final Function function = new Function(FUNC_VALIDCANDIDATE,
Arrays.<Type>asList(new Bytes32(candidate)),
Arrays.<TypeReference<?>>asList(new TypeReference<Bool>() {}));
return executeRemoteCallSingleValueReturn(function, Boolean.class);
}
public RemoteCall<BigInteger> getVotesFor(byte[] candidate) {
final Function function = new Function(FUNC_GETVOTESFOR,
Arrays.<Type>asList(new Bytes32(candidate)),
Arrays.<TypeReference<?>>asList(new TypeReference<Uint8>() {}));
return executeRemoteCallSingleValueReturn(function, BigInteger.class);
}
public static RemoteCall<Voting> deploy(Web3j web3j, Credentials credentials, BigInteger gasPrice, BigInteger gasLimit, List<byte[]> candidateNames) {
String encodedConstructor = FunctionEncoder.encodeConstructor(Arrays.<Type>asList(new org.web3j.abi.datatypes.DynamicArray<Bytes32>(
org.web3j.abi.Utils.typeMap(candidateNames, Bytes32.class))));
return deployRemoteCall(Voting.class, web3j, credentials, gasPrice, gasLimit, BINARY, encodedConstructor);
}
public static RemoteCall<Voting> deploy(Web3j web3j, TransactionManager transactionManager, BigInteger gasPrice, BigInteger gasLimit, List<byte[]> candidateNames) {
String encodedConstructor = FunctionEncoder.encodeConstructor(Arrays.<Type>asList(new org.web3j.abi.datatypes.DynamicArray<Bytes32>(
org.web3j.abi.Utils.typeMap(candidateNames, Bytes32.class))));
return deployRemoteCall(Voting.class, web3j, transactionManager, gasPrice, gasLimit, BINARY, encodedConstructor);
}
public static Voting load(String contractAddress, Web3j web3j, Credentials credentials, BigInteger gasPrice, BigInteger gasLimit) {
return new Voting(contractAddress, web3j, credentials, gasPrice, gasLimit);
}
public static Voting load(String contractAddress, Web3j web3j, TransactionManager transactionManager, BigInteger gasPrice, BigInteger gasLimit) {
return new Voting(contractAddress, web3j, transactionManager, gasPrice, gasLimit);
}
}
3. App.java(测试类)
package org.example;
import org.example.Voting.Voting;
import org.web3j.protocol.Web3j;
import org.web3j.protocol.core.RemoteCall;
import org.web3j.protocol.core.Request;
import org.web3j.protocol.core.methods.response.TransactionReceipt;
import org.web3j.protocol.core.methods.response.Web3ClientVersion;
import org.web3j.protocol.http.HttpService;
import org.web3j.tx.ClientTransactionManager;
import org.web3j.tx.Contract;
import java.io.IOException;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.List;
/**
* Hello world!
*
*/
public class App
{
public static void main(String[] args) throws Exception {
Web3j web3j = Web3j.build(new HttpService("http://localhost:8545"));//实例化web3j对象
List<String> accounts = web3j.ethAccounts().send().getAccounts();
ClientTransactionManager clientTransactionManager = new ClientTransactionManager(web3j, accounts.get(0));
//准备参数,候选人名单
ArrayList<byte[]> candidates = new ArrayList<>();
candidates.add(stringToBytes32("Tommy"));
candidates.add(stringToBytes32("Lucky"));
candidates.add(stringToBytes32("Mike"));
//部署合约
Voting send = Voting.deploy(web3j, clientTransactionManager, Contract.GAS_PRICE, Contract.GAS_LIMIT, candidates).send();
//获取合约的部署地址
String contractAddress = send.getContractAddress();
System.out.println(contractAddress);
//加载已部署的合约
//Voting voting = Voting.load(contractAddress,web3j,clientTransactionManager,Contract.GAS_PRICE,Contract.GAS_LIMIT,candidates);
//用账户一给Tommy投票
//TransactionReceipt a = voting.voteFor(stringToBytes32("Tommy")).send();
//System.out.println(a);//打印收据
//获取Tommy的票数
//BigInteger tommyvotes = voting.getVotesFor(stringToBytes32("Tommy")).send();
//System.out.println("tommy得票:"+tommyvotes);
}
//将String转化为字节流
private static byte[] stringToBytes32(String str){
byte[] a = new byte[32];
System.arraycopy(str.getBytes(),0,a,32-str.length(),str.length());
return a;
}
}