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 List<Transaction> getTransactionsFromBither(
      JSONObject jsonObject, int storeBlockHeight)
      throws JSONException, WrongNetworkException, AddressFormatException, VerificationException,
          ParseException, NoSuchFieldException, IllegalAccessException, IllegalArgumentException {
    List<Transaction> transactions = new ArrayList<Transaction>();

    if (!jsonObject.isNull(TXS)) {
      JSONArray txArray = jsonObject.getJSONArray(TXS);
      double count = 0;
      double size = txArray.length();

      for (int j = 0; j < txArray.length(); j++) {
        JSONObject tranJsonObject = txArray.getJSONObject(j);
        String blockHash = tranJsonObject.getString(BITHER_BLOCK_HASH);
        String txHash = tranJsonObject.getString(TX_HASH);
        int height = tranJsonObject.getInt(BITHER_BLOCK_NO);
        if (height > storeBlockHeight && storeBlockHeight > 0) {
          continue;
        }
        int version = 1;
        Date updateTime = new Date();
        if (!tranJsonObject.isNull(EXPLORER_TIME)) {
          updateTime = DateTimeUtil.getDateTimeForTimeZone(tranJsonObject.getString(EXPLORER_TIME));
        }
        if (!tranJsonObject.isNull(EXPLORER_VERSION)) {
          version = tranJsonObject.getInt(EXPLORER_VERSION);
        }
        Transaction transaction =
            new Transaction(BitherSetting.NETWORK_PARAMETERS, version, new Sha256Hash(txHash));
        transaction.addBlockAppearance(new Sha256Hash(blockHash), height);
        if (!tranJsonObject.isNull(EXPLORER_OUT)) {
          JSONArray tranOutArray = tranJsonObject.getJSONArray(EXPLORER_OUT);
          for (int i = 0; i < tranOutArray.length(); i++) {
            JSONObject tranOutJson = tranOutArray.getJSONObject(i);
            BigInteger value = BigInteger.valueOf(tranOutJson.getLong(BITHER_VALUE));
            if (!tranOutJson.isNull(SCRIPT_PUB_KEY)) {
              String str = tranOutJson.getString(SCRIPT_PUB_KEY);
              // Script script = new Script(
              // );
              // byte[] bytes1 = ScriptBuilder.createOutputScript(
              // address).getProgram();
              // byte[] bytes2 = StringUtil
              // .hexStringToByteArray(str);
              // LogUtil.d("tx", Arrays.equals(bytes1, bytes2) +
              // ";");
              TransactionOutput transactionOutput =
                  new TransactionOutput(
                      BitherSetting.NETWORK_PARAMETERS,
                      transaction,
                      value,
                      StringUtil.hexStringToByteArray(str));
              transaction.addOutput(transactionOutput);
            }
          }
        }

        if (!tranJsonObject.isNull(EXPLORER_IN)) {
          JSONArray tranInArray = tranJsonObject.getJSONArray(EXPLORER_IN);
          for (int i = 0; i < tranInArray.length(); i++) {
            JSONObject tranInJson = tranInArray.getJSONObject(i);
            TransactionOutPoint transactionOutPoint = null;
            if (!tranInJson.isNull(EXPLORER_COINBASE)) {
              long index = 0;
              if (!tranInJson.isNull(EXPLORER_SEQUENCE)) {
                index = tranInJson.getLong(EXPLORER_SEQUENCE);
              }
              transactionOutPoint =
                  new TransactionOutPoint(
                      BitherSetting.NETWORK_PARAMETERS, index, Sha256Hash.ZERO_HASH);

            } else {

              String prevOutHash = tranInJson.getString(PREV_TX_HASH);
              long n = 0;
              if (!tranInJson.isNull(PREV_OUTPUT_SN)) {
                n = tranInJson.getLong(PREV_OUTPUT_SN);
              }
              transactionOutPoint =
                  new TransactionOutPoint(
                      BitherSetting.NETWORK_PARAMETERS, n, new Sha256Hash(prevOutHash));
            }
            // Log.d("transaction", transaction.toString());
            if (transactionOutPoint != null) {
              TransactionInput transactionInput =
                  new TransactionInput(
                      BitherSetting.NETWORK_PARAMETERS,
                      transaction,
                      Script.createInputScript(EMPTY_BYTES, EMPTY_BYTES),
                      transactionOutPoint);

              transaction.addInput(transactionInput);
            }
          }
        }
        transaction.getConfidence().setAppearedAtChainHeight(height);
        transaction.getConfidence().setConfidenceType(ConfidenceType.BUILDING);
        transaction.getConfidence().setDepthInBlocks(storeBlockHeight - height + 1);
        transaction.setUpdateTime(updateTime);
        // Log.d("transaction", "transaction.num:" + transaction);
        Field txField = Transaction.class.getDeclaredField("hash");
        txField.setAccessible(true);
        txField.set(transaction, new Sha256Hash(txHash));
        transactions.add(transaction);
        count++;
        double progress =
            BitherSetting.SYNC_TX_PROGRESS_BLOCK_HEIGHT
                + BitherSetting.SYNC_TX_PROGRESS_STEP1
                + BitherSetting.SYNC_TX_PROGRESS_STEP2 * (count / size);
        BroadcastUtil.sendBroadcastProgressState(progress);
      }
    }

    LogUtil.d("transaction", "transactions.num:" + transactions.size());
    return transactions;
  }