Build transaction locally

package org.tron.demo;

import com.google.protobuf.Any;

import com.google.protobuf.ByteString;

import com.google.protobuf.InvalidProtocolBufferException;

import org.tron.api.GrpcAPI.Return;

import org.tron.api.GrpcAPI.TransactionExtention;

import org.tron.common.crypto.ECKey;

import org.tron.common.crypto.Sha256Sm3Hash;

import org.tron.common.utils.ByteArray;

import org.tron.core.exception.CancelException;

import org.tron.protos.Contract;

import org.tron.protos.Protocol.Block;

import org.tron.protos.Protocol.Transaction;

import org.tron.walletserver.WalletApi;

import java.util.Arrays;

public class TransactionSignDemo {

/* Set reference block data*/

public static Transaction setReference(Transaction transaction, Block newestBlock) {

long blockHeight = newestBlock.getBlockHeader().getRawData().getNumber();

byte[] blockHash = getBlockHash(newestBlock).getBytes();

byte[] refBlockNum = ByteArray.fromLong(blockHeight);

Transaction.raw rawData = transaction.getRawData().toBuilder()

.setRefBlockHash(ByteString.copyFrom(ByteArray.subArray(blockHash, 8, 16)))

.setRefBlockBytes(ByteString.copyFrom(ByteArray.subArray(refBlockNum, 6, 8)))

.setRefBlockNum(blockHeight)

.build();

return transaction.toBuilder().setRawData(rawData).build();

}

public static Sha256Sm3Hash getBlockHash(Block block) {

return Sha256Sm3Hash.of(block.getBlockHeader().getRawData().toByteArray());

}

public static String getTransactionHash(Transaction transaction) {

String txid = ByteArray.toHexString(Sha256Sm3Hash.hash(transaction.getRawData().toByteArray()));

return txid;

}

public static Transaction createTransaction(byte[] from, byte[] to, long amount) {

Transaction.Builder transactionBuilder = Transaction.newBuilder();

Block newestBlock = WalletApi.getBlock(-1);

/*设置合约内部数据*/

Transaction.Contract.Builder contractBuilder = Transaction.Contract.newBuilder();

Contract.TransferContract.Builder transferContractBuilder =

Contract.TransferContract.newBuilder();

transferContractBuilder.setAmount(amount);

ByteString bsTo = ByteString.copyFrom(to);

ByteString bsOwner = ByteString.copyFrom(from);

transferContractBuilder.setToAddress(bsTo);

transferContractBuilder.setOwnerAddress(bsOwner);

try {

Any any = Any.pack(transferContractBuilder.build());

contractBuilder.setParameter(any);

} catch (Exception e) {

return null;

}

/* Set memo, transaction expiration time and other data*/

contractBuilder.setType(Transaction.Contract.ContractType.TransferContract);

transactionBuilder.getRawDataBuilder().addContract(contractBuilder)

.setTimestamp(System.currentTimeMillis())

.setExpiration(newestBlock.getBlockHeader().getRawData().getTimestamp() + 10 * 60 * 60 * 1000)

.setData(ByteString.copyFromUtf8("memo"))

.setScripts(ByteString.copyFromUtf8("scripts"));

Transaction transaction = transactionBuilder.build();

Transaction refTransaction = setReference(transaction, newestBlock);

return refTransaction;

}

private static byte[] signTransaction2Byte(byte[] transaction, byte[] privateKey)

throws InvalidProtocolBufferException {

ECKey ecKey = ECKey.fromPrivate(privateKey);

Transaction transaction1 = Transaction.parseFrom(transaction);

byte[] rawdata = transaction1.getRawData().toByteArray();

byte[] hash = Sha256Sm3Hash.hash(rawdata);

byte[] sign = ecKey.sign(hash).toByteArray();

return transaction1.toBuilder().addSignature(ByteString.copyFrom(sign)).build().toByteArray();

}

private static boolean broadcast(byte[] transactionBytes) throws InvalidProtocolBufferException {

return WalletApi.broadcastTransaction(transactionBytes);

}

public static void main(String[] args) throws InvalidProtocolBufferException, CancelException {

String privateStr = "da146374a75310b9666e834ee4ad0866d6f4035967bfc76217c5a495fff9f0d0";

byte[] privateBytes = ByteArray.fromHexString(privateStr);

ECKey ecKey = ECKey.fromPrivate(privateBytes);

byte[] from = ecKey.getAddress();

byte[] to = WalletApi.decodeFromBase58Check("TN9RRaXkCFtTXRso2GdTZxSxxwufzxLQPP");

long amount = 100_000_000L; // 100 TRX, api only receive trx in Sun, and 1 trx = 1000000 Sun

Transaction transaction = createTransaction(from, to, amount);

byte[] transactionBytes = transaction.toByteArray();

byte[] transaction4 = signTransaction2Byte(transactionBytes, privateBytes);

boolean result = broadcast(transaction4);

System.out.println(result);

}

}

Last updated

Was this helpful?