public class BitUtil {
public static Object signBTCTransactionData(List<UnSpentBTC> unSpentBTCList, WalletModel walletModel, String to, long value, long fee) throws Exception {
NetworkParameters networkParameters = Getnetparams.GetNetworkParams();
Transaction transaction = new Transaction(networkParameters);
long totalMoney = 0;
List<UTXO> utxos = new ArrayList<>();
long myfee = 34*2+10;
long halfHourFee = Long.parseLong(JSONObject.parseObject(HttpUtils.sendGet("https://bitcoinfees.earn.com/api/v1/fees/recommended","")).getString("hourFee"));
// System.out.println(jsStr.getString("halfHourFee"));
long Input = 0;
long transfee=0;
for (UnSpentBTC us : unSpentBTCList) {
if (totalMoney >= value + (myfee+ Input * 148)*halfHourFee) {
transfee = (myfee+ Input * 148)*halfHourFee;
break;
}
UTXO utxo = new UTXO(Sha256Hash.wrap(us.getTxid()), us.getVout(), Coin.valueOf(us.getSatoshis()),
us.getHeight(), false, new Script(Hex.decode(us.getScriptPubKey())));
utxos.add(utxo);
totalMoney += us.getSatoshis();
Input++;
}
transaction.addOutput(Coin.valueOf(value), Address.fromBase58(networkParameters, to));
// transaction.
//消费列表总金额 - 已经转账的金额 - 手续费 就等于需要返回给自己的金额了
long balance = totalMoney - value - ((myfee+ Input * 148)*halfHourFee);
//输出-转给自己
if (balance > 0) {
transaction.addOutput(Coin.valueOf(balance), Address.fromBase58(networkParameters, walletModel.getAddress()));
}
//输入未消费列表项
for (UTXO utxo : utxos) {
TransactionOutPoint outPoint = new TransactionOutPoint(networkParameters, utxo.getIndex(), utxo.getHash());
DeterministicKey key = AddressUtils.getDeterministicKey(walletModel.getSeedCode(), walletModel.getPassphrase(), walletModel.getKeyPath());
transaction.addSignedInput(outPoint, ScriptBuilder.createOutputScript(new Address(networkParameters, key.getPubKeyHash())), key, Transaction.SigHash.ALL, true);
}
Cardetails cardetails = new Cardetails(transaction.getHash().toString(),Hex.toHexString(transaction.bitcoinSerialize()),Long.toString(transfee));
return cardetails;
}
}
Cardetails 是我定义的一个类获得hash和rawcode还有fee传出去
可能会有人疑问手续费为什么这么算的 ,大家可参考这一篇文章BTC手续费计算
List<UnSpentBTC>是我从RPC获取的UTXO自己构造的
WalletModel 是一个根据助记词生成BIP39的私钥和地址的类,可以做多币种, 大家可以自己写或者参考HD钱包的
附带上pib助记词生成校验网址BIP
助记词如何生成可以参考我写的这个
public class MnemonicUtil {
/**
* 生成12个助记词
*
* @return
* @throws IOException
* @throws MnemonicException.MnemonicLengthException
*/
public static List<String> getWordList() throws IOException, MnemonicException.MnemonicLengthException {
MnemonicCode mnemonicCode = new MnemonicCode();
SecureRandom secureRandom = new SecureRandom();
/**必须是被4整除*/
byte[] initialEntropy = new byte[16];
secureRandom.nextBytes(initialEntropy);
return mnemonicCode.toMnemonic(initialEntropy);
}
}
@Test
public void RandAccount() throws Exception {
//随机生成助记词 根据助记词生成各个地址。切记要记住助记词
List<String> mnemonicList = MnemonicUtil.getWordList();
String MyMnemonic = StringUtils.join(mnemonicList," ");
System.out.println(MyMnemonic);
}
记得pom导入bitcoinj14版本