All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.bitcoin.blockchain.api.builder.TransactionBuilder Maven / Gradle / Ivy

There is a newer version: 1.0.3
Show newest version
package com.bitcoin.blockchain.api.builder;

import com.bccapi.bitlib.StandardTransactionBuilder;
import com.bccapi.bitlib.crypto.InMemoryPrivateKey;
import com.bccapi.bitlib.crypto.PrivateKeyRing;
import com.bccapi.bitlib.crypto.PublicKey;
import com.bccapi.bitlib.crypto.PublicKeyRing;
import com.bccapi.bitlib.model.*;
import com.bitcoin.blockchain.api.domain.*;
import com.bitcoin.blockchain.api.domain.TransactionOutput;
import com.bushidowallet.core.bitcoin.bip32.Derivation;
import com.bushidowallet.core.bitcoin.bip32.ExtendedKey;
import com.bushidowallet.core.bitcoin.bip32.Hash;
import com.bushidowallet.core.bitcoin.bip32.Seed;
import com.bushidowallet.core.crypto.util.ByteUtil;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * Created by Jesion on 2015-03-17.
 */
public class TransactionBuilder {

    private Map utxo;
    private List spendings;
    private V2Key changeKey;
    private Balance balance;
    private String seed;
    private boolean compressedPubKeys;
    private long fee;

    public TransactionBuilder(Map utxo,
                              Balance balance,
                              List spendings,
                              V2Key changeKey,
                              String seed,
                              boolean compressedPubKeys,
                              long fee) {
        this.utxo = utxo;
        this.spendings = spendings;
        this.changeKey = changeKey;
        this.balance = balance;
        this.seed = seed;
        this.compressedPubKeys = compressedPubKeys;
        this.fee = fee;
    }

    public String build() throws Exception {
        Address changeAddress = Address.fromString(changeKey.address);
        StandardTransactionBuilder builder = new StandardTransactionBuilder(NetworkParameters.productionNetwork);
        for (int s = 0; s < spendings.size(); s++) {
            builder.addOutput(Address.fromString(spendings.get(s).receivingAddress), spendings.get(s).value);
        }
        PublicKeyRing pubKeys = new PublicKeyRing();
        PrivateKeyRing privKeys = new PrivateKeyRing();
        TransactionOutputList pendingUTXOs = utxo.get(TransactionStatus.PENDING);
        TransactionOutputList confirmedUTXOs = utxo.get(TransactionStatus.CONFIRMED);
        ExtendedKey root = getRootKey(seed);
        List unspents = new ArrayList();
        UTXOBuilder utxoBuilder = new UTXOBuilder();
        for (int i = 0; i < pendingUTXOs.outputs.size(); i++) {
            TransactionOutput to = pendingUTXOs.outputs.get(i);
            pubKeys.addPublicKey(new PublicKey(ByteUtil.fromHex(to.getKey().publicKeyBytes)), NetworkParameters.productionNetwork);
            ExtendedKey privKey = getDerivedKey(root, to.getKey().account, to.getKey().sequence);
            privKeys.addPrivateKey(new InMemoryPrivateKey(privKey.getWIF(), NetworkParameters.productionNetwork), NetworkParameters.productionNetwork);
            unspents.add(utxoBuilder.build(to.getTxHash(), 0, to.getScriptBytes(), to.getIndex(), to.getValue()));
        }
        for (int j = 0; j < confirmedUTXOs.outputs.size(); j++) {
            TransactionOutput to = confirmedUTXOs.outputs.get(j);
            pubKeys.addPublicKey(new PublicKey(ByteUtil.fromHex(to.getKey().publicKeyBytes)), NetworkParameters.productionNetwork);
            ExtendedKey privKey = getDerivedKey(root, to.getKey().account, to.getKey().sequence);
            privKeys.addPrivateKey(new InMemoryPrivateKey(privKey.getWIF(), NetworkParameters.productionNetwork), NetworkParameters.productionNetwork);
            unspents.add(utxoBuilder.build(to.getTxHash(), 1, to.getScriptBytes(), to.getIndex(), to.getValue()));
        }
        StandardTransactionBuilder.UnsignedTransaction ut = builder.createUnsignedTransaction(unspents, changeAddress, fee, pubKeys, NetworkParameters.productionNetwork);
        StandardTransactionBuilder.SigningRequest[] s = ut.getSignatureInfo();
        List signatures = StandardTransactionBuilder.generateSignatures(s, privKeys);
        com.bccapi.bitlib.model.Transaction tx = StandardTransactionBuilder.finalizeTransaction(ut, signatures);
        return ByteUtil.toHex(tx.toBytes());
    }

    private ExtendedKey getRootKey(String seed) throws Exception {
        byte[] passphraseHash = ByteUtil.fromHex(seed);
        byte[] keyHash = new Hash(passphraseHash).getHmacSHA512(Seed.BITCOIN_SEED);
        return new ExtendedKey(keyHash, compressedPubKeys);
    }

    private ExtendedKey getDerivedKey(ExtendedKey root,
                                      int account,
                                      int sequence) throws Exception {
        Derivation d = new Derivation(root);
        return d.accountKey(0, account, sequence);
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy