tronweb版本请参考 波场trc20转账(tronWeb版本)
发行trc20代币步骤详见 波场(Tron)发行trc20代币(Shasta测试网络)
为了避免私钥泄露,一般都要我们搭建自己的本地节点。
我这里就直接搭建自己的FullNole (Nile测试网) 详细的搭建可以看 波场(Tron)发行trc20代币(Shasta测试网络) 的“写在后面”部分 里面有提及怎么搭建Nile网的FullNode节点
波场官方Api说明
1、只能合约调用API /wallet/triggersmartcontract
2、交易签名api /wallet/gettransactionsign
3、交易广播API /wallet/broadcasttransaction
feign接口
package com.tricky.tron.trc20.feign;
import com.alibaba.fastjson.JSONObject;
import com.tricky.tron.trc20.feign.dt.GetTransactionSign;
import com.tricky.tron.trc20.feign.dt.TriggerSmartContract;
import feign.jackson.JacksonDecoder;
import feign.jackson.JacksonEncoder;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
/**
* tron-full-node接口
*
* @Autor Shadow 2020/10/22
* @Date 2020-10-22 15:36:02
*/
@FeignClient(url = "${tron.url}", name = "tron-node", configuration = {
JacksonEncoder.class, JacksonDecoder.class})
public interface TronFullNodeFeign {
/**
* 只能合约调用接口
*
* @param param
* @return
*/
@PostMapping("/wallet/triggersmartcontract")
TriggerSmartContract.Result triggerSmartContract(@RequestBody TriggerSmartContract.Param param);
/**
* 使用私钥签名交易.(存在安全风险,trongrid已经关闭此接口服务,请使用离线方式或者自己部署的节点)
*
* @param param
* @return
*/
@PostMapping("/wallet/gettransactionsign")
JSONObject getTransactionSign(@RequestBody GetTransactionSign.Param param);
/**
* 广播签名后的交易.
*
* @param rawBody
* @return
*/
@PostMapping("/wallet/broadcasttransaction")
JSONObject broadcastTransaction(@RequestBody Object rawBody);
}
转账的Service
import com.alibaba.fastjson.JSONObject;
import com.tricky.tron.trc20.feign.TronFullNodeFeign;
import com.tricky.tron.trc20.feign.dt.GetTransactionSign;
import com.tricky.tron.trc20.feign.dt.TriggerSmartContract;
import com.tricky.tron.trc20.utils.ByteArray;
import com.tricky.tron.trc20.utils.TronUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import java.math.BigDecimal;
/**
* trc20-service
*
* @Autor Shadow 2020/10/22
* @Date 2020-10-22 15:49:41
*/
@Service
public class Trc20Service {
private static Logger logger = LoggerFactory.getLogger(Trc20Service.class);
@Value("${tron.contract-address}")
private String contractAddress;//hex格式
@Value("${tron.address}")
private String address;//发币地址 hex格式
@Value("${tron.private-key}")
private String privateKey;//私钥
//token的精度 就是小数点后面有多少位小数 然后1后面加多少个0就可以
private static final BigDecimal decimal = new BigDecimal("1000000");
@Autowired
private TronFullNodeFeign feign;
/**
* 发送trc20交易 返回交易id
*
* @param toAddress 收币地址
* @param amount 转出数量
* @param remark 备注
* @return
*/
public String sendTrc20Transaction(String toAddress, String amount, String remark) {
try {
String hexAddress = toAddress;
if (toAddress.startsWith("T")) {
hexAddress = TronUtils.toHexAddress(toAddress);
}
if (StringUtils.isEmpty(hexAddress)) {
logger.error("转账失败:收款地址为空");
return null;
}
if (StringUtils.isEmpty(amount)) {
logger.error("转账失败:额度为空");
return null;
}
BigDecimal a = new BigDecimal(amount);
if (a.compareTo(BigDecimal.ZERO) <= 0) {
logger.error("转账失败:额度不符合规则 " + amount);
return null;
}
if (remark == null) {
remark = "";
}
String params = hexAddress + "@" + amount + "@" + remark;
TriggerSmartContract.Param param = createTriggerSmartContractParam();
param.setFunction_selector("transfer(address,uint256)");
String addressParam = addZero(hexAddress, 64);
String amountParam = addZero(new BigDecimal(amount).multiply(decimal).toBigInteger().toString(16), 64);
param.setParameter(addressParam + amountParam);
logger.info("创建交易参数:" + JSONObject.toJSONString(param));
TriggerSmartContract.Result obj = feign.triggerSmartContract(param);
logger.info("创建交易结果:" + JSONObject.toJSONString(obj));
if (!obj.isSuccess()) {
logger.error("创建交易失败|" + params);
return null;
}
//交易签名
GetTransactionSign.Param signParam = new GetTransactionSign.Param();
TriggerSmartContract.Transaction transaction = obj.getTransaction();
transaction.getRaw_data().put("data", ByteArray.toHexString(remark.getBytes()));
signParam.setTransaction(transaction);
signParam.setPrivateKey(privateKey);
logger.info("签名交易参数:" + JSONObject.toJSONString(signParam));
Object dt = feign.getTransactionSign(signParam);
logger.info("签名交易结果:" + JSONObject.toJSONString(dt));
//广播交易
if (dt != null) {
logger.info("广播交易参数:" + JSONObject.toJSONString(dt));
JSONObject rea = feign.broadcastTransaction(dt);
logger.info("广播交易结果:" + JSONObject.toJSONString(rea));
if (rea != null) {
Object result = rea.get("result");
if (result instanceof Boolean) {
if ((boolean) result) {
return (String) rea.get("txid");
}
}
}
}
} catch (Throwable t) {
logger.error(t.getMessage(), t);
}
return null;
}
/**
* 创建智能合约参数
*
* @return
*/
private TriggerSmartContract.Param createTriggerSmartContractParam() {
TriggerSmartContract.Param tscParam = new TriggerSmartContract.Param();
tscParam.setOwner_address(address);
tscParam.setContract_address(contractAddress);
tscParam.setFee_limit(1000000L);
return tscParam;
}
/**
* 补充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();
}
}
打开页面 http://localhost:3600/zmm/
代码在最后
Nile测试网浏览器
输入上面的交易id 5e1863d83b363f04934d650dd8d8b9acd1d505820102ee2a95a0347e128cb79d
完美 我的备注也看到了
有积分的就在这里下载吧
trc20-转账 如果积分超过15的话,可以留言喊我改一下(这个每下载一次,都会自动增加消耗积分,要手动把它改回去)
如果下载了我的代码的朋友,需要把 setFee_limit 里面的费用提高至少4倍(因为后面波场的这个费用涨了4倍)
demo页面
如果有啥问题 可以评论留言哦~
不喜勿喷
2020-12月记
如果下载了我的代码的朋友,需要把 setFee_limit 里面的费用提高至少4倍(因为后面波场的这个费用涨了4倍)