JAVA 离线签名-生成波场地址
/**
* 快捷生成Trx地址
* @return
* @throws InvalidAlgorithmParameterException
* @throws NoSuchAlgorithmException
* @throws NoSuchProviderException
*/
public static Map<String, Object> newAddress() throws InvalidAlgorithmParameterException, NoSuchAlgorithmException, NoSuchProviderException {
HashMap<String, Object> map = new HashMap<>();
ECKeyPair ecKeyPair = Keys.createEcKeyPair();
String address = "41" + Keys.getAddress(ecKeyPair);
String privatekey = ecKeyPair.getPrivateKey().toString(16);
if(privatekey.length() < privateLength){
for(int i = 0 ; i < privateLength - privatekey.length() ; i++){
privatekey = ""+"0"+privatekey;
}
}
String publickey = ecKeyPair.getPublicKey().toString(16);
map.put("address", address);
map.put("private", privatekey);
map.put("public", publickey);
return map;
}
/**
* 转换地址,TGtiQ5uQzw3Z3ni3EC 转成 41 类型的地址
*
* @param addressT
* @return
*/
public static String toHexString(String addressT) {
return ByteArray.toHexString(decodeFromBase58Check(addressT));
}
/**
* 转换地址,415694e6807bf4685fb6 转成 TGtiQ5uQzw3Z3ni3EC 类型的地址
*
* @param addressStart41
* @return
*/
public static String fromHexString(String addressStart41) {
return encode58Check(ByteArray.fromHexString(addressStart41));
}
/**
* 查询trx的代币余额
*
* @param contractAddress 代币的合约地址
* @param address 要查询的地址
* @return 代币数量
*/
public BigDecimal getTokenBalance(String contractAddress, String address) throws Exception {
String method = "balanceOf(address)";
String contract = TronAddress.toHexString(contractAddress);
String parameter = fill_zero(TronAddress.toHexString(address));
String ownerAddress = TronAddress.toHexString(address);
JSONObject result = TriggersmartContract(contract, method, parameter, ownerAddress);
Object constant_result = result.getJSONArray("constant_result").get(0);
if (constant_result == null)
return new BigDecimal(0);
Integer decimals = decimals(contractAddress, address);
BigDecimal balance = new BigDecimal(new BigInteger(constant_result.toString(), 16).toString()).divide(new BigDecimal(BigInteger.valueOf(10).pow(decimals)), 8, RoundingMode.DOWN);
return balance;
}
/**
* 获取TRX余额
*
* @param address 地址
* @return
* @throws Exception
*/
public static BigDecimal getBalance(String address) throws Exception {
JSONObject requestBody = new JSONObject();
requestBody.put("address", address);
requestBody.put("visible", true);
HttpResponse httpResponse = HttpClientUtil.httpPostJson(TronHttpUrl + TronCode_API.TRXBalance, requestBody.toString(), new HttpOptions(1, 5000));
JSONObject result = (JSONObject) HttpClientUtil.doResult(httpResponse);
if (result.containsKey("Error"))
return new BigDecimal(0);
String balance = result.getString("balance");
BigDecimal trxBalance = new BigDecimal(balance).divide(new BigDecimal(BigInteger.valueOf(10).pow(6)), 8, RoundingMode.DOWN);
return trxBalance;
}
/**
* 获取合约的单位
*
* @param contractAddress 合约地址
* @param address 拥有者地址
* @return
* @throws Exception
*/
public static Integer decimals(String contractAddress, String address) throws Exception {
String method = "decimals()";
contractAddress = TronAddress.toHexString(contractAddress);
String parameter = fill_zero(TronAddress.toHexString(address));
String ownerAddress = TronAddress.toHexString(address);
JSONObject result = TriggersmartContract(contractAddress, method, parameter, ownerAddress);
Object constant_result = result.getJSONArray("constant_result").get(0);
if (constant_result == null)
return 0;
BigInteger decimals = new BigInteger(constant_result.toString(), 16);
return Integer.parseInt(decimals.toString());
}
/**
* 调用智能合约
*
* @param contractAddress 合约地址
* @param method 方法名
* @param parameter parameter的编码需要根据合约的ABI规则
* @param ownerAddress 拥有者地址
* @return
* @throws Exception
*/
private static JSONObject TriggersmartContract(String contractAddress, String method, String parameter, String ownerAddress) throws Exception {
JSONObject requestBody = new JSONObject();
requestBody.put("contract_address", contractAddress);
requestBody.put("function_selector", method);
requestBody.put("parameter", parameter);
requestBody.put("owner_address", ownerAddress);
HttpResponse httpResponse = HttpClientUtil.httpPostJson(TronHttpUrl + TronCode_API.TRCTOokenBalance, requestBody.toString(), new HttpOptions(1, 5000));
JSONObject result = (JSONObject) HttpClientUtil.doResult(httpResponse);
return result;
}
/**
* 交易TRC20
*
* @param fromAddress 转账地址
* @param privateKey
* @param contractAddress 合约地址
* @param toAddress 入账地址
* @param amount 金额
* @return
* @throws Exception
*/
public static TronResult TRC20signTransaction(String fromAddress, String privateKey, String contractAddress, String toAddress, BigDecimal amount) throws Exception {
byte[] privateBytes = ByteArray.fromHexString(privateKey);
byte[] fromAddressBytes = decodeFromBase58Check(fromAddress);
toAddress = TronAddress.toHexString(toAddress);
byte[] contractAddressBytes = decodeFromBase58Check(contractAddress);
Integer decimals = decimals(contractAddress, fromAddress);
amount = amount.multiply(new BigDecimal(BigInteger.valueOf(10).pow(decimals)));
System.out.println(amount.toBigInteger());
Function transfer = new Function(
"transfer",
Arrays.asList(new Address(toAddress.substring(2)), new Uint256(amount.toBigInteger())),
Arrays.asList(new TypeReference<Bool>() {
})
);
Contract.TriggerSmartContract.Builder build = Trc20Construct.build(transfer, fromAddressBytes, contractAddressBytes);
Protocol.Transaction transaction = Trc20Construct.createTransaction(build, Protocol.Transaction.Contract.ContractType.TriggerSmartContract, 10000000l);
byte[] transactionByte = transaction.toByteArray();
byte[] signTransaction = signTransaction(transactionByte, privateBytes);
TronResult tronResult = SendTransaction(signTransaction);
return tronResult;
}
/**
* 交易 TRX
*
* @param fromAddress 出账地址
* @param privateKey
* @param toAddress 入账地址
* @param amount 金额
* @return
* @throws Exception
*/
public static TronResult signTRXTransaction(String fromAddress, String privateKey, String toAddress, BigDecimal amount) throws Exception {
byte[] privateBytes = ByteArray.fromHexString(privateKey);
byte[] fromAddressBytes = decodeFromBase58Check(fromAddress);
byte[] toAddressBytes = decodeFromBase58Check(toAddress);
long value = amount.multiply(new BigDecimal(BigInteger.valueOf(10).pow(6))).toBigInteger().longValue();
Protocol.Transaction contractTransaction = TRXConstruct.createTransferContractTransaction(fromAddressBytes, toAddressBytes, value);
byte[] bytes = contractTransaction.toByteArray();
byte[] signTransaction = signTransaction(bytes, privateBytes);
TronResult tronResult = SendTransaction(signTransaction);
System.out.println(tronResult);
return tronResult;
}
/**
* 获取最新区块的信息
*
* @return
* @throws Exception
*/
public static JSONObject NowBlock() throws Exception {
JSONObject block = new JSONObject();
HttpResponse response = HttpClientUtil.httpPost(new HttpRequest(TronHttpUrl + TronCode_API.GetNowBlock, null, null));
System.out.println(response);
JSONObject result = (JSONObject) HttpClientUtil.doResult(response);
String blockID = result.getString("blockID");
Long timestamp = result.getJSONObject("block_header").getJSONObject("raw_data").getLong("timestamp");
Long number = result.getJSONObject("block_header").getJSONObject("raw_data").getLong("number");
block.put("blockID", blockID);
block.put("timestamp", timestamp);
block.put("number", number);
return block;
}
/**
* 交易签名
*
* @param transactionBytes 待签名数据
* @param privateKey 交易创建者私钥
* @return 签名后的数据
* @throws InvalidProtocolBufferException 异常
*/
public static byte[] signTransaction(byte[] transactionBytes, byte[] privateKey) throws InvalidProtocolBufferException {
Protocol.Transaction transaction = Protocol.Transaction.parseFrom(transactionBytes);
byte[] rawData = transaction.getRawData().toByteArray();
byte[] hash = Sha256Hash.hash(rawData);
ECKey ecKey = ECKey.fromPrivate(privateKey);
byte[] sign = ecKey.sign(hash).toByteArray();
return transaction.toBuilder().addSignature(ByteString.copyFrom(sign)).build().toByteArray();
}
/**
* 广播交易
*
* @param sign 签名后的信息
* @return
* @throws Exception
*/
public static TronResult SendTransaction(byte[] sign) throws Exception {
String toHexString = ByteArray.toHexString(sign);
JSONObject requestBody = new JSONObject();
requestBody.put("transaction", toHexString);
HttpResponse httpResponse = HttpClientUtil.httpPostJson(TronHttpUrl + TronCode_API.Send, requestBody.toString(), new HttpOptions(1, 5000));
JSONObject result = (JSONObject) HttpClientUtil.doResult(httpResponse);
boolean status = result.getBoolean("result");
String code = result.getString("code");
String hash = result.getString("txid");
String message = result.getString("message");
TronResult tronResult = new TronResult(hash, status, code, message);
return tronResult;
}
/**
* 补0到64位
*
* @param input
* @return
*/
public static String fill_zero(String input) {
int strLen = input.length();
StringBuffer sb = null;
while (strLen < 64) {
sb = new StringBuffer();
sb.append("0").append(input);// 左补0
input = sb.toString();
strLen = input.length();
}
return input;
}
/**
* 根据hash获取交易FEE情况
*
* @param Hash hash
* @return
* @throws Exception
*/
public static JSONObject GetTransactionInfoById(String Hash) throws Exception {
JSONObject requestBody = new JSONObject();
BigDecimal fee = new BigDecimal(0);
requestBody.put("value", Hash);
HttpResponse httpResponse = HttpClientUtil.httpPostJson(TronHttpUrl + TronCode_API.GetTransactionInfoById, requestBody.toString(), new HttpOptions(1, 5000));
Object doResult = HttpClientUtil.doResult(httpResponse);
JSONObject obj = JSONObject.fromObject(doResult);
return obj;
}
/**
* 根据hash获取交易状态
*
* @param Hash hash
* @return
* @throws Exception
*/
public static JSONObject GetTransactionById(String Hash) throws Exception {
JSONObject requestBody = new JSONObject();
BigDecimal fee = new BigDecimal(0);
requestBody.put("value", Hash);
requestBody.put("visible", true);
HttpResponse httpResponse = HttpClientUtil.httpPostJson(TronHttpUrl + TronCode_API.GetTransactionById, requestBody.toString(), new HttpOptions(1, 5000));
Object doResult = HttpClientUtil.doResult(httpResponse);
JSONObject obj = JSONObject.fromObject(doResult);
return obj;
}