最近有个项目需要用到波场链的授权转账,找了各种文档资料都没有详细说明,因为做交易所的时候有一个功能叫授权转账,比如我们充值到交易所的充值地址,其实当交易所创建这个充值地址的时候会调用合约approve方法把当前地址 *** 作权限授权给交易所的热钱包来 *** 作当前充值地址。在参考别人转账代码的基础上实现了transferFrom功能,自己也研究了1周才搞定,给后来人少走的弯路吧
下来来代码
public static final String SUCCESS_STATUS = "SUCCESS" ;
public static final String TRANSFER_TYPE = "TransferContract" ;
public static final int HEX_ADDRESS_SIZE = 21;
public static final byte ADD_PRE_FIX_BYTE_TESTNET = (byte) 0xa0; //a0 + address
@Autowired
private RestTemplate restTemplate;
private static SecureRandom random = new SecureRandom();
private static final Integer PRECIS=18;
/**
* trc20合约地址 这个是USDT代币
*/
private String contract = "TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t";
/**
* TRX主网
*/
private static final String tronUrl = "https://api.trongrid.io";
private static final String WALLET_URL="https://api.trongrid.io";
private static final long feeLimit=1000000L;
/**
* 代币精度
*/
//token的精度 就是小数点后面有多少位小数 然后1后面加多少个0就可以
private static final BigDecimal decimal = new BigDecimal("1000000");
查询余额
public BigDecimal usdtBalanceOf(String address) {
return balanceOf(contract,address);
}
public String getTransactionById(String txId){
Map param = new HashMap<>();
param.put("value", txId);
String url=tronUrl + "/wallet/gettransactionbyid";
String jsonStr =restTemplate.postForEntity(url,param, String.class).getBody();
return jsonStr;
}
/**
* 查询tron币数量
*
* @param address
* @return
*/
public BigDecimal balanceOfTron(String address) {
final BigDecimal decimal = new BigDecimal("1000000");
final int accuracy = 6;//六位小数
Map param = new HashMap<>();
param.put("address", castHexAddress(address));
String url=tronUrl + "/wallet/getaccount";
JSONObject obj = restTemplate.postForEntity(url,param,JSONObject.class).getBody();
if (obj != null) {
BigInteger balance = obj.getBigInteger("balance");
if(balance == null) balance = BigInteger.ZERO;
return new BigDecimal(balance).divide(decimal, accuracy, RoundingMode.FLOOR);
}
return BigDecimal.ZERO;
}
/**
* 查询额度
*
* @param contract 合约地址
* @param address 查询地址
* @return
*/
public BigDecimal balanceOf(String contract, String address) {
String hexAddress = address;
if (address.startsWith("T")) {
hexAddress = TronUtils.toHexAddress(address);
}
String hexContract = contract;
if (contract.startsWith("T")) {
hexContract = TronUtils.toHexAddress(contract);
}
TriggerSmartContract.Param param = new TriggerSmartContract.Param();
param.setContract_address(hexContract);
param.setOwner_address(hexAddress);
param.setFunction_selector("balanceOf(address)");
String addressParam = addZero(hexAddress.substring(2), 64);
param.setParameter(addressParam);
String url=tronUrl + "/wallet/triggersmartcontract";
TriggerSmartContract.Result result = restTemplate.postForEntity(url,param,TriggerSmartContract.Result.class).getBody();
if (result != null && result.isSuccess()) {
String value = result.getConstantResult(0);
if (value != null) {
final int accuracy = 6;//六位小数
return new BigDecimal(value).divide(decimal, accuracy, RoundingMode.FLOOR);
//return new BigInteger(value, 16);
}
}
return BigDecimal.ZERO;
}
public String castHexAddress(String address) {
if (address.startsWith("T")) {
return TronUtils.toHexAddress(address);
}
return address;
}
代币授权转账
/**
* 代币转账 trc20
*
* @param contract
* @param fromAddress
* @param privateKey fromAddress的私钥
* @param amount
* @param toAddress
* @param remark
* @return
*/
public String sendTokenTransformTransaction(String contract,String authAddress, String fromAddress, String privateKey, String amount, String toAddress, String remark) {
try {
String hexFromAddress = castHexAddress(fromAddress);
String hexToAddress = castHexAddress(toAddress);
String hexAuthAddress = castHexAddress(authAddress);
String hexContract = castHexAddress(contract);
BigInteger a = new BigInteger(amount);
if (a.compareTo(BigInteger.ZERO) <= 0) {
log.error("转账失败:额度不符合规则 " + amount);
return null;
}
if (remark == null) {
remark = "";
}
TriggerSmartContract.Param param = new TriggerSmartContract.Param();
param.setOwner_address(hexAuthAddress);
param.setContract_address(hexContract);
param.setFee_limit(6000000L);
// param.setFunction_selector("transfer(address,uint256)");
param.setFunction_selector("transferFrom(address,address,uint256)");
String fromAddressParam = addZero(hexFromAddress, 64);
String addressParam = addZero(hexToAddress, 64);
String amountParam = addZero(a.toString(16), 64);
param.setParameter(fromAddressParam+ addressParam + amountParam);
log.info("创建交易参数:" + JSONObject.toJSONString(param));
String url=tronUrl + "/wallet/triggersmartcontract";
String json = restTemplate.postForEntity(url,param,String.class).getBody();
log.info("创建交易返回:" + json);
TriggerSmartContract.Result obj=JSON.parseObject(json,TriggerSmartContract.Result.class);
if (!obj.isSuccess()) {
log.error("创建交易失败");
return null;
}
Transaction transaction= TronUtils.packTransaction(JSON.toJSONString(obj.getTransaction()));
byte[] transaction4 = signTransaction2Byte(transaction.toByteArray(), ByteArray.fromHexString(privateKey));
com.alibaba.fastjson.JSONObject transactionObj = org.tron.common.utils.Utils.printTransactionToJSON(Transaction.parseFrom(transaction4), false);
JSONObject jsonObject = restTemplate.postForEntity(tronUrl+"/wallet/broadcasttransaction",transactionObj, JSONObject.class).getBody();
log.info("广播交易结果:" + jsonObject.toJSONString());
if (jsonObject != null) {
Object result = jsonObject.get("result");
if (result instanceof Boolean) {
if ((boolean) result) {
return (String) jsonObject.get("txid");
}
}
}
} catch (Throwable t) {
log.error(t.getMessage(), t);
}
return null;
}
代币转账
/**
* 代币转账 trc20
*
* @param contract
* @param fromAddress
* @param privateKey fromAddress的私钥
* @param amount
* @param toAddress
* @param remark
* @return
*/
public String sendTokenTransaction(String contract, String fromAddress, String privateKey, String amount, String toAddress, String remark) {
try {
String hexFromAddress = castHexAddress(fromAddress);
String hexToAddress = castHexAddress(toAddress);
String hexContract = castHexAddress(contract);
BigInteger a = new BigInteger(amount);
if (a.compareTo(BigInteger.ZERO) <= 0) {
log.error("转账失败:额度不符合规则 " + amount);
return null;
}
if (remark == null) {
remark = "";
}
TriggerSmartContract.Param param = new TriggerSmartContract.Param();
param.setOwner_address(hexFromAddress);
param.setContract_address(hexContract);
param.setFee_limit(1000000L);
param.setFunction_selector("transfer(address,uint256)");
String addressParam = addZero(hexToAddress, 64);
String amountParam = addZero(a.toString(16), 64);
param.setParameter(addressParam + amountParam);
log.info("创建交易参数:" + JSONObject.toJSONString(param));
String url=tronUrl + "/wallet/triggersmartcontract";
String json = restTemplate.postForEntity(url,param,String.class).getBody();
TriggerSmartContract.Result obj=JSON.parseObject(json,TriggerSmartContract.Result.class);
if (!obj.isSuccess()) {
log.error("创建交易失败");
return null;
}
Transaction transaction= TronUtils.packTransaction(JSON.toJSONString(obj.getTransaction()));
byte[] transaction4 = signTransaction2Byte(transaction.toByteArray(), ByteArray.fromHexString(privateKey));
com.alibaba.fastjson.JSONObject transactionObj = org.tron.common.utils.Utils.printTransactionToJSON(Transaction.parseFrom(transaction4), false);
JSONObject jsonObject = restTemplate.postForEntity(tronUrl+"/wallet/broadcasttransaction",transactionObj, JSONObject.class).getBody();
// JSONObject rea = restTemplate.postForEntity(tronUrl+"/wallet/broadcasttransaction",signParam, JSONObject.class).getBody();
log.info("广播交易结果:" + jsonObject.toJSONString());
if (jsonObject != null) {
Object result = jsonObject.get("result");
if (result instanceof Boolean) {
if ((boolean) result) {
return (String) jsonObject.get("txid");
}
}
}
} catch (Throwable t) {
log.error(t.getMessage(), t);
}
return null;
}
/**
* 补充0到64个字节
*
* @param dt
* @return
*/
private String addZero(String dt, int length) {
StringBuilder builder = new StringBuilder();
final int count = length;
int zeroAmount = count - dt.length();
for (int i = 0; i < zeroAmount; i++) {
builder.append("0");
}
builder.append(dt);
return builder.toString();
}
创建地址
/**具体方法
*/
public Map createAddress() {
ECKey eCkey = new ECKey(random);
String privateKey = ByteArray.toHexString(eCkey.getPrivKeyBytes());
byte[] addressBytes = eCkey.getAddress();
String hexAddress = ByteArray.toHexString(addressBytes);
Map addressInfo = new HashMap<>(3);
addressInfo.put("address", toViewAddress(hexAddress));
addressInfo.put("hexAddress", hexAddress);
addressInfo.put("privateKey", privateKey);
//String privateKeyBase58 = org.spongycastle.util.encoders.Hex.e(base58Str);
String privateKeyBase58= encode58Check(eCkey.getPrivKeyBytes());
addressInfo.put("privateKeyBase58", privateKeyBase58);
return addressInfo;
}
代码下载地址:
GitHub - kingson88/trx-usdtContribute to kingson88/trx-usdt development by creating an account on GitHub.https://github.com/kingson88/trx-usdt
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)