前几篇博客里有个web3j基本使用,本方法也是建立在那篇博客里写的。
交易代码如下:
/**
* 私钥交易或者keystore交易
* @param fromAddress 出方地址
* @param fromPk 出方私钥
* @param toAddress 入方地址
* @param value 数量 单位wei
* @throws IOException
* @throws CipherException
* @throws InvalidAlgorithmParameterException
* @throws NoSuchAlgorithmException
* @throws NoSuchProviderException
* @throws InterruptedException
* @throws ExecutionException
*/
public static void tran(String fromAddress, String fromPk, String toAddress,BigInteger value) throws IOException, CipherException, InvalidAlgorithmParameterException, NoSuchAlgorithmException, NoSuchProviderException, InterruptedException, ExecutionException {
Web3j web3j = initWeb3j();
//使用私钥生成Credentials对象
Credentials credentials = Credentials.create(fromPk);
//加载本地KeyStore文件生成Credentials对象
//Credentials credentials = WalletUtils.loadCredentials(password,keyStore);
EthGetTransactionCount ethGetTransactionCount = web3j.ethGetTransactionCount(
fromAddress, DefaultBlockParameterName.LATEST).send();
BigInteger nonce = ethGetTransactionCount.getTransactionCount();
BigInteger gasPrice = web3j.ethGasPrice().send().getGasPrice();
BigInteger gasLimit = new BigInteger("900000");
//生成RawTransaction交易对象
RawTransaction rawTransaction = RawTransaction.createTransaction(nonce,gasPrice,gasLimit,toAddress,value,"abcde123");//可以额外带数据
//使用Credentials对象对RawTransaction对象进行签名
byte[] signedMessage = TransactionEncoder.signMessage(rawTransaction,credentials);
String hexValue = Numeric.toHexString(signedMessage);
EthSendTransaction ethSendTransaction = web3j.ethSendRawTransaction(hexValue).sendAsync().get();
String transactionHash = ethSendTransaction.getTransactionHash();
if(ethSendTransaction.hasError()){
String message=ethSendTransaction.getError().getMessage();
System.out.println("transaction failed,info:"+message);
}else{
EthGetTransactionReceipt send = web3j.ethGetTransactionReceipt(transactionHash).send();
if (send != null) {
System.out.println("交易成功");
}
}
}
这里需要注意的也很多:
1.这里只是交易方式的一种,签名交易,相对来说比较方便。可以对任何区块节点使用本api。
2.签名交易主要是使用私钥对交易过程进行签名,所以不管是私钥,还是keystore都可以达到这个目的。
3.nonce相当于是标识,标识不同的交易,如果nonce相同就代表着是同一笔交易。节点内部会先结算nonce小的交易。这里查询了出方的交易次数作为新交易的nonce.(index和length总是差1)
4.加密交易数据然后进行发送请求,如果成功的话会返回交易hash
5.通过交易hash可以查询到EthGetTransactionReceipt ,如果有的话,代表着这笔交易已经完成。但要注意的是,本例中这样写是不对的,因为有可能这块代码执行了之后,发现返回的是null,因为挖矿等延时原因,区块在代码执行完后才开始进行交易。所以这里要延迟循环判断。
6.严格来讲EthGetTransactionReceipt不为null,也不能说明它成功了。因为还需要其他区块网络确认,一般以太坊要确认12次算是真正转账成功。怎么判断确认多少次?EthGetTransactionReceipt里面有交易区块blockid,可以通过eth.ethBlockNumber()获取当前区块blockid,它们之间的差值+1就是确认次数。