大家都知道使用web3j實現以太坊的功能。
查詢了很多文章,對於全自動發送交易的文章少之又少,尤其是一個賬戶同時發送多筆交易的方式。(容易 nonce to low 的錯誤)
這裏我簡單說說我的思路。
基本知識:
- 以太坊發送交易需要帶上nonce
- 如果nonce 小於已經成功發送交易的nonce那麼就會交易失敗
- 每次交易成功後,獲得的nonce就會相比之前的交易nonce多1 (其實交易就是自增的)
- 如果nonce大於現有交易,那麼當前nonce的交易會等待前面的交易完成
單錢包實現多筆交易同時發送:
- 如果是內部賬戶,可以使用自己維護nonce自增的方式
- 使用 DefaultBlockParameterName.PENDING方式 ,一般來說這種方式能獲取pending 交易的nonce.從而實現交易nonce自增
String address = /* 發送交易的地址 */;
BigInteger nonce = web3j.ethGetTransactionCount(address , DefaultBlockParameterName.PENDING).send().getTransactionCount();
如果使用web3j封裝的方法進行交易,你根本就不知道TxHash,而且很容易出現網絡超時的錯誤。而且當你發送多筆交易後,你根本就不知道自己有沒有給那個地址打過幣。
所以自己維護TXHash是非常重要的,可以保證自己能正確的發送交易 。而且可以自己檢查交易狀態。
獲取TXHash
普通以太交易獲取TxHash的方式
public EthSendTransaction ethSendTransaction(BigInteger gasPrice, Credentials credentials,String toAddress, BigInteger nonce, String hexData, BigInteger value) throws IOException {
byte[] signedMessage = TransactionEncoder.signMessage(
RawTransaction.createTransaction(
nonce,
gasPrice, gasLimit(),
toAddress,
value,
hexData == null ? "" : hexData
),
credentials
);
String hexValue = Numeric.toHexString(signedMessage);
EthSendTransaction transactionHash = web3j.ethSendRawTransaction(hexValue).send();
// 交易發送失敗
// 會返回錯誤信息的
// 其實web3j只是封裝了以太坊的接口
if (transactionHash.hasError()) {
logger.error("transactionHash error -> code :{} \n message:{} \n data:{}", transactionHash.getError().getCode(), transactionHash.getError().getMessage(), transactionHash.getError().getData());
return null;
}
// 這個就是TXHash 可以通過這個查詢交易狀態
String txHash = transactionHash.getTransactionHash()
return transactionHash;
}
代幣發送方法
protected EthSendTransaction sendErc20Transfer(Credentials credentials,String toAddress,BigInteger tokens, BigInteger gasPrice, BigInteger nonce) throws IOException {
String erc20Address = /* 合約地址 */;
// 看web3j生成的合約怎麼實現的交易方法
// 複製粘貼過來就可以了
Function function = new Function(
"transfer",
Arrays.asList(new Address(toAddress), new Uint256(tokens)),
Collections.emptyList());
RawTransaction transaction = RawTransaction.createTransaction(
nonce,
gasPrice, gasLimit(),
erc20Address ,
BigInteger.ZERO,
FunctionEncoder.encode(function));
String hexValue = Numeric.toHexString(TransactionEncoder.signMessage(transaction, credentials));
EthSendTransaction transactionHash = web3j.ethSendRawTransaction(hexValue).send();
if (transactionHash.hasError()) {
logger.error("transactionHash error -> code :{} \n message:{} \n data:{}", transactionHash.getError().getCode(), transactionHash.getError().getMessage(), transactionHash.getError().getData());
return null;
}
return transactionHash;
}
檢查TxHash
protected void check(Transaction transaction) {
try {
EthGetTransactionReceipt ethGetTransactionReceipt = web3j.ethGetTransactionReceipt(transaction.getTxHash()).send();
TransactionReceipt result = ethGetTransactionReceipt.getResult();
if (result != null) {
if (result.isStatusOK()) {
// 交易成功
// 可以獲取到交易信息
} else {
// 交易失敗
// 錯誤信息
String errorMsg = String.format(
"Transaction has failed with status: %s. "
+ "Gas used: %d. (not-enough gas?)",
result.getStatus(),
result.getGasUsed())
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
有了以上的這些,你就可以自己維護自己的交易。交易有無問題也可已直接上 https://etherscan.io/ 查詢交易tx
分享個獲取當前時間 安全gas 的api 免費接口
https://ethgasstation.info/json/ethgasAPI.json