From ba5a988f471f6892054e3e423996b66f2e088be3 Mon Sep 17 00:00:00 2001 From: Sjoerd Visscher Date: Wed, 30 Mar 2022 17:42:54 +0200 Subject: [PATCH] Reinstate the SigningProcess API --- .../Plutus/Trace/Effects/EmulatorControl.hs | 2 +- plutus-contract/src/Wallet/Emulator/Wallet.hs | 65 +- plutus-ledger/src/Ledger/Tx/CardanoAPI.hs | 1 + plutus-ledger/src/Ledger/Validation.hs | 6 + .../src/Plutus/Contracts/MultiSig.hs | 9 +- plutus-use-cases/test/Spec.hs | 9 +- plutus-use-cases/test/Spec/MultiSig.hs | 6 +- plutus-use-cases/test/Spec/multisig.pir | 1140 +++++++++++++++++ 8 files changed, 1204 insertions(+), 34 deletions(-) create mode 100644 plutus-use-cases/test/Spec/multisig.pir diff --git a/plutus-contract/src/Plutus/Trace/Effects/EmulatorControl.hs b/plutus-contract/src/Plutus/Trace/Effects/EmulatorControl.hs index 9ec5e8c58f..01beb8af28 100644 --- a/plutus-contract/src/Plutus/Trace/Effects/EmulatorControl.hs +++ b/plutus-contract/src/Plutus/Trace/Effects/EmulatorControl.hs @@ -63,7 +63,7 @@ are some modifications to be made) -} data EmulatorControl r where - SetSigningProcess :: Wallet -> SigningProcess -> EmulatorControl () + SetSigningProcess :: Wallet -> Maybe SigningProcess -> EmulatorControl () AgentState :: Wallet -> EmulatorControl WalletState FreezeContractInstance :: ContractInstanceId -> EmulatorControl () ThawContractInstance :: ContractInstanceId -> EmulatorControl () diff --git a/plutus-contract/src/Wallet/Emulator/Wallet.hs b/plutus-contract/src/Wallet/Emulator/Wallet.hs index 839493298a..c0bd481bd0 100644 --- a/plutus-contract/src/Wallet/Emulator/Wallet.hs +++ b/plutus-contract/src/Wallet/Emulator/Wallet.hs @@ -57,7 +57,7 @@ import Ledger.Constraints.OffChain (UnbalancedTx (UnbalancedTx, unBalancedTxTx)) import Ledger.Constraints.OffChain qualified as U import Ledger.Credential (Credential (PubKeyCredential, ScriptCredential)) import Ledger.Tx qualified as Tx -import Ledger.Validation (addSignature, evaluateTransactionFee, fromPlutusIndex, fromPlutusTx) +import Ledger.Validation (addSignature, evaluateTransactionFee, fromPlutusIndex, fromPlutusTx, getRequiredSigners) import Ledger.Value qualified as Value import Plutus.ChainIndex (PageQuery) import Plutus.ChainIndex qualified as ChainIndex @@ -81,7 +81,7 @@ import Wallet.Emulator.NodeClient (NodeClientState, emptyNodeClientState) newtype SigningProcess = SigningProcess { - unSigningProcess :: forall effs. (Member (Error WAPI.WalletAPIError) effs) => [PaymentPubKeyHash] -> Tx -> Eff effs Tx + unSigningProcess :: forall effs. (Member (Error WAPI.WalletAPIError) effs) => [PaymentPubKeyHash] -> CardanoTx -> Eff effs CardanoTx } instance Show SigningProcess where @@ -194,10 +194,12 @@ makePrisms ''WalletEvent -- | The state used by the mock wallet environment. data WalletState = WalletState { - _mockWallet :: MockWallet, -- ^ mock wallet with the user's private key + _mockWallet :: MockWallet, -- ^ Mock wallet with the user's private key. _nodeClient :: NodeClientState, _chainIndexEmulatorState :: ChainIndexEmulatorState, - _signingProcess :: SigningProcess + _signingProcess :: Maybe SigningProcess + -- ^ Override the signing process. + -- Used for testing multi-agent use cases. } deriving Show makeLenses ''WalletState @@ -219,8 +221,7 @@ ownAddress = flip Ledger.pubKeyAddress Nothing -- | An empty wallet using the given private key. -- for that wallet as the sole watched address. fromMockWallet :: MockWallet -> WalletState -fromMockWallet mw = WalletState mw emptyNodeClientState mempty sp where - sp = signWithPrivateKey (CW.paymentPrivateKey mw) +fromMockWallet mw = WalletState mw emptyNodeClientState mempty Nothing -- | Empty wallet state for an emulator 'Wallet'. Returns 'Nothing' if the wallet -- is not known in the emulator. @@ -266,7 +267,12 @@ handleWallet = \case logInfo $ FinishedBalancing txCTx pure txCTx - walletAddSignatureH :: (Member (State WalletState) effs, Member (LogMsg TxBalanceMsg) effs) => CardanoTx -> Eff effs CardanoTx + walletAddSignatureH :: + ( Member (State WalletState) effs + , Member (LogMsg TxBalanceMsg) effs + , Member (Error WalletAPIError) effs + ) + => CardanoTx -> Eff effs CardanoTx walletAddSignatureH txCTx = do logInfo $ SigningTx txCTx handleAddSignature txCTx @@ -294,7 +300,7 @@ handleBalance :: , Member ChainIndexQueryEffect effs , Member (State WalletState) effs , Member (LogMsg TxBalanceMsg) effs - , Member (Error WAPI.WalletAPIError) effs + , Member (Error WalletAPIError) effs ) => UnbalancedTx -> Eff effs CardanoTx @@ -330,17 +336,32 @@ handleBalance utx' = do handleError _ (Right v) = pure v handleAddSignature :: - Member (State WalletState) effs + ( Member (State WalletState) effs + , Member (Error WalletAPIError) effs + ) => CardanoTx -> Eff effs CardanoTx handleAddSignature tx = do - (PaymentPrivateKey privKey) <- gets ownPaymentPrivateKey - pure $ Tx.cardanoTxMap (Ledger.addSignature' privKey) (addSignatureCardano privKey) tx + msp <- gets _signingProcess + case msp of + Nothing -> do + PaymentPrivateKey privKey <- gets ownPaymentPrivateKey + pure $ addSignature' privKey tx + Just (SigningProcess sp) -> do + let ctx = case tx of + Tx.CardanoApiTx (Tx.SomeTx ctx' AlonzoEraInCardanoMode) -> ctx' + Tx.Both _ (Tx.SomeTx ctx' AlonzoEraInCardanoMode) -> ctx' + _ -> error "handleAddSignature: Need a Cardano API Tx from the Alonzo era to get the required signers" + reqSigners = getRequiredSigners ctx + sp reqSigners tx + +addSignature' :: PrivateKey -> CardanoTx -> CardanoTx +addSignature' privKey = Tx.cardanoTxMap (Ledger.addSignature' privKey) addSignatureCardano where - addSignatureCardano :: PrivateKey -> SomeCardanoApiTx -> SomeCardanoApiTx - addSignatureCardano privKey (Tx.SomeTx ctx AlonzoEraInCardanoMode) + addSignatureCardano :: SomeCardanoApiTx -> SomeCardanoApiTx + addSignatureCardano (Tx.SomeTx ctx AlonzoEraInCardanoMode) = Tx.SomeTx (addSignature privKey ctx) AlonzoEraInCardanoMode - addSignatureCardano _ _ = error "Wallet.Emulator.Wallet.handleAddSignature: Expected an Alonzo tx" + addSignatureCardano _ = error "Wallet.Emulator.Wallet.addSignature': Expected an Alonzo tx" ownOutputs :: forall effs. ( Member ChainIndexQueryEffect effs @@ -580,9 +601,9 @@ signWallet wllt = SigningProcess $ signTxnWithKey :: (Member (Error WAPI.WalletAPIError) r) => MockWallet - -> Tx + -> CardanoTx -> PaymentPubKeyHash - -> Eff r Tx + -> Eff r CardanoTx signTxnWithKey mw = signTxWithPrivateKey (CW.paymentPrivateKey mw) -- | Sign the transaction with the private key, if the hash is that of the @@ -590,26 +611,26 @@ signTxnWithKey mw = signTxWithPrivateKey (CW.paymentPrivateKey mw) signTxWithPrivateKey :: (Member (Error WAPI.WalletAPIError) r) => PaymentPrivateKey - -> Tx + -> CardanoTx -> PaymentPubKeyHash - -> Eff r Tx + -> Eff r CardanoTx signTxWithPrivateKey (PaymentPrivateKey pk) tx pkh@(PaymentPubKeyHash pubK) = do let ownPaymentPubKey = Ledger.toPublicKey pk if Ledger.pubKeyHash ownPaymentPubKey == pubK - then pure (Ledger.addSignature' pk tx) + then pure (addSignature' pk tx) else throwError (WAPI.PaymentPrivateKeyNotFound pkh) -- | Sign the transaction with the given private keys, -- ignoring the list of public keys that the 'SigningProcess' is passed. signPrivateKeys :: [PaymentPrivateKey] -> SigningProcess signPrivateKeys signingKeys = SigningProcess $ \_ tx -> - pure (foldr (Ledger.addSignature' . unPaymentPrivateKey) tx signingKeys) + pure (foldr (addSignature' . unPaymentPrivateKey) tx signingKeys) data SigningProcessControlEffect r where - SetSigningProcess :: SigningProcess -> SigningProcessControlEffect () + SetSigningProcess :: Maybe SigningProcess -> SigningProcessControlEffect () makeEffect ''SigningProcessControlEffect -type SigningProcessEffs = '[State SigningProcess, Error WAPI.WalletAPIError] +type SigningProcessEffs = '[State (Maybe SigningProcess), Error WAPI.WalletAPIError] handleSigningProcessControl :: (Members SigningProcessEffs effs) => Eff (SigningProcessControlEffect ': effs) ~> Eff effs handleSigningProcessControl = interpret $ \case diff --git a/plutus-ledger/src/Ledger/Tx/CardanoAPI.hs b/plutus-ledger/src/Ledger/Tx/CardanoAPI.hs index c72e7e46f1..62ebd1d241 100644 --- a/plutus-ledger/src/Ledger/Tx/CardanoAPI.hs +++ b/plutus-ledger/src/Ledger/Tx/CardanoAPI.hs @@ -31,6 +31,7 @@ module Ledger.Tx.CardanoAPI( , fromCardanoFee , fromCardanoValidityRange , fromCardanoScriptInEra + , fromCardanoPaymentKeyHash , fromCardanoScriptData , fromTxScriptValidity , scriptDataFromCardanoTxBody diff --git a/plutus-ledger/src/Ledger/Validation.hs b/plutus-ledger/src/Ledger/Validation.hs index 841086aa88..8dbc987b5b 100644 --- a/plutus-ledger/src/Ledger/Validation.hs +++ b/plutus-ledger/src/Ledger/Validation.hs @@ -17,6 +17,7 @@ module Ledger.Validation( initialState, evaluateTransactionFee, evaluateMinLovelaceOutput, + getRequiredSigners, addSignature, hasValidationErrors, -- * Modifying the state @@ -47,6 +48,7 @@ import Cardano.Ledger.Alonzo.Rules.Utxos (constructValidated) import Cardano.Ledger.Alonzo.Scripts (ExUnits (ExUnits)) import Cardano.Ledger.Alonzo.Tools qualified as C.Ledger import Cardano.Ledger.Alonzo.Tx (ValidatedTx (..)) +import Cardano.Ledger.Alonzo.TxBody (TxBody (TxBody, reqSignerHashes)) import Cardano.Ledger.Alonzo.TxWitness (RdmrPtr, txwitsVKey) import Cardano.Ledger.BaseTypes (Globals (..)) import Cardano.Ledger.Core (PParams, Tx) @@ -293,6 +295,10 @@ plutusTxToTxBodyContent plutusTxToTxBodyContent requiredSigners = P.toCardanoTxBodyContent requiredSigners (Just emulatorProtocolParameters) emulatorNetworkId +getRequiredSigners :: C.Api.Tx C.Api.AlonzoEra -> [P.PaymentPubKeyHash] +getRequiredSigners (C.Api.ShelleyTx _ (ValidatedTx TxBody { reqSignerHashes = rsq } _ _ _)) = + foldMap (pure . P.PaymentPubKeyHash . P.fromCardanoPaymentKeyHash . C.Api.PaymentKeyHash . C.Ledger.coerceKeyRole) rsq + addSignature :: P.PrivateKey -> C.Api.Tx C.Api.AlonzoEra diff --git a/plutus-use-cases/src/Plutus/Contracts/MultiSig.hs b/plutus-use-cases/src/Plutus/Contracts/MultiSig.hs index ff2717d87c..1cc76e01c5 100644 --- a/plutus-use-cases/src/Plutus/Contracts/MultiSig.hs +++ b/plutus-use-cases/src/Plutus/Contracts/MultiSig.hs @@ -77,9 +77,11 @@ typedValidator = Scripts.mkTypedValidatorParam @MultiSig -- | Lock some funds in a 'MultiSig' contract. lock :: AsContractError e => Promise () MultiSigSchema e () lock = endpoint @"lock" $ \(ms, vl) -> do - let tx = Constraints.mustPayToTheScript () vl let inst = typedValidator ms - void $ submitTxConstraints inst tx + let tx = Constraints.mustPayToTheScript () vl + lookups = Constraints.typedValidatorLookups inst + mkTxConstraints lookups tx + >>= void . submitUnbalancedTx . Constraints.adjustUnbalancedTx -- | The @"unlock"@ endpoint, unlocking some funds with a list -- of signatures. @@ -91,4 +93,5 @@ unlock = endpoint @"unlock" $ \(ms, pks) -> do <> foldMap Constraints.mustBeSignedBy pks lookups = Constraints.typedValidatorLookups inst <> Constraints.unspentOutputs utx - void $ submitTxConstraintsWith lookups tx + mkTxConstraints lookups tx + >>= void . submitUnbalancedTx . Constraints.adjustUnbalancedTx diff --git a/plutus-use-cases/test/Spec.hs b/plutus-use-cases/test/Spec.hs index 291675f497..455e22a917 100644 --- a/plutus-use-cases/test/Spec.hs +++ b/plutus-use-cases/test/Spec.hs @@ -10,14 +10,14 @@ import Spec.Future qualified import Spec.Game qualified import Spec.GameStateMachine qualified import Spec.Governance qualified -import Spec.SealedBidAuction qualified -import Spec.SimpleEscrow qualified --- import qualified Spec.MultiSig +import Spec.MultiSig qualified import Spec.MultiSigStateMachine qualified import Spec.PingPong qualified import Spec.Prism qualified import Spec.PubKey qualified import Spec.Rollup qualified +import Spec.SealedBidAuction qualified +import Spec.SimpleEscrow qualified import Spec.Stablecoin qualified import Spec.TokenAccount qualified import Spec.Uniswap qualified @@ -42,8 +42,7 @@ tests = localOption limit $ testGroup "use cases" [ Spec.Vesting.tests, Spec.ErrorHandling.tests, Spec.Future.tests, - -- disable temporarily, because we need to adopt the signing API - -- Spec.MultiSig.tests, + Spec.MultiSig.tests, Spec.MultiSigStateMachine.tests, Spec.Currency.tests, Spec.PubKey.tests, diff --git a/plutus-use-cases/test/Spec/MultiSig.hs b/plutus-use-cases/test/Spec/MultiSig.hs index aa9030f03b..1786f01e6b 100644 --- a/plutus-use-cases/test/Spec/MultiSig.hs +++ b/plutus-use-cases/test/Spec/MultiSig.hs @@ -23,7 +23,7 @@ import Wallet.Emulator.Wallet (signPrivateKeys) tests :: TestTree tests = testGroup "multisig" [ checkPredicate "2 out of 5" - (assertFailedTransaction (\_ err _ -> case err of {ScriptFailure (EvaluationError ["not enough signatures"] _) -> True; _ -> False })) + (assertFailedTransaction (\_ err _ -> case err of {ScriptFailure (EvaluationError ("not enough signatures":_) _) -> True; _ -> False })) failingTrace , checkPredicate "3 out of 5" @@ -40,7 +40,7 @@ failingTrace = do hdl <- Trace.activateContractWallet w1 theContract Trace.callEndpoint @"lock" hdl (multiSig, Ada.lovelaceValueOf 10) _ <- Trace.waitNSlots 1 - Trace.setSigningProcess w1 (signPrivateKeys [CW.paymentPrivateKey (CW.knownMockWallet 1), CW.paymentPrivateKey (CW.knownMockWallet 2)]) + Trace.setSigningProcess w1 (Just $ signPrivateKeys [CW.paymentPrivateKey (CW.knownMockWallet 1), CW.paymentPrivateKey (CW.knownMockWallet 2)]) Trace.callEndpoint @"unlock" hdl (multiSig, fmap mockWalletPaymentPubKeyHash [w1, w2]) void $ Trace.waitNSlots 1 @@ -51,7 +51,7 @@ succeedingTrace = do hdl <- Trace.activateContractWallet w1 theContract Trace.callEndpoint @"lock" hdl (multiSig, Ada.lovelaceValueOf 10) _ <- Trace.waitNSlots 1 - Trace.setSigningProcess w1 (signPrivateKeys [CW.paymentPrivateKey (CW.knownMockWallet 1), CW.paymentPrivateKey (CW.knownMockWallet 2), CW.paymentPrivateKey (CW.knownMockWallet 3)]) + Trace.setSigningProcess w1 (Just $ signPrivateKeys [CW.paymentPrivateKey (CW.knownMockWallet 1), CW.paymentPrivateKey (CW.knownMockWallet 2), CW.paymentPrivateKey (CW.knownMockWallet 3)]) Trace.callEndpoint @"unlock" hdl (multiSig, fmap mockWalletPaymentPubKeyHash [w1, w2, w3]) void $ Trace.waitNSlots 1 diff --git a/plutus-use-cases/test/Spec/multisig.pir b/plutus-use-cases/test/Spec/multisig.pir new file mode 100644 index 0000000000..120ed02a88 --- /dev/null +++ b/plutus-use-cases/test/Spec/multisig.pir @@ -0,0 +1,1140 @@ +(program + (let + (nonrec) + (datatypebind + (datatype + (tyvardecl Monoid (fun (type) (type))) + (tyvardecl a (type)) + Monoid_match + (vardecl + CConsMonoid + (fun [ (lam a (type) (fun a (fun a a))) a ] (fun a [ Monoid a ])) + ) + ) + ) + (termbind + (strict) + (vardecl + p1Monoid + (all a (type) (fun [ Monoid a ] [ (lam a (type) (fun a (fun a a))) a ])) + ) + (abs + a + (type) + (lam + v + [ Monoid a ] + [ + { [ { Monoid_match a } v ] [ (lam a (type) (fun a (fun a a))) a ] } + (lam v [ (lam a (type) (fun a (fun a a))) a ] (lam v a v)) + ] + ) + ) + ) + (termbind + (strict) + (vardecl mempty (all a (type) (fun [ Monoid a ] a))) + (abs + a + (type) + (lam + v + [ Monoid a ] + [ + { [ { Monoid_match a } v ] a } + (lam v [ (lam a (type) (fun a (fun a a))) a ] (lam v a v)) + ] + ) + ) + ) + (let + (rec) + (datatypebind + (datatype + (tyvardecl List (fun (type) (type))) + (tyvardecl a (type)) + Nil_match + (vardecl Nil [ List a ]) + (vardecl Cons (fun a (fun [ List a ] [ List a ]))) + ) + ) + (let + (rec) + (termbind + (strict) + (vardecl + fFoldableNil_cfoldMap + (all + m + (type) + (all + a (type) (fun [ Monoid m ] (fun (fun a m) (fun [ List a ] m))) + ) + ) + ) + (abs + m + (type) + (abs + a + (type) + (lam + dMonoid + [ Monoid m ] + (lam + ds + (fun a m) + (lam + ds + [ List a ] + { + [ + [ + { [ { Nil_match a } ds ] (all dead (type) m) } + (abs dead (type) [ { mempty m } dMonoid ]) + ] + (lam + x + a + (lam + xs + [ List a ] + (abs + dead + (type) + [ + [ [ { p1Monoid m } dMonoid ] [ ds x ] ] + [ + [ + [ + { { fFoldableNil_cfoldMap m } a } dMonoid + ] + ds + ] + xs + ] + ] + ) + ) + ) + ] + (all dead (type) dead) + } + ) + ) + ) + ) + ) + ) + (let + (rec) + (termbind + (strict) + (vardecl + foldr + (all + a + (type) + (all + b (type) (fun (fun a (fun b b)) (fun b (fun [ List a ] b))) + ) + ) + ) + (abs + a + (type) + (abs + b + (type) + (lam + f + (fun a (fun b b)) + (lam + acc + b + (lam + l + [ List a ] + { + [ + [ + { [ { Nil_match a } l ] (all dead (type) b) } + (abs dead (type) acc) + ] + (lam + x + a + (lam + xs + [ List a ] + (abs + dead + (type) + [ + [ f x ] [ [ [ { { foldr a } b } f ] acc ] xs ] + ] + ) + ) + ) + ] + (all dead (type) dead) + } + ) + ) + ) + ) + ) + ) + (let + (nonrec) + (typebind (tyvardecl Unit (type)) (all a (type) (fun a a))) + (datatypebind + (datatype + (tyvardecl MultiSig (type)) + + MultiSig_match + (vardecl + MultiSig + (fun [ List (con bytestring) ] (fun (con integer) MultiSig)) + ) + ) + ) + (typebind (tyvardecl ScriptPurpose (type)) (all a (type) (fun a a))) + (typebind (tyvardecl DCert (type)) (all a (type) (fun a a))) + (typebind + (tyvardecl Interval (fun (type) (type))) + (lam a (type) (all a (type) (fun a a))) + ) + (typebind (tyvardecl TxInInfo (type)) (all a (type) (fun a a))) + (typebind (tyvardecl TxOut (type)) (all a (type) (fun a a))) + (typebind + (tyvardecl StakingCredential (type)) (all a (type) (fun a a)) + ) + (typebind + (tyvardecl Tuple2 (fun (type) (fun (type) (type)))) + (lam a (type) (lam a (type) (all a (type) (fun a a)))) + ) + (datatypebind + (datatype + (tyvardecl TxInfo (type)) + + TxInfo_match + (vardecl + TxInfo + (fun + [ List TxInInfo ] + (fun + [ List TxOut ] + (fun + [ + [ + (lam + k + (type) + (lam v (type) [ List [ [ Tuple2 k ] v ] ]) + ) + (con bytestring) + ] + [ + [ + (lam + k + (type) + (lam v (type) [ List [ [ Tuple2 k ] v ] ]) + ) + (con bytestring) + ] + (con integer) + ] + ] + (fun + [ + [ + (lam + k + (type) + (lam v (type) [ List [ [ Tuple2 k ] v ] ]) + ) + (con bytestring) + ] + [ + [ + (lam + k + (type) + (lam v (type) [ List [ [ Tuple2 k ] v ] ]) + ) + (con bytestring) + ] + (con integer) + ] + ] + (fun + [ List DCert ] + (fun + [ + List + [ [ Tuple2 StakingCredential ] (con integer) ] + ] + (fun + [ Interval (con integer) ] + (fun + [ List (con bytestring) ] + (fun + [ + List + [ [ Tuple2 (con bytestring) ] (con data) ] + ] + (fun (con bytestring) TxInfo) + ) + ) + ) + ) + ) + ) + ) + ) + ) + ) + ) + ) + (datatypebind + (datatype + (tyvardecl ScriptContext (type)) + + ScriptContext_match + (vardecl + ScriptContext (fun TxInfo (fun ScriptPurpose ScriptContext)) + ) + ) + ) + (datatypebind + (datatype + (tyvardecl Bool (type)) + + Bool_match + (vardecl True Bool) (vardecl False Bool) + ) + ) + (datatypebind + (datatype + (tyvardecl Maybe (fun (type) (type))) + (tyvardecl a (type)) + Maybe_match + (vardecl Just (fun a [ Maybe a ])) (vardecl Nothing [ Maybe a ]) + ) + ) + (lam + w + MultiSig + (lam + w + Unit + (lam + w + Unit + (lam + w + ScriptContext + [ + { [ MultiSig_match w ] Bool } + (lam + ww + [ List (con bytestring) ] + (lam + ww + (con integer) + { + [ + [ + { + [ + Bool_match + [ + [ + [ + { (builtin ifThenElse) Bool } + [ + [ + (builtin lessThanInteger) + (let + (nonrec) + (termbind + (strict) + (vardecl + t [ List (con bytestring) ] + ) + [ + [ + [ + { + { + foldr + (con bytestring) + } + [ + List + (con bytestring) + ] + } + (lam + e + (con bytestring) + (lam + xs + [ + List + (con bytestring) + ] + [ + { + [ + ScriptContext_match + w + ] + [ + List + (con + bytestring + ) + ] + } + (lam + ds + TxInfo + (lam + ds + ScriptPurpose + [ + { + [ + TxInfo_match + ds + ] + [ + List + (con + bytestring + ) + ] + } + (lam + ww + [ + List + TxInInfo + ] + (lam + ww + [ + List + TxOut + ] + (lam + ww + [ + [ + (lam + k + (type) + (lam + v + (type) + [ + List + [ + [ + Tuple2 + k + ] + v + ] + ] + ) + ) + (con + bytestring + ) + ] + [ + [ + (lam + k + (type) + (lam + v + (type) + [ + List + [ + [ + Tuple2 + k + ] + v + ] + ] + ) + ) + (con + bytestring + ) + ] + (con + integer + ) + ] + ] + (lam + ww + [ + [ + (lam + k + (type) + (lam + v + (type) + [ + List + [ + [ + Tuple2 + k + ] + v + ] + ] + ) + ) + (con + bytestring + ) + ] + [ + [ + (lam + k + (type) + (lam + v + (type) + [ + List + [ + [ + Tuple2 + k + ] + v + ] + ] + ) + ) + (con + bytestring + ) + ] + (con + integer + ) + ] + ] + (lam + ww + [ + List + DCert + ] + (lam + ww + [ + List + [ + [ + Tuple2 + StakingCredential + ] + (con + integer + ) + ] + ] + (lam + ww + [ + Interval + (con + integer + ) + ] + (lam + ww + [ + List + (con + bytestring + ) + ] + (lam + ww + [ + List + [ + [ + Tuple2 + (con + bytestring + ) + ] + (con + data + ) + ] + ] + (lam + ww + (con + bytestring + ) + { + [ + [ + { + [ + Bool_match + { + [ + [ + { + [ + { + Maybe_match + (con + bytestring + ) + } + [ + [ + [ + { + { + fFoldableNil_cfoldMap + [ + (lam + a + (type) + [ + Maybe + a + ] + ) + (con + bytestring + ) + ] + } + (con + bytestring + ) + } + [ + [ + { + CConsMonoid + [ + (lam + a + (type) + [ + Maybe + a + ] + ) + (con + bytestring + ) + ] + } + (lam + ds + [ + (lam + a + (type) + [ + Maybe + a + ] + ) + (con + bytestring + ) + ] + (lam + b + [ + (lam + a + (type) + [ + Maybe + a + ] + ) + (con + bytestring + ) + ] + { + [ + [ + { + [ + { + Maybe_match + (con + bytestring + ) + } + ds + ] + (all + dead + (type) + [ + (lam + a + (type) + [ + Maybe + a + ] + ) + (con + bytestring + ) + ] + ) + } + (lam + ipv + (con + bytestring + ) + (abs + dead + (type) + ds + ) + ) + ] + (abs + dead + (type) + b + ) + ] + (all + dead + (type) + dead + ) + } + ) + ) + ] + { + Nothing + (con + bytestring + ) + } + ] + ] + (lam + x + (con + bytestring + ) + { + [ + [ + { + [ + Bool_match + [ + [ + [ + { + (builtin + ifThenElse + ) + Bool + } + [ + [ + (builtin + equalsByteString + ) + e + ] + x + ] + ] + True + ] + False + ] + ] + (all + dead + (type) + [ + Maybe + (con + bytestring + ) + ] + ) + } + (abs + dead + (type) + [ + { + Just + (con + bytestring + ) + } + x + ] + ) + ] + (abs + dead + (type) + { + Nothing + (con + bytestring + ) + } + ) + ] + (all + dead + (type) + dead + ) + } + ) + ] + ww + ] + ] + (all + dead + (type) + Bool + ) + } + (lam + ds + (con + bytestring + ) + (abs + dead + (type) + True + ) + ) + ] + (abs + dead + (type) + False + ) + ] + (all + dead + (type) + dead + ) + } + ] + (all + dead + (type) + [ + List + (con + bytestring + ) + ] + ) + } + (abs + dead + (type) + [ + [ + { + Cons + (con + bytestring + ) + } + e + ] + xs + ] + ) + ] + (abs + dead + (type) + xs + ) + ] + (all + dead + (type) + dead + ) + } + ) + ) + ) + ) + ) + ) + ) + ) + ) + ) + ] + ) + ) + ] + ) + ) + ] + { Nil (con bytestring) } + ] + ww + ] + ) + [ + [ + [ + [ + { + { + fFoldableNil_cfoldMap + [ + (lam a (type) a) + [ + (lam + a + (type) + (fun a a) + ) + (con integer) + ] + ] + } + (con bytestring) + } + [ + { + (abs + a + (type) + (lam + v + [ Monoid a ] + [ + [ + { + CConsMonoid + [ + (lam + a + (type) + a + ) + a + ] + } + (lam + eta + [ + (lam + a + (type) + a + ) + a + ] + (lam + eta + [ + (lam + a + (type) + a + ) + a + ] + [ + [ + [ + { + p1Monoid + a + } + v + ] + eta + ] + eta + ] + ) + ) + ] + [ + { mempty a } + v + ] + ] + ) + ) + [ + (lam + a + (type) + (fun a a) + ) + (con integer) + ] + } + [ + [ + { + CConsMonoid + [ + (lam + a + (type) + (fun a a) + ) + (con integer) + ] + } + (lam + ds + [ + (lam + a + (type) + (fun a a) + ) + (con integer) + ] + (lam + ds + [ + (lam + a + (type) + (fun a a) + ) + (con + integer + ) + ] + (lam + x + (con + integer + ) + [ + ds + [ ds x ] + ] + ) + ) + ) + ] + (lam + x (con integer) x + ) + ] + ] + ] + (lam + x + (con bytestring) + (lam + y + (con integer) + [ + [ + (builtin + addInteger + ) + y + ] + (con integer 1) + ] + ) + ) + ] + t + ] + (con integer 0) + ] + ) + ] + ww + ] + ] + False + ] + True + ] + ] + (all dead (type) Bool) + } + (abs dead (type) True) + ] + (abs + dead + (type) + [ + [ + { (builtin trace) Bool } + (con string "not enough signatures") + ] + False + ] + ) + ] + (all dead (type) dead) + } + ) + ) + ] + ) + ) + ) + ) + ) + ) + ) + ) + ) +) \ No newline at end of file