mergeTxs :: [Tx] -> [(ScriptOutput, OutPoint)] -> Either String Tx
mergeTxs txs os
    | null txs = error "Transaction list is empty"
    | length (nub emptyTxs) /= 1 = Left "Transactions do not match"
    | length txs == 1 = return $ head txs
    | otherwise = foldM (mergeTxInput txs) (head emptyTxs) outs
  where
    zipOp = zip (matchTemplate os (txIn $ head txs) f) [0..]
    outs = map (first $ fst . fromJust) $ filter (isJust . fst) zipOp
    f (_,o) txin = o == prevOutput txin
    emptyTxs = map (\tx -> foldl clearInput tx outs) txs
    clearInput tx (_, i) = tx{ txIn =
        updateIndex i (txIn tx) (\ti -> ti{ scriptInput = BS.empty }) }
mergeTxs :: [Tx] -> [(ScriptOutput, OutPoint)] -> Either String Tx
mergeTxs txs os
    | null txs = error "Transaction list is empty"
    | length (nub emptyTxs) /= 1 = Left "Transactions do not match"
    | length txs == 1 = return $ head txs
    | otherwise = foldM (mergeTxInput txs) (head emptyTxs) outs
  where
    zipOp = zip (matchTemplate os (txIn $ head txs) f) [0..]
    outs = map (first $ fst . fromJust) $ filter (isJust . fst) zipOp
    f (_,o) txin = o == prevOutput txin
    emptyTxs = map (\tx -> foldl clearInput tx outs) txs
    clearInput tx (_, i) = tx{ txIn =
        updateIndex i (txIn tx) (\ti -> ti{ scriptInput = BS.empty }) }
mergeTxs txs os
    | null txs = error "Transaction list is empty"
    | length (nub emptyTxs) /= 1 = Left "Transactions do not match"
    | length txs == 1 = return $ head txs
    | otherwise = foldM (mergeTxInput txs) (head emptyTxs) outs
  where
    zipOp = zip (matchTemplate os (txIn $ head txs) f) [0..]
    outs = map (first $ fst . fromJust) $ filter (isJust . fst) zipOp
    f (_,o) txin = o == prevOutput txin
    emptyTxs = map (\tx -> foldl clearInput tx outs) txs
    clearInput tx (_, i) = tx{ txIn =
        updateIndex i (txIn tx) (\ti -> ti{ scriptInput = BS.empty }) }