Exemple #1
0
  public Address getAddressForInput(TransactionInput in, boolean confirmed) {
    if (in.isCoinBase()) return null;

    try {
      Address a = in.getFromAddress();
      return a;
    } catch (ScriptException e) {
      // Lets try this the other way

      try {

        TransactionOutPoint out_p = in.getOutpoint();

        Transaction src_tx = null;
        while (src_tx == null) {
          src_tx = getTransaction(out_p.getHash());
          if (src_tx == null) {
            if (!confirmed) {
              return null;
            }
            System.out.println("Unable to get source transaction: " + out_p.getHash());
            try {
              Thread.sleep(500);
            } catch (Exception e7) {
            }
          }
        }
        TransactionOutput out = src_tx.getOutput((int) out_p.getIndex());
        Address a = getAddressForOutput(out);
        return a;
      } catch (ScriptException e2) {
        return null;
      }
    }
  }
 /**
  * When the servers signature for the refund transaction is received, call this to verify it and
  * sign the complete refund ourselves.
  *
  * <p>If this does not throw an exception, we are secure against the loss of funds and can safely
  * provide the server with the multi-sig contract to lock in the agreement. In this case, both the
  * multisig contract and the refund transaction are automatically committed to wallet so that it
  * can handle broadcasting the refund transaction at the appropriate time if necessary.
  */
 public synchronized void provideRefundSignature(byte[] theirSignature)
     throws VerificationException {
   checkNotNull(theirSignature);
   checkState(state == State.WAITING_FOR_SIGNED_REFUND);
   TransactionSignature theirSig = TransactionSignature.decodeFromBitcoin(theirSignature, true);
   if (theirSig.sigHashMode() != Transaction.SigHash.NONE || !theirSig.anyoneCanPay())
     throw new VerificationException("Refund signature was not SIGHASH_NONE|SIGHASH_ANYONECANPAY");
   // Sign the refund transaction ourselves.
   final TransactionOutput multisigContractOutput = multisigContract.getOutput(0);
   try {
     multisigScript = multisigContractOutput.getScriptPubKey();
   } catch (ScriptException e) {
     throw new RuntimeException(e); // Cannot happen: we built this ourselves.
   }
   TransactionSignature ourSignature =
       refundTx.calculateSignature(0, myKey, multisigScript, Transaction.SigHash.ALL, false);
   // Insert the signatures.
   Script scriptSig = ScriptBuilder.createMultiSigInputScript(ourSignature, theirSig);
   log.info("Refund scriptSig: {}", scriptSig);
   log.info("Multi-sig contract scriptPubKey: {}", multisigScript);
   TransactionInput refundInput = refundTx.getInput(0);
   refundInput.setScriptSig(scriptSig);
   refundInput.verify(multisigContractOutput);
   state = State.SAVE_STATE_IN_WALLET;
 }
Exemple #3
0
  public void putTxOutSpents(Transaction tx) {
    LinkedList<String> tx_outs = new LinkedList<String>();

    for (TransactionInput in : tx.getInputs()) {
      if (!in.isCoinBase()) {
        TransactionOutPoint out = in.getOutpoint();
        String key = out.getHash().toString() + ":" + out.getIndex();
        // file_db.addTxOutSpentByMap(key, tx.getHash());
        tx_outs.add(key);
      }
    }
  }
  private void readTransaction(Protos.Transaction txProto, NetworkParameters params) {
    Transaction tx = new Transaction(params);
    if (txProto.hasUpdatedAt()) {
      tx.setUpdateTime(new Date(txProto.getUpdatedAt()));
    }

    for (Protos.TransactionOutput outputProto : txProto.getTransactionOutputList()) {
      BigInteger value = BigInteger.valueOf(outputProto.getValue());
      byte[] scriptBytes = outputProto.getScriptBytes().toByteArray();
      TransactionOutput output = new TransactionOutput(params, tx, value, scriptBytes);
      tx.addOutput(output);
    }

    for (Protos.TransactionInput transactionInput : txProto.getTransactionInputList()) {
      byte[] scriptBytes = transactionInput.getScriptBytes().toByteArray();
      TransactionOutPoint outpoint =
          new TransactionOutPoint(
              params,
              transactionInput.getTransactionOutPointIndex(),
              byteStringToHash(transactionInput.getTransactionOutPointHash()));
      TransactionInput input = new TransactionInput(params, tx, scriptBytes, outpoint);
      if (transactionInput.hasSequence()) {
        input.setSequenceNumber(transactionInput.getSequence());
      }
      tx.addInput(input);
    }

    for (ByteString blockHash : txProto.getBlockHashList()) {
      tx.addBlockAppearance(byteStringToHash(blockHash));
    }

    if (txProto.hasLockTime()) {
      tx.setLockTime(0xffffffffL & txProto.getLockTime());
    }

    // Transaction should now be complete.
    Sha256Hash protoHash = byteStringToHash(txProto.getHash());
    Preconditions.checkState(
        tx.getHash().equals(protoHash),
        "Transaction did not deserialize completely: %s vs %s",
        tx.getHash(),
        protoHash);
    Preconditions.checkState(
        !txMap.containsKey(txProto.getHash()),
        "Wallet contained duplicate transaction %s",
        byteStringToHash(txProto.getHash()));
    txMap.put(txProto.getHash(), tx);
  }
 public static void signTransaction(Transaction tx, String qrCodeContent) throws ScriptException {
   String[] stringArray = qrCodeContent.split(StringUtil.QR_CODE_SPLIT);
   List<String> hashList = new ArrayList<String>();
   for (String str : stringArray) {
     if (!StringUtil.isEmpty(str)) {
       hashList.add(str);
       LogUtil.d("sign", str);
     }
   }
   for (int i = 0; i < tx.getInputs().size(); i++) {
     TransactionInput input = tx.getInputs().get(i);
     String str = hashList.get(i);
     input.setScriptSig(new Script(StringUtil.hexStringToByteArray(str)));
     input
         .getScriptSig()
         .correctlySpends(tx, i, input.getOutpoint().getConnectedOutput().getScriptPubKey(), true);
   }
 }
  private WalletTransaction connectTransactionOutputs(
      org.bitcoinj.wallet.Protos.Transaction txProto) {
    Transaction tx = txMap.get(txProto.getHash());
    WalletTransaction.Pool pool = WalletTransaction.Pool.valueOf(txProto.getPool().getNumber());
    if (pool == WalletTransaction.Pool.INACTIVE
        || pool == WalletTransaction.Pool.PENDING_INACTIVE) {
      // Upgrade old wallets: inactive pool has been merged with the pending pool.
      // Remove this some time after 0.9 is old and everyone has upgraded.
      // There should not be any spent outputs in this tx as old wallets would not allow them to be
      // spent
      // in this state.
      pool = WalletTransaction.Pool.PENDING;
    }
    for (int i = 0; i < tx.getOutputs().size(); i++) {
      TransactionOutput output = tx.getOutputs().get(i);
      final Protos.TransactionOutput transactionOutput = txProto.getTransactionOutput(i);
      if (transactionOutput.hasSpentByTransactionHash()) {
        final ByteString spentByTransactionHash = transactionOutput.getSpentByTransactionHash();
        Transaction spendingTx = txMap.get(spentByTransactionHash);
        if (spendingTx == null)
          throw new IllegalArgumentException(
              String.format(
                  "Could not connect %s to %s",
                  tx.getHashAsString(), byteStringToHash(spentByTransactionHash)));
        final int spendingIndex = transactionOutput.getSpentByTransactionIndex();
        TransactionInput input = checkNotNull(spendingTx.getInput(spendingIndex));
        input.connect(output);
      }
    }

    if (txProto.hasConfidence()) {
      Protos.TransactionConfidence confidenceProto = txProto.getConfidence();
      TransactionConfidence confidence = tx.getConfidence();
      readConfidence(tx, confidenceProto, confidence);
    }

    return new WalletTransaction(pool, tx);
  }
Exemple #7
0
  @Test
  public void dataDrivenInvalidTransactions() throws Exception {
    BufferedReader in =
        new BufferedReader(
            new InputStreamReader(
                getClass().getResourceAsStream("tx_invalid.json"), Charset.forName("UTF-8")));

    NetworkParameters params = TestNet3Params.get();

    // Poor man's (aka. really, really poor) JSON parser (because pulling in a lib for this is
    // probably overkill)
    List<JSONObject> tx = new ArrayList<JSONObject>(1);
    in.read(); // remove first [
    StringBuffer buffer = new StringBuffer(1000);
    while (in.ready()) {
      String line = in.readLine();
      if (line == null || line.equals("")) continue;
      buffer.append(line);
      if (line.equals("]") && buffer.toString().equals("]") && !in.ready()) break; // ignore last ]
      boolean isFinished = appendToList(tx, buffer);
      while (tx.size() > 0
          && tx.get(0).isList()
          && tx.get(0).list.size() == 1
          && tx.get(0).list.get(0).isString()) tx.remove(0);
      if (isFinished && tx.size() == 1 && tx.get(0).list.size() == 3) {
        HashMap<TransactionOutPoint, Script> scriptPubKeys =
            new HashMap<TransactionOutPoint, Script>();
        for (JSONObject input : tx.get(0).list.get(0).list) {
          String hash = input.list.get(0).string;
          int index = input.list.get(1).integer;
          String script = input.list.get(2).string;
          Sha256Hash sha256Hash =
              new Sha256Hash(Hex.decode(hash.getBytes(Charset.forName("UTF-8"))));
          scriptPubKeys.put(
              new TransactionOutPoint(params, index, sha256Hash), parseScriptString(script));
        }

        byte[] bytes = tx.get(0).list.get(1).string.getBytes(Charset.forName("UTF-8"));
        Transaction transaction = new Transaction(params, Hex.decode(bytes));
        boolean enforceP2SH = tx.get(0).list.get(2).booleanValue;
        assertTrue(tx.get(0).list.get(2).isBoolean());

        boolean valid = true;
        try {
          transaction.verify();
        } catch (VerificationException e) {
          valid = false;
        }

        // The reference client checks this case in CheckTransaction, but we leave it to
        // later where we will see an attempt to double-spend, so we explicitly check here
        HashSet<TransactionOutPoint> set = new HashSet<TransactionOutPoint>();
        for (TransactionInput input : transaction.getInputs()) {
          if (set.contains(input.getOutpoint())) valid = false;
          set.add(input.getOutpoint());
        }

        for (int i = 0; i < transaction.getInputs().size() && valid; i++) {
          TransactionInput input = transaction.getInputs().get(i);
          assertTrue(scriptPubKeys.containsKey(input.getOutpoint()));
          try {
            input
                .getScriptSig()
                .correctlySpends(
                    transaction, i, scriptPubKeys.get(input.getOutpoint()), enforceP2SH);
          } catch (VerificationException e) {
            valid = false;
          }
        }

        if (valid) fail();

        tx.clear();
      }
    }
    in.close();
  }
Exemple #8
0
  @Test
  public void dataDrivenValidTransactions() throws Exception {
    BufferedReader in =
        new BufferedReader(
            new InputStreamReader(
                getClass().getResourceAsStream("tx_valid.json"), Charset.forName("UTF-8")));

    NetworkParameters params = TestNet3Params.get();

    // Poor man's (aka. really, really poor) JSON parser (because pulling in a lib for this is
    // probably not overkill)
    int lineNum = -1;
    List<JSONObject> tx = new ArrayList<JSONObject>(3);
    in.read(); // remove first [
    StringBuffer buffer = new StringBuffer(1000);
    while (in.ready()) {
      lineNum++;
      String line = in.readLine();
      if (line == null || line.equals("")) continue;
      buffer.append(line);
      if (line.equals("]") && buffer.toString().equals("]") && !in.ready()) break;
      boolean isFinished = appendToList(tx, buffer);
      while (tx.size() > 0
          && tx.get(0).isList()
          && tx.get(0).list.size() == 1
          && tx.get(0).list.get(0).isString()) tx.remove(0); // ignore last ]
      if (isFinished && tx.size() == 1 && tx.get(0).list.size() == 3) {
        Transaction transaction = null;
        try {
          HashMap<TransactionOutPoint, Script> scriptPubKeys =
              new HashMap<TransactionOutPoint, Script>();
          for (JSONObject input : tx.get(0).list.get(0).list) {
            String hash = input.list.get(0).string;
            int index = input.list.get(1).integer;
            String script = input.list.get(2).string;
            Sha256Hash sha256Hash =
                new Sha256Hash(Hex.decode(hash.getBytes(Charset.forName("UTF-8"))));
            scriptPubKeys.put(
                new TransactionOutPoint(params, index, sha256Hash), parseScriptString(script));
          }

          byte[] bytes = tx.get(0).list.get(1).string.getBytes(Charset.forName("UTF-8"));
          transaction = new Transaction(params, Hex.decode(bytes));
          boolean enforceP2SH = tx.get(0).list.get(2).booleanValue;
          assertTrue(tx.get(0).list.get(2).isBoolean());

          transaction.verify();

          for (int i = 0; i < transaction.getInputs().size(); i++) {
            TransactionInput input = transaction.getInputs().get(i);
            if (input.getOutpoint().getIndex() == 0xffffffffL) input.getOutpoint().setIndex(-1);
            assertTrue(scriptPubKeys.containsKey(input.getOutpoint()));
            input
                .getScriptSig()
                .correctlySpends(
                    transaction, i, scriptPubKeys.get(input.getOutpoint()), enforceP2SH);
          }
          tx.clear();
        } catch (Exception e) {
          System.err.println("Exception processing line " + lineNum + ": " + line);
          if (transaction != null) System.err.println(transaction);
          throw e;
        }
      }
    }
    in.close();
  }
  private static Protos.Transaction makeTxProto(WalletTransaction wtx) {
    Transaction tx = wtx.getTransaction();
    Protos.Transaction.Builder txBuilder = Protos.Transaction.newBuilder();

    txBuilder
        .setPool(Protos.Transaction.Pool.valueOf(wtx.getPool().getValue()))
        .setHash(hashToByteString(tx.getHash()))
        .setVersion((int) tx.getVersion());

    if (tx.getUpdateTime() != null) {
      txBuilder.setUpdatedAt(tx.getUpdateTime().getTime());
    }

    if (tx.getLockTime() > 0) {
      txBuilder.setLockTime((int) tx.getLockTime());
    }

    // Handle inputs.
    for (TransactionInput input : tx.getInputs()) {
      Protos.TransactionInput.Builder inputBuilder =
          Protos.TransactionInput.newBuilder()
              .setScriptBytes(ByteString.copyFrom(input.getScriptBytes()))
              .setTransactionOutPointHash(hashToByteString(input.getOutpoint().getHash()))
              .setTransactionOutPointIndex((int) input.getOutpoint().getIndex());
      if (input.hasSequence()) {
        inputBuilder.setSequence((int) input.getSequenceNumber());
      }
      txBuilder.addTransactionInput(inputBuilder);
    }

    // Handle outputs.
    for (TransactionOutput output : tx.getOutputs()) {
      Protos.TransactionOutput.Builder outputBuilder =
          Protos.TransactionOutput.newBuilder()
              .setScriptBytes(ByteString.copyFrom(output.getScriptBytes()))
              .setValue(output.getValue().longValue());
      final TransactionInput spentBy = output.getSpentBy();
      if (spentBy != null) {
        Sha256Hash spendingHash = spentBy.getParentTransaction().getHash();
        int spentByTransactionIndex = spentBy.getParentTransaction().getInputs().indexOf(spentBy);
        outputBuilder
            .setSpentByTransactionHash(hashToByteString(spendingHash))
            .setSpentByTransactionIndex(spentByTransactionIndex);
      }
      txBuilder.addTransactionOutput(outputBuilder);
    }

    // Handle which blocks tx was seen in.
    if (tx.getAppearsInHashes() != null) {
      for (Sha256Hash hash : tx.getAppearsInHashes()) {
        txBuilder.addBlockHash(hashToByteString(hash));
      }
    }

    if (tx.hasConfidence()) {
      TransactionConfidence confidence = tx.getConfidence();
      Protos.TransactionConfidence.Builder confidenceBuilder =
          Protos.TransactionConfidence.newBuilder();
      writeConfidence(txBuilder, confidence, confidenceBuilder);
    }

    return txBuilder.build();
  }