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;
}
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());
}
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;
}
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;
}
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()));
}
}
Aggregations