建一个空的project
mvn archetype:generate -DgroupId=com.test -DartifactId=metacoinJava -DarchetypeArtifactId=maven-archetype-quickstart -DinteractiveMode=false
加入web3j的依赖
<dependency>
<groupId>org.web3j</groupId>
<artifactId>core</artifactId>
<version>4.8.4</version>
</dependency>
下载 web3j-cli
https://github.com/web3j/web3j-cli
配置到环境变量,验证下应该出现如下提示
D:\workspace\metacoin>web3j generate --help
_ _____ _
| | |____ (_)
__ _____| |__ / /_
\ \ /\ / / _ \ '_ \ \ \ |
\ V V / __/ |_) |.___/ / |
\_/\_/ \___|_.__/ \____/| |
_/ |
|__/
by Web3Labs
web3j generate [OPTIONS] [COMMAND]
Description:
Generate Wrappers or Tests
通过npm安装truffle ganache-cli solc
npm install -g truffle
npm install -g ganache-cli
npm install -g solc
然后下载一个简单的合约项目,自己建合约项目会花一点时间,直接用教程提供的合约会比较简单
truffle unbox metacoin
启动 ganache-cli -l 2000000000000
在truffle-config.js里面改network dev,
truffle migrate --network dev
用以下命令生成java的wrapper class
web3j generate truffle -t=build\contracts\MetaCoin.json -p=com.test -o=java
找到java目录下的 MetaCoin,拷贝到刚刚的mvn 项目
记得加上如下
<maven.compiler.target>1.8</maven.compiler.target>
<maven.compiler.source>1.8</maven.compiler.source>
https://stackoverflow.com/questions/8697513/why-do-i-get-must-override-a-superclass-method-with-override
In Java 5, the @Override annotation requires that the method is actually overriding a method in a superclass.
In Java 6 and later, the @Override annotation will also be satisfied if the method is implementing an abstract method in a superclass or interface.
打开truffle console --network dev
var acc = await web3.eth.accounts.create();
console.log(acc)
D:\workspace\metacoin>truffle console --network dev
truffle(dev)> var acc = await web3.eth.accounts.create();
undefined
truffle(dev)> console.log(acc)
{
address: '0xB3B5c03054ECF1691A3E1889E90d2F4930b31e40',
privateKey: '0x9905450c0112f9bddc12778aab1b060c7491d94c0bb4c669c46d1896845bde90',
signTransaction: [Function: signTransaction],
sign: [Function: sign],
encrypt: [Function: encrypt]
}
undefined
truffle(dev)>
保存下私钥
public static String address = "0xB3B5c03054ECF1691A3E1889E90d2F4930b31e40";
public static String privateKey = "0x9905450c0112f9bddc12778aab1b060c7491d94c0bb4c669c46d1896845bde90";
public static BigInteger getBalance(Web3j web3j, String fromAddress) {
BigInteger balance = null;
try {
EthGetBalance ethGetBalance = web3j.ethGetBalance(fromAddress, DefaultBlockParameterName.PENDING).send();
balance = ethGetBalance.getBalance();
} catch (IOException e) {
e.printStackTrace();
}
System.out.println("address " + fromAddress + " balance " + balance + " wei");
return balance;
}
public static void main(String[] args) {
System.out.println("Hello World!");
Web3j web3j = Web3j.build(new HttpService("http://localhost:8545"));
Credentials credentials = Credentials.create(privateKey);
System.out.println("Address:" + credentials.getAddress());
System.out.println("Balance:" + getBalance(web3j,credentials.getAddress()));
}
可以看到账户是没有钱的
Hello World!
SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".
SLF4J: Defaulting to no-operation (NOP) logger implementation
SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.
Address:0xb3b5c03054ecf1691a3e1889e90d2f4930b31e40
address 0xb3b5c03054ecf1691a3e1889e90d2f4930b31e40 balance 0 wei
Balance:0
找几个可用账号
truffle(dev)> var accounts = await web3.eth.getAccounts();
undefined
truffle(dev)> accounts[0]
'0x90Af934A1675e8dB26389406B5f5a651eB47FB18'
truffle(dev)>
truffle(dev)> var rec= await instance.sendCoin('0xB3B5c03054ECF1691A3E1889E90d2F4930b31e40',500)
undefined
truffle(dev)> var balance = await instance.getBalance('0xB3B5c03054ECF1691A3E1889E90d2F4930b31e40')
undefined
truffle(dev)> balance.toNumber()
500
truffle(dev)> var balance = await instance.getBalance('0x90Af934A1675e8dB26389406B5f5a651eB47FB18')
undefined
truffle(dev)> balance.toNumber()
9500
可以看到account[0] 少了500
记下contract 的address
truffle(dev)> console.log(instance.address)
0xE900939B709321b27afD5Bbe1E9b4213085463cF
undefined
现在用java的两种方式来实现它
public static Function getContractSenCoin(String receiver, BigInteger amount) {
final org.web3j.abi.datatypes.Function function = new org.web3j.abi.datatypes.Function(
MetaCoin.FUNC_SENDCOIN,
Arrays.<Type>asList(new org.web3j.abi.datatypes.Address(receiver),
new org.web3j.abi.datatypes.generated.Uint256(amount)),
Collections.<TypeReference<?>>emptyList());
return function;
}
public static RawTransaction createRawtransaction(Web3j web3j,Credentials credentials, Function function,String contracAddress) throws IOException {
EthGetTransactionCount ethGetTransactionCount =
web3j.ethGetTransactionCount(credentials.getAddress(),DefaultBlockParameterName.LATEST).send();
BigInteger nonce = ethGetTransactionCount.getTransactionCount();
StaticGasProvider gasProvider = new StaticGasProvider(BigInteger.valueOf(0),BigInteger.valueOf(20000000));
String encodedData = FunctionEncoder.encode(function);
RawTransaction rawTransaction = RawTransaction.createTransaction(nonce, BigInteger.ZERO,gasProvider.getGasLimit(function.getName()),
contracAddress,BigInteger.ZERO, encodedData);
return rawTransaction;
}
public static void signAndSendRawTransaction(Web3j web3j,Credentials credentials,RawTransaction rawTransaction) throws IOException {
byte[] signedMessage = TransactionEncoder.signMessage(rawTransaction, credentials);
String hexValue = Numeric.toHexString(signedMessage);
EthSendTransaction ethSendTransaction = web3j.ethSendRawTransaction(hexValue).send();
String transactionHash = ethSendTransaction.getTransactionHash();
System.out.println("transactionHash:" + transactionHash);
Optional<TransactionReceipt> receipt = null;
do {
System.out.println("checking if transaction "+transactionHash+" is mined....");
EthGetTransactionReceipt rsp = web3j.ethGetTransactionReceipt(transactionHash).send();
receipt = rsp.getTransactionReceipt();
}while(!receipt.isPresent());
}
调用
public static void main(String[] args) throws IOException {
System.out.println("Hello World!");
Web3j web3j = Web3j.build(new HttpService("http://localhost:8545"));
Credentials credentials = Credentials.create(privateKey);
System.out.println("Address:" + credentials.getAddress());
System.out.println("Balance:" + getBalance(web3j,credentials.getAddress()));
Function function = getContractSenCoin(orgaddress,BigInteger.valueOf(1));
RawTransaction rawtransaction = App.createRawtransaction(web3j, credentials, function, contractAddress);
App.signAndSendRawTransaction(web3j, credentials, rawtransaction);
}
查看
truffle(dev)> var balance = await instance.getBalance('0x90Af934A1675e8dB26389406B5f5a651eB47FB18')
undefined
truffle(dev)> balance.toNumber()
9501
可以看到放回一个coin
第二种比较简单
TransactionManager txManager = new FastRawTransactionManager(web3j,credentials);
StaticGasProvider gasProvider = new StaticGasProvider(BigInteger.valueOf(0),BigInteger.valueOf(20000000));
MetaCoin instance = MetaCoin.load(contractAddress, web3j, txManager, gasProvider);
TransactionReceipt receipt = instance.sendCoin(orgaddress, BigInteger.valueOf(1)).send();
System.out.println("receipt:"+receipt);
BigInteger cb = instance.getBalance(orgaddress).send();
System.out.println("Private Balance:"+cb);
BigInteger cb1 = instance.getBalance(credentials.getAddress()).send();
System.out.println("Private Balance:"+cb1);