buildInput :: Tx -> Int -> ScriptOutput -> (Maybe RedeemScript)
           -> TxSignature -> PubKey -> Either String ScriptInput
buildInput tx i so rdmM sig pub = case (so, rdmM) of
    (PayPK _, Nothing) ->
        return $ RegularInput $ SpendPK sig
    (PayPKHash _, Nothing) ->
        return $ RegularInput $ SpendPKHash sig pub
    (PayMulSig msPubs r, Nothing) -> do
        let mSigs = take r $ catMaybes $ matchTemplate allSigs msPubs f
        return $ RegularInput $ SpendMulSig mSigs
    (PayScriptHash _, Just rdm) -> do
        inp  <- buildInput tx i rdm Nothing sig pub
        return $ ScriptHashInput (getRegularInput inp) rdm
    _ -> Left "buildInput: Invalid output/redeem script combination"
  where
    scp     = scriptInput $ txIn tx !! i
    allSigs = nub $ sig : case decodeInputBS scp of
        Right (ScriptHashInput (SpendMulSig xs) _) -> xs
        Right (RegularInput    (SpendMulSig xs))   -> xs
        _ -> []
    out = encodeOutput so
    f (TxSignature x sh) p = verifySig (txSigHash tx out i sh) x p

{- Merge multisig transactions -}
buildInput :: Tx -> Int -> ScriptOutput -> (Maybe RedeemScript)
           -> TxSignature -> PubKey -> Either String ScriptInput
buildInput tx i so rdmM sig pub = case (so, rdmM) of
    (PayPK _, Nothing) ->
        return $ RegularInput $ SpendPK sig
    (PayPKHash _, Nothing) ->
        return $ RegularInput $ SpendPKHash sig pub
    (PayMulSig msPubs r, Nothing) -> do
        let mSigs = take r $ catMaybes $ matchTemplate allSigs msPubs f
        return $ RegularInput $ SpendMulSig mSigs
    (PayScriptHash _, Just rdm) -> do
        inp  <- buildInput tx i rdm Nothing sig pub
        return $ ScriptHashInput (getRegularInput inp) rdm
    _ -> Left "buildInput: Invalid output/redeem script combination"
  where
    scp     = scriptInput $ txIn tx !! i
    allSigs = nub $ sig : case decodeInputBS scp of
        Right (ScriptHashInput (SpendMulSig xs) _) -> xs
        Right (RegularInput    (SpendMulSig xs))   -> xs
        _ -> []
    out = encodeOutput so
    f (TxSignature x sh) p = verifySig (txSigHash tx out i sh) x p

{- Merge multisig transactions -}
buildInput tx i so rdmM sig pub = case (so, rdmM) of
    (PayPK _, Nothing) ->
        return $ RegularInput $ SpendPK sig
    (PayPKHash _, Nothing) ->
        return $ RegularInput $ SpendPKHash sig pub
    (PayMulSig msPubs r, Nothing) -> do
        let mSigs = take r $ catMaybes $ matchTemplate allSigs msPubs f
        return $ RegularInput $ SpendMulSig mSigs
    (PayScriptHash _, Just rdm) -> do
        inp  <- buildInput tx i rdm Nothing sig pub
        return $ ScriptHashInput (getRegularInput inp) rdm
    _ -> Left "buildInput: Invalid output/redeem script combination"
  where
    scp     = scriptInput $ txIn tx !! i
    allSigs = nub $ sig : case decodeInputBS scp of
        Right (ScriptHashInput (SpendMulSig xs) _) -> xs
        Right (RegularInput    (SpendMulSig xs))   -> xs
        _ -> []
    out = encodeOutput so
    f (TxSignature x sh) p = verifySig (txSigHash tx out i sh) x p

{- Merge multisig transactions -}