波场区块链浏览器:https://tronscan.org/#/
API:https://cn.developers.tron.network/reference#reference-getting-started
Github上的API:https://github.com/tronscan/tronscan-frontend/blob/dev2019/document/api.md
针对Trx的离线签名(TransferContract), trc10和trc20根据Protoc协议中构造Transaction中的TransferAssetContract和TriggerSmartContract签名即可
代码直接在官方钱包wallet-cli项目中写的demo
package org.tron.demo;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.google.protobuf.Any;
import com.google.protobuf.ByteString;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.tron.common.crypto.ECKey;
import org.tron.common.crypto.Sha256Hash;
import org.tron.common.utils.ByteArray;
import org.tron.common.utils.TransactionUtils;
import org.tron.protos.Contract;
import org.tron.walletserver.WalletApi;
import org.tron.protos.Protocol.Transaction;
import org.tron.protos.Protocol.BlockHeader;
/*
author:hht
email:593432577@qq.com
des:Tron波场离线签名
*/
public class TronSignDemo {
public static void main(String[] args) {
String privateStr = "private key";
byte[] privateByte = ByteArray.fromHexString(privateStr);
ECKey ecKey = ECKey.fromPrivate(privateByte);
byte[] from = ecKey.getAddress();
byte[] to = WalletApi.decodeFromBase58Check("address");
System.out.println("from::"+ByteArray.toHexString(from));
System.out.println("to::"+ByteArray.toHexString(to));
long amount = 321;
Transaction transaction = createTransaction(from,to,amount);
byte[] transactionBytes = transaction.toByteArray();
System.out.println(ByteArray.toHexString(transactionBytes));
Transaction transactionSign = TransactionUtils.sign(transaction,ecKey);
System.out.println("transactionSign ::::: " + ByteArray.toHexString(transactionSign.toByteArray()));
//g广播交易
postBroadcast(ByteArray.toHexString(transactionSign.toByteArray()));
}
//构造交易 参考官网Protoc协议
public static Transaction createTransaction(byte[] from,byte[] to,long amount){
Transaction.Builder transactionBuilder = Transaction.newBuilder();
Transaction.Contract.Builder contractBuilder = Transaction.Contract.newBuilder();
Contract.TransferContract.Builder transferContractBuidler = Contract.TransferContract.newBuilder();
transferContractBuidler.setOwnerAddress(ByteString.copyFrom(from));
transferContractBuidler.setToAddress(ByteString.copyFrom(to));
transferContractBuidler.setAmount(amount);
Any any = Any.pack(transferContractBuidler.build());
contractBuilder.setParameter(any);
contractBuilder.setType(Transaction.Contract.ContractType.TransferContract);
transactionBuilder.getRawDataBuilder().addContract(contractBuilder)
.setTimestamp(System.currentTimeMillis())
.setExpiration(System.currentTimeMillis()+10*60*60*1000);
BlockHeader.raw raw = getNowBlock();
byte[] blockHash = Sha256Hash.of(raw.toByteArray()).getBytes();
byte[] blockNum = ByteArray.fromLong(raw.getNumber());
System.out.println("block::::"+ByteArray.toHexString(blockHash));
transactionBuilder.getRawDataBuilder()
.setRefBlockHash(ByteString.copyFrom(ByteArray.subArray(blockHash,8,16)))
.setRefBlockBytes(ByteString.copyFrom(ByteArray.subArray(blockNum,6,8)));
return transactionBuilder.build();
}
public static BlockHeader.raw getNowBlock(){
//使用RPC接口获取BlockHeader
// Protocol.Block newestBlock = WalletApi.getBlock(-1);
// return newestBlock.getBlockHeader().getRawData();
//使用get请求获取blockHeader 目前只找到这个这个接口
//https://apilist.tronscan.org/api/block/latest 这个接口获取的数据 少个version参数,打包广播的时候会出现 TAPOS_ERROR
String nowBlockStr = getHttp("https://api.trongrid.io/wallet/getnowblock");
JSONObject jsonObject = JSON.parseObject(nowBlockStr);
String block_header = jsonObject.getString("block_header");
JSONObject raw_data = JSON.parseObject(block_header);
JSONObject data = JSON.parseObject(raw_data.getString("raw_data"));
BlockHeader.raw.Builder rawBuidler = BlockHeader.raw.newBuilder();
rawBuidler.setNumber(data.getLong("number"));
rawBuidler.setTxTrieRoot(ByteString.copyFrom(ByteArray.fromHexString(data.getString("txTrieRoot"))));
rawBuidler.setWitnessAddress(ByteString.copyFrom(ByteArray.fromHexString(data.getString("witness_address"))));
rawBuidler.setParentHash(ByteString.copyFrom(ByteArray.fromHexString(data.getString("parentHash"))));
rawBuidler.setTimestamp(data.getLong("timestamp"));
rawBuidler.setVersion(data.getIntValue("version"));
return rawBuidler.build();
}
public static String getHttp(String url) {
try {
HttpGet get = new HttpGet((url));
HttpClient client = HttpClients.createDefault();
HttpResponse response = client.execute(get);
HttpEntity entity = response.getEntity();
String result = EntityUtils.toString(entity);
return result;
} catch (Exception e) {
e.printStackTrace();
}
return "";
}
public static String postBroadcast(String sgin){
try {
//广播地址:https://apilist.tronscan.org/api/broadcast
HttpPost post = new HttpPost("https://apilist.tronscan.org/api/broadcast");
post.setEntity(new StringEntity("{\"transaction\":\""+sgin+"\"}"));
HttpClient client = HttpClients.createDefault();
HttpResponse response = client.execute(post);
HttpEntity entity = response.getEntity();
String result = EntityUtils.toString(entity);
System.out.println(result);
return result;
}catch (Exception e){
e.printStackTrace();
}
return "";
}
}