请一定要注意下面三点:
//1.必要情况下可以提高gasPrice 5%-30%左右(做到可以随时动态调整)
//2.nonce需要自己内部维护一份(可以采用redis去维护,每个转账账号维护自己对应的nonce,每次交易成功自增+1,多服情况下记得要加锁处理)
//3.转账账号不要只设置一个,需要要多个账号去实现交易转账(防止链上大量交易排队的情况)
下面是简单例子(未去实现上面注意的三点,自己手动业务处理下即可)
/**NFT批量转账
* @param wallet
* @param headIds
* @param privateKey
* @param contractAddress
* @param coinRpcUrl
* @param chainId
* @return
* @throws Exception
*/
public static String safeBatchTransferFromForNft(String from,String to,JSONArray headIds, String privateKey,String contractAddress, String coinRpcUrl,long chainId) throws Exception {
Web3j web3j = null;
OkHttpClient okHttpClient = null;
String str = null;
try {
okHttpClient = OKHttpUtil.createOkHttpClient();
web3j = Web3j.build(new HttpService(coinRpcUrl, okHttpClient));
//Uint256[] list=new Uint256[headIds.size()];
List<Uint256> li=new java.util.ArrayList<Uint256>();
for(int i=0;i<headIds.size();i++){
// list[i]=new Uint256(new BigInteger(headIds.get(i)+""));
li.add(new Uint256(new BigInteger(headIds.get(i)+"")));
}
BigInteger nonce;
EthGetTransactionCount ethGetTransactionCount = web3j.ethGetTransactionCount(from,
DefaultBlockParameterName.PENDING).send();
if (ethGetTransactionCount == null) {
return null;
}
nonce = ethGetTransactionCount.getTransactionCount();
BigInteger gasPrice;
EthGasPrice ethGasPrice = web3j.ethGasPrice().sendAsync().get();
if (ethGasPrice == null) {
return null;
}
// 加载转账所需的凭证,用私钥
Credentials credentials = Credentials.create(privateKey);
gasPrice = ethGasPrice.getGasPrice();
DynamicArray<Uint256> array = new DynamicArray<Uint256>(Uint256.class , li);
Function function = new Function(BtTradeConstant.safeBatchTransferFromForNft, Arrays.asList(new Address(from),new Address(to),array,DynamicBytes.DEFAULT), Arrays.asList(new TypeReference<Type>() {
}));
String encodedFunction = FunctionEncoder.encode(function);
//获取gas
Transaction transaction = Transaction.createEthCallTransaction(from, contractAddress, encodedFunction);
EthEstimateGas ethEstimateGas=web3j.ethEstimateGas(transaction).sendAsync().get();
BigInteger gas=BigInteger.valueOf(0L);
if(ethEstimateGas.getError()==null){
gas=ethEstimateGas.getAmountUsed();
}else{
throw new Exception(ethEstimateGas.getError().getMessage());
}
// BigInteger gasLimit =BigInteger.valueOf(4000000L);
BigInteger gasLimit=gas.multiply(BigInteger.valueOf(2L));
RawTransaction rawTransaction = RawTransaction.createTransaction(nonce, gasPrice, gasLimit,contractAddress, encodedFunction);
// 签名Transaction
byte[] signMessage = TransactionEncoder.signMessage(rawTransaction, chainId, credentials);
String hexValue = Numeric.toHexString(signMessage);
// 发送交易
EthSendTransaction ethSendTransaction = web3j.ethSendRawTransaction(hexValue).sendAsync().get();
logger.warn("================safeBatchTransferFromForNft结果==" + JSON.toJSONString(ethSendTransaction));
if(ethSendTransaction.getError()==null){
str = ethSendTransaction.getTransactionHash();
}else{
throw new Exception(ethSendTransaction.getError().getMessage());
}
} catch(Exception e){
logger.error("================safeBatchTransferFromForNft异常==",e);
throw new Exception(e.getMessage());
} finally {
if (web3j != null) {
web3j.shutdown();
}
}
return str;
}