Search in sources :

Example 31 with TransactionInput

use of org.bitcoinj.core.TransactionInput in project balzac by balzac-lang.

the class TransactionBuilder method toTransaction.

@Override
public Transaction toTransaction(ECKeyStore keystore) {
    checkState(this.isReady(), "the transaction and all its ancestors are not ready");
    Transaction tx = new Transaction(params);
    // set version
    tx.setVersion(2);
    // inputs
    for (Input input : inputs) {
        if (!input.hasParentTx()) {
            // coinbase transaction
            // script will be set later
            byte[] script = new byte[] {};
            TransactionInput txInput = new TransactionInput(params, tx, script);
            tx.addInput(txInput);
            checkState(txInput.isCoinBase(), "'txInput' is expected to be a coinbase");
        } else {
            ITransactionBuilder parentTransaction2 = input.getParentTx();
            Transaction parentTransaction = parentTransaction2.toTransaction(keystore);
            TransactionOutPoint outPoint = new TransactionOutPoint(params, input.getOutIndex(), parentTransaction);
            // script will be set later
            byte[] script = new byte[] {};
            TransactionInput txInput = new TransactionInput(params, tx, script, outPoint);
            // set checksequenseverify (relative locktime)
            if (input.getLocktime() == UNSET_LOCKTIME) {
                // see BIP-0065
                if (this.locktime != UNSET_LOCKTIME)
                    txInput.setSequenceNumber(TransactionInput.NO_SEQUENCE - 1);
            } else {
                txInput.setSequenceNumber(input.getLocktime());
            }
            // txInput.setScriptSig(input.script.build());
            tx.addInput(txInput);
        }
    }
    // outputs
    for (Output output : outputs) {
        // bind free variables
        OutputScript sb = output.getScript();
        for (String freeVarName : getVariables()) {
            if (sb.hasVariable(freeVarName) && sb.isFree(freeVarName)) {
                sb.bindVariable(freeVarName, this.getValue(freeVarName));
            }
        }
        checkState(sb.isReady(), "script cannot have free variables: " + sb.toString());
        checkState(sb.signatureSize() == 0);
        Script outScript;
        if (sb instanceof P2SHOutputScript) {
            // P2SH
            outScript = ((P2SHOutputScript) sb).getOutputScript();
        } else {
            outScript = sb.build();
        }
        Coin value = Coin.valueOf(output.getValue());
        tx.addOutput(value, outScript);
    }
    // set checklocktime (absolute locktime)
    if (locktime != UNSET_LOCKTIME) {
        tx.setLockTime(locktime);
    }
    // set all the signatures within the input scripts (which are never part of the signature)
    for (int i = 0; i < tx.getInputs().size(); i++) {
        TransactionInput txInput = tx.getInputs().get(i);
        InputScript sb = inputs.get(i).getScript();
        // bind free variables
        for (String freeVarName : getVariables()) {
            if (sb.hasVariable(freeVarName) && sb.isFree(freeVarName)) {
                sb.bindVariable(freeVarName, this.getValue(freeVarName));
            }
        }
        checkState(sb.isReady(), "script cannot have free variables: " + sb.toString());
        byte[] outScript;
        if (txInput.isCoinBase()) {
            outScript = new byte[] {};
        } else {
            if (txInput.getOutpoint().getConnectedOutput().getScriptPubKey().isPayToScriptHash()) {
                checkState(sb instanceof P2SHInputScript, "why not?");
                P2SHInputScript p2shInput = (P2SHInputScript) sb;
                outScript = p2shInput.getRedeemScript().build().getProgram();
            } else
                outScript = txInput.getOutpoint().getConnectedPubKeyScript();
        }
        try {
            sb.setAllSignatures(keystore, tx, i, outScript);
        } catch (KeyStoreException e) {
            throw new RuntimeException(e);
        }
        checkState(sb.signatureSize() == 0, "all the signatures should have been set");
        // update scriptSig
        txInput.setScriptSig(sb.build());
    }
    return tx;
}
Also used : P2SHInputScript(it.unica.tcs.lib.script.P2SHInputScript) OutputScript(it.unica.tcs.lib.script.OutputScript) InputScript(it.unica.tcs.lib.script.InputScript) Script(org.bitcoinj.script.Script) P2SHOutputScript(it.unica.tcs.lib.script.P2SHOutputScript) P2SHInputScript(it.unica.tcs.lib.script.P2SHInputScript) InputScript(it.unica.tcs.lib.script.InputScript) P2SHOutputScript(it.unica.tcs.lib.script.P2SHOutputScript) KeyStoreException(java.security.KeyStoreException) TransactionInput(org.bitcoinj.core.TransactionInput) TransactionOutPoint(org.bitcoinj.core.TransactionOutPoint) P2SHInputScript(it.unica.tcs.lib.script.P2SHInputScript) Coin(org.bitcoinj.core.Coin) TransactionInput(org.bitcoinj.core.TransactionInput) Transaction(org.bitcoinj.core.Transaction) OutputScript(it.unica.tcs.lib.script.OutputScript) P2SHOutputScript(it.unica.tcs.lib.script.P2SHOutputScript) TransactionOutPoint(org.bitcoinj.core.TransactionOutPoint)

Example 32 with TransactionInput

use of org.bitcoinj.core.TransactionInput in project balzac by balzac-lang.

the class ScriptBuilder2Test method test_signature.

@Test
public void test_signature() throws KeyStoreException {
    ScriptBuilder2 sb = new ScriptBuilder2();
    assertEquals(0, sb.size());
    assertEquals(0, sb.getFreeVariables().size());
    assertEquals(0, sb.signatureSize());
    ECKey k1 = new ECKey();
    ECKey k2 = new ECKey();
    ecks.addKey(k1);
    ecks.addKey(k2);
    sb.signaturePlaceholder(k1, SigHash.ALL, false);
    sb.signaturePlaceholder(k2, SigHash.ALL, false);
    System.out.println(sb);
    assertEquals(2, sb.size());
    assertEquals(0, sb.getFreeVariables().size());
    assertEquals(2, sb.signatureSize());
    Transaction tx = new Transaction(new MainNetParams());
    tx.addInput(new TransactionInput(new MainNetParams(), null, new byte[] { 42, 42 }));
    sb.setAllSignatures(ecks, tx, 0, new byte[] {});
    System.out.println(sb);
    assertEquals(2, sb.size());
    assertEquals(0, sb.getFreeVariables().size());
    assertEquals(0, sb.signatureSize());
}
Also used : Transaction(org.bitcoinj.core.Transaction) ScriptBuilder2(it.unica.tcs.lib.script.ScriptBuilder2) ECKey(org.bitcoinj.core.ECKey) MainNetParams(org.bitcoinj.params.MainNetParams) TransactionInput(org.bitcoinj.core.TransactionInput) Test(org.junit.Test)

Example 33 with TransactionInput

use of org.bitcoinj.core.TransactionInput in project samourai-wallet-android by Samourai-Wallet.

the class SendFactory method makeTransaction.

/*
    Used by spends
     */
private Transaction makeTransaction(int accountIdx, HashMap<String, BigInteger> receivers, List<MyTransactionOutPoint> unspent) throws Exception {
    BigInteger amount = BigInteger.ZERO;
    for (Iterator<Map.Entry<String, BigInteger>> iterator = receivers.entrySet().iterator(); iterator.hasNext(); ) {
        Map.Entry<String, BigInteger> mapEntry = iterator.next();
        amount = amount.add(mapEntry.getValue());
    }
    List<TransactionOutput> outputs = new ArrayList<TransactionOutput>();
    Transaction tx = new Transaction(SamouraiWallet.getInstance().getCurrentNetworkParams());
    for (Iterator<Map.Entry<String, BigInteger>> iterator = receivers.entrySet().iterator(); iterator.hasNext(); ) {
        Map.Entry<String, BigInteger> mapEntry = iterator.next();
        String toAddress = mapEntry.getKey();
        BigInteger value = mapEntry.getValue();
        /*
            if(value.compareTo(SamouraiWallet.bDust) < 1)    {
                throw new Exception(context.getString(R.string.dust_amount));
            }
*/
        if (value == null || (value.compareTo(BigInteger.ZERO) <= 0 && !FormatsUtil.getInstance().isValidBIP47OpReturn(toAddress))) {
            throw new Exception(context.getString(R.string.invalid_amount));
        }
        TransactionOutput output = null;
        Script toOutputScript = null;
        if (!FormatsUtil.getInstance().isValidBitcoinAddress(toAddress) && FormatsUtil.getInstance().isValidBIP47OpReturn(toAddress)) {
            toOutputScript = new ScriptBuilder().op(ScriptOpCodes.OP_RETURN).data(Hex.decode(toAddress)).build();
            output = new TransactionOutput(SamouraiWallet.getInstance().getCurrentNetworkParams(), null, Coin.valueOf(0L), toOutputScript.getProgram());
        } else if (toAddress.toLowerCase().startsWith("tb") || toAddress.toLowerCase().startsWith("bc")) {
            byte[] scriptPubKey = null;
            try {
                Pair<Byte, byte[]> pair = Bech32Segwit.decode(SamouraiWallet.getInstance().isTestNet() ? "tb" : "bc", toAddress);
                scriptPubKey = Bech32Segwit.getScriptPubkey(pair.getLeft(), pair.getRight());
            } catch (Exception e) {
                return null;
            }
            output = new TransactionOutput(SamouraiWallet.getInstance().getCurrentNetworkParams(), null, Coin.valueOf(value.longValue()), scriptPubKey);
        } else {
            toOutputScript = ScriptBuilder.createOutputScript(org.bitcoinj.core.Address.fromBase58(SamouraiWallet.getInstance().getCurrentNetworkParams(), toAddress));
            output = new TransactionOutput(SamouraiWallet.getInstance().getCurrentNetworkParams(), null, Coin.valueOf(value.longValue()), toOutputScript.getProgram());
        }
        outputs.add(output);
    }
    List<MyTransactionInput> inputs = new ArrayList<MyTransactionInput>();
    for (MyTransactionOutPoint outPoint : unspent) {
        Script script = new Script(outPoint.getScriptBytes());
        if (script.getScriptType() == Script.ScriptType.NO_TYPE) {
            continue;
        }
        MyTransactionInput input = new MyTransactionInput(SamouraiWallet.getInstance().getCurrentNetworkParams(), null, new byte[0], outPoint, outPoint.getTxHash().toString(), outPoint.getTxOutputN());
        if (PrefsUtil.getInstance(context).getValue(PrefsUtil.RBF_OPT_IN, false) == true) {
            input.setSequenceNumber(SamouraiWallet.RBF_SEQUENCE_NO);
        }
        inputs.add(input);
    }
    // 
    // deterministically sort inputs and outputs, see BIP69 (OBPP)
    // 
    Collections.sort(inputs, new BIP69InputComparator());
    for (TransactionInput input : inputs) {
        tx.addInput(input);
    }
    Collections.sort(outputs, new BIP69OutputComparator());
    for (TransactionOutput to : outputs) {
        tx.addOutput(to);
    }
    return tx;
}
Also used : Script(org.bitcoinj.script.Script) TransactionOutput(org.bitcoinj.core.TransactionOutput) ArrayList(java.util.ArrayList) ScriptBuilder(org.bitcoinj.script.ScriptBuilder) MnemonicException(org.bitcoinj.crypto.MnemonicException) ScriptException(org.bitcoinj.script.ScriptException) AddressFormatException(org.bitcoinj.core.AddressFormatException) IOException(java.io.IOException) TransactionInput(org.bitcoinj.core.TransactionInput) Transaction(org.bitcoinj.core.Transaction) BigInteger(java.math.BigInteger) HashMap(java.util.HashMap) Map(java.util.Map) Pair(org.apache.commons.lang3.tuple.Pair)

Example 34 with TransactionInput

use of org.bitcoinj.core.TransactionInput in project samourai-wallet-android by Samourai-Wallet.

the class SendFactory method signTransaction.

private synchronized Transaction signTransaction(Transaction transaction, HashMap<String, ECKey> keyBag) throws ScriptException {
    List<TransactionInput> inputs = transaction.getInputs();
    TransactionInput input = null;
    TransactionOutput connectedOutput = null;
    byte[] connectedPubKeyScript = null;
    TransactionSignature sig = null;
    Script scriptPubKey = null;
    ECKey key = null;
    for (int i = 0; i < inputs.size(); i++) {
        input = inputs.get(i);
        key = keyBag.get(input.getOutpoint().toString());
        connectedPubKeyScript = input.getOutpoint().getConnectedPubKeyScript();
        connectedOutput = input.getOutpoint().getConnectedOutput();
        scriptPubKey = connectedOutput.getScriptPubKey();
        String address = new Script(connectedPubKeyScript).getToAddress(SamouraiWallet.getInstance().getCurrentNetworkParams()).toString();
        if (Address.fromBase58(SamouraiWallet.getInstance().getCurrentNetworkParams(), address).isP2SHAddress()) {
            final SegwitAddress p2shp2wpkh = new SegwitAddress(key.getPubKey(), SamouraiWallet.getInstance().getCurrentNetworkParams());
            // System.out.println("pubKey:" + Hex.toHexString(key.getPubKey()));
            // final Script scriptPubKey = p2shp2wpkh.segWitOutputScript();
            // System.out.println("scriptPubKey:" + Hex.toHexString(scriptPubKey.getProgram()));
            // System.out.println("to address from script:" + scriptPubKey.getToAddress(SamouraiWallet.getInstance().getCurrentNetworkParams()).toString());
            final Script redeemScript = p2shp2wpkh.segWitRedeemScript();
            // System.out.println("redeem script:" + Hex.toHexString(redeemScript.getProgram()));
            final Script scriptCode = redeemScript.scriptCode();
            // System.out.println("script code:" + Hex.toHexString(scriptCode.getProgram()));
            sig = transaction.calculateWitnessSignature(i, key, scriptCode, connectedOutput.getValue(), Transaction.SigHash.ALL, false);
            final TransactionWitness witness = new TransactionWitness(2);
            witness.setPush(0, sig.encodeToBitcoin());
            witness.setPush(1, key.getPubKey());
            transaction.setWitness(i, witness);
            final ScriptBuilder sigScript = new ScriptBuilder();
            sigScript.data(redeemScript.getProgram());
            transaction.getInput(i).setScriptSig(sigScript.build());
            transaction.getInput(i).getScriptSig().correctlySpends(transaction, i, scriptPubKey, connectedOutput.getValue(), Script.ALL_VERIFY_FLAGS);
        } else {
            if (key != null && key.hasPrivKey() || key.isEncrypted()) {
                sig = transaction.calculateSignature(i, key, connectedPubKeyScript, Transaction.SigHash.ALL, false);
            } else {
                // watch only ?
                sig = TransactionSignature.dummy();
            }
            if (scriptPubKey.isSentToAddress()) {
                input.setScriptSig(ScriptBuilder.createInputScript(sig, key));
            } else if (scriptPubKey.isSentToRawPubKey()) {
                input.setScriptSig(ScriptBuilder.createInputScript(sig));
            } else {
                throw new RuntimeException("Unknown script type: " + scriptPubKey);
            }
        }
    }
    return transaction;
}
Also used : Script(org.bitcoinj.script.Script) TransactionOutput(org.bitcoinj.core.TransactionOutput) TransactionWitness(org.bitcoinj.core.TransactionWitness) SegwitAddress(com.samourai.wallet.segwit.SegwitAddress) TransactionSignature(org.bitcoinj.crypto.TransactionSignature) ECKey(org.bitcoinj.core.ECKey) ScriptBuilder(org.bitcoinj.script.ScriptBuilder) TransactionInput(org.bitcoinj.core.TransactionInput)

Example 35 with TransactionInput

use of org.bitcoinj.core.TransactionInput in project samourai-wallet-android by Samourai-Wallet.

the class SendActivity method markUTXOAsUnspendable.

private void markUTXOAsUnspendable(String hexTx) {
    HashMap<String, Long> utxos = new HashMap<String, Long>();
    for (UTXO utxo : APIFactory.getInstance(SendActivity.this).getUtxos(true)) {
        for (MyTransactionOutPoint outpoint : utxo.getOutpoints()) {
            utxos.put(outpoint.getTxHash().toString() + "-" + outpoint.getTxOutputN(), outpoint.getValue().longValue());
        }
    }
    Transaction tx = new Transaction(SamouraiWallet.getInstance().getCurrentNetworkParams(), Hex.decode(hexTx));
    for (TransactionInput input : tx.getInputs()) {
        BlockedUTXO.getInstance().add(input.getOutpoint().getHash().toString(), (int) input.getOutpoint().getIndex(), utxos.get(input.getOutpoint().getHash().toString() + "-" + (int) input.getOutpoint().getIndex()));
    }
}
Also used : UTXO(com.samourai.wallet.send.UTXO) BlockedUTXO(com.samourai.wallet.send.BlockedUTXO) Transaction(org.bitcoinj.core.Transaction) HashMap(java.util.HashMap) MyTransactionOutPoint(com.samourai.wallet.send.MyTransactionOutPoint) TransactionInput(org.bitcoinj.core.TransactionInput)

Aggregations

TransactionInput (org.bitcoinj.core.TransactionInput)36 Transaction (org.bitcoinj.core.Transaction)29 TransactionOutput (org.bitcoinj.core.TransactionOutput)20 TransactionOutPoint (org.bitcoinj.core.TransactionOutPoint)18 Script (org.bitcoinj.script.Script)16 ECKey (org.bitcoinj.core.ECKey)11 HashMap (java.util.HashMap)10 Address (org.bitcoinj.core.Address)9 Coin (org.bitcoinj.core.Coin)9 ArrayList (java.util.ArrayList)7 AddressFormatException (org.bitcoinj.core.AddressFormatException)7 RawTransactionInput (bisq.core.btc.data.RawTransactionInput)6 TransactionSignature (org.bitcoinj.crypto.TransactionSignature)6 ScriptException (org.bitcoinj.script.ScriptException)6 MyTransactionOutPoint (com.samourai.wallet.send.MyTransactionOutPoint)5 IOException (java.io.IOException)5 Sha256Hash (org.bitcoinj.core.Sha256Hash)5 MnemonicException (org.bitcoinj.crypto.MnemonicException)5 SendRequest (org.bitcoinj.wallet.SendRequest)5 BlockedUTXO (com.samourai.wallet.send.BlockedUTXO)4